Gimp/app/widgets/gimprow.c
Alx Sa d20c7f01cb widgets: Don't force selection of GimpRow
As seen in the Welcome Dialog, if you have multi-selection
in place for a ListBox and try to Ctrl-click another row,
the call to gtk_list_box_select_row () will deselect the
prior row unless you click on an area that's not covered
by GimpRow. This patch removes the forced selection,
with the assumption that the click will bubble through
as normal to GtkListBox.
2025-12-05 23:41:12 +00:00

903 lines
26 KiB
C

/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimprow.c
* Copyright (C) 2025 Michael Natterer <mitch@gimp.org>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
#include "widgets-types.h"
#include "core/gimpcontext.h"
#include "core/gimpviewable.h"
#include "gimpdnd.h"
#include "gimpeditor.h"
#include "gimprow.h"
#include "gimprow-utils.h"
#include "gimpview.h"
#include "gimpviewrenderer.h"
#include "gimp-intl.h"
enum
{
EDIT_NAME,
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_CONTEXT,
PROP_VIEWABLE,
PROP_VIEW_SIZE,
PROP_VIEW_BORDER_WIDTH,
N_PROPS
};
static GParamSpec *obj_props[N_PROPS] = { NULL, };
typedef struct _GimpRowPrivate GimpRowPrivate;
struct _GimpRowPrivate
{
GimpContext *context;
GimpViewable *viewable;
gint view_size;
gint view_border_width;
GtkWidget *box;
GtkWidget *icon;
GtkWidget *view;
GtkWidget *label;
GtkWidget *rename_popover;
GtkGesture *rename_long_press;
};
#define GET_PRIVATE(obj) \
((GimpRowPrivate *) gimp_row_get_instance_private ((GimpRow *) obj))
static void gimp_row_constructed (GObject *object);
static void gimp_row_dispose (GObject *object);
static void gimp_row_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_row_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static gboolean gimp_row_button_press_event (GtkWidget *widget,
GdkEventButton *bevent);
static void gimp_row_style_updated (GtkWidget *widget);
static gboolean gimp_row_query_tooltip (GtkWidget *widget,
gint x,
gint y,
gboolean keyboard_tooltip,
GtkTooltip *tooltip);
static void gimp_row_real_set_context (GimpRow *row,
GimpContext *context);
static void gimp_row_real_set_viewable (GimpRow *row,
GimpViewable *viewable);
static void gimp_row_real_set_view_size (GimpRow *row);
static void gimp_row_real_icon_changed (GimpRow *row);
static void gimp_row_real_name_changed (GimpRow *row);
static void gimp_row_real_monitor_changed (GimpRow *row);
static void gimp_row_real_edit_name (GimpRow *row);
static gboolean gimp_row_real_name_edited (GimpRow *row,
const gchar *new_name);
static void gimp_row_icon_changed (GimpViewable *viewable,
const GParamSpec *pspec,
GimpRow *row);
static void gimp_row_name_changed (GimpViewable *viewable,
GimpRow *row);
static void gimp_row_label_long_pressed (GtkGesture *gesture,
gdouble x,
gdouble y,
GimpRow *row);
static void gimp_row_rename_entry_activate (GtkEntry *entry,
GimpRow *row);
static GimpViewable *
gimp_row_drag_viewable (GtkWidget *widget,
GimpContext **context,
gpointer data);
static GdkPixbuf *gimp_row_drag_pixbuf (GtkWidget *widget,
gpointer data);
G_DEFINE_TYPE_WITH_PRIVATE (GimpRow, gimp_row, GTK_TYPE_LIST_BOX_ROW)
#define parent_class gimp_row_parent_class
static guint row_signals[LAST_SIGNAL] = { 0 };
static void
gimp_row_class_init (GimpRowClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GtkBindingSet *binding_set;
object_class->constructed = gimp_row_constructed;
object_class->dispose = gimp_row_dispose;
object_class->set_property = gimp_row_set_property;
object_class->get_property = gimp_row_get_property;
widget_class->button_press_event = gimp_row_button_press_event;
widget_class->style_updated = gimp_row_style_updated;
widget_class->query_tooltip = gimp_row_query_tooltip;
klass->set_context = gimp_row_real_set_context;
klass->set_viewable = gimp_row_real_set_viewable;
klass->set_view_size = gimp_row_real_set_view_size;
klass->icon_changed = gimp_row_real_icon_changed;
klass->name_changed = gimp_row_real_name_changed;
klass->monitor_changed = gimp_row_real_monitor_changed;
klass->edit_name = gimp_row_real_edit_name;
klass->name_edited = gimp_row_real_name_edited;
row_signals[EDIT_NAME] =
g_signal_new ("edit-name",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GimpRowClass, edit_name),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
binding_set = gtk_binding_set_by_class (klass);
gtk_binding_entry_add_signal (binding_set, GDK_KEY_F2, 0,
"edit-name", 0);
obj_props[PROP_CONTEXT] =
g_param_spec_object ("context",
NULL, NULL,
GIMP_TYPE_CONTEXT,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT);
obj_props[PROP_VIEWABLE] =
g_param_spec_object ("viewable",
NULL, NULL,
GIMP_TYPE_VIEWABLE,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT);
obj_props[PROP_VIEW_SIZE] =
g_param_spec_int ("view-size",
NULL, NULL,
1, GIMP_VIEWABLE_MAX_PREVIEW_SIZE,
GIMP_VIEW_SIZE_MEDIUM,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT);
obj_props[PROP_VIEW_BORDER_WIDTH] =
g_param_spec_int ("view-border-width",
NULL, NULL,
0, GIMP_VIEW_MAX_BORDER_WIDTH,
1,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT);
g_object_class_install_properties (object_class, N_PROPS, obj_props);
}
static void
gimp_row_init (GimpRow *row)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
GtkWidget *ebox;
gtk_widget_set_has_tooltip (GTK_WIDGET (row), TRUE);
priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_container_add (GTK_CONTAINER (row), priv->box);
gtk_widget_set_visible (priv->box, TRUE);
priv->icon = gtk_image_new_from_icon_name (NULL, GTK_ICON_SIZE_BUTTON);
gtk_box_pack_start (GTK_BOX (priv->box), priv->icon, FALSE, FALSE, 0);
gtk_widget_set_visible (priv->icon, TRUE);
ebox = gtk_event_box_new ();
gtk_box_pack_end (GTK_BOX (priv->box), ebox, TRUE, TRUE, 0);
gtk_widget_show (ebox);
priv->label = gtk_label_new (NULL);
gtk_label_set_xalign (GTK_LABEL (priv->label), 0.0);
gtk_container_add (GTK_CONTAINER (ebox), priv->label);
gtk_widget_set_visible (priv->label, TRUE);
priv->rename_long_press = gtk_gesture_long_press_new (ebox);
gtk_event_controller_set_propagation_phase
(GTK_EVENT_CONTROLLER (priv->rename_long_press),
GTK_PHASE_TARGET);
g_signal_connect (priv->rename_long_press, "pressed",
G_CALLBACK (gimp_row_label_long_pressed),
row);
}
static void
gimp_row_constructed (GObject *object)
{
GimpRowPrivate *priv = GET_PRIVATE (object);
gboolean preview = FALSE;
G_OBJECT_CLASS (parent_class)->constructed (object);
priv->view = gimp_view_new (priv->context,
priv->viewable,
priv->view_size,
priv->view_border_width,
FALSE);
GIMP_VIEW (priv->view)->eat_button_events = FALSE;
GIMP_VIEW (priv->view)->show_popup = TRUE;
gtk_box_pack_start (GTK_BOX (priv->box), priv->view, FALSE, FALSE, 0);
if (priv->viewable)
preview = gimp_viewable_has_preview (priv->viewable);
gtk_widget_set_visible (priv->icon, ! preview);
gtk_widget_set_visible (priv->view, preview);
}
static void
gimp_row_dispose (GObject *object)
{
GimpRowPrivate *priv = GET_PRIVATE (object);
gimp_row_set_viewable (GIMP_ROW (object), NULL);
g_clear_pointer (&priv->rename_popover, gtk_widget_destroy);
g_clear_object (&priv->rename_long_press);
gimp_row_set_context (GIMP_ROW (object), NULL);
gimp_row_set_viewable (GIMP_ROW (object), NULL);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
gimp_row_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpRow *row = GIMP_ROW (object);
switch (property_id)
{
case PROP_CONTEXT:
gimp_row_set_context (row, g_value_get_object (value));
break;
case PROP_VIEWABLE:
gimp_row_set_viewable (row, g_value_get_object (value));
break;
case PROP_VIEW_SIZE:
case PROP_VIEW_BORDER_WIDTH:
{
gint size;
gint border = 0;
size = gimp_row_get_view_size (row, &border);
if (property_id == PROP_VIEW_SIZE)
size = g_value_get_int (value);
else
border = g_value_get_int (value);
gimp_row_set_view_size (row, size, border);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_row_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpRow *row = GIMP_ROW (object);
switch (property_id)
{
case PROP_CONTEXT:
g_value_set_object (value, gimp_row_get_context (row));
break;
case PROP_VIEWABLE:
g_value_set_object (value, gimp_row_get_viewable (row));
break;
case PROP_VIEW_SIZE:
case PROP_VIEW_BORDER_WIDTH:
{
gint size;
gint border = 0;
size = gimp_row_get_view_size (row, &border);
if (property_id == PROP_VIEW_SIZE)
g_value_set_int (value, size);
else
g_value_set_int (value, border);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static gboolean
gimp_row_button_press_event (GtkWidget *widget,
GdkEventButton *bevent)
{
GdkEvent *event = (GdkEvent *) bevent;
gboolean context_menu;
GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, bevent);
context_menu = gdk_event_triggers_context_menu (event);
if (bevent->button == 1 || context_menu)
{
GtkWidget *list_box = gtk_widget_get_parent (widget);
if (GTK_IS_LIST_BOX (list_box))
{
if (context_menu)
{
GtkWidget *editor = gtk_widget_get_ancestor (widget,
GIMP_TYPE_EDITOR);
if (editor)
{
return gimp_editor_popup_menu_at_pointer (GIMP_EDITOR (editor),
event);
}
}
}
}
return FALSE;
}
static void
gimp_row_style_updated (GtkWidget *widget)
{
GimpRowPrivate *priv = GET_PRIVATE (widget);
GTK_WIDGET_CLASS (parent_class)->style_updated (widget);
if (priv->view)
gimp_view_renderer_invalidate (GIMP_VIEW (priv->view)->renderer);
}
static gboolean
gimp_row_query_tooltip (GtkWidget *widget,
gint x,
gint y,
gboolean keyboard_tooltip,
GtkTooltip *tooltip)
{
GimpRowPrivate *priv = GET_PRIVATE (widget);
gboolean show_tip = FALSE;
if (priv->viewable)
{
gchar *desc;
gchar *tip;
desc = gimp_viewable_get_description (priv->viewable, &tip);
if (tip)
{
gtk_tooltip_set_text (tooltip, tip);
show_tip = TRUE;
g_free (tip);
}
g_free (desc);
}
return show_tip;
}
static void
gimp_row_real_set_context (GimpRow *row,
GimpContext *context)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
g_set_object (&priv->context, context);
if (priv->view)
gimp_view_renderer_set_context (GIMP_VIEW (priv->view)->renderer,
priv->context);
}
static void
gimp_row_real_set_viewable (GimpRow *row,
GimpViewable *viewable)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
GType viewable_type = G_TYPE_NONE;
gboolean preview = FALSE;
if (viewable)
viewable_type = G_TYPE_FROM_INSTANCE (viewable);
if (priv->viewable)
{
g_signal_handlers_disconnect_by_func (priv->viewable,
gimp_row_icon_changed,
row);
g_signal_handlers_disconnect_by_func (priv->viewable,
gimp_row_name_changed,
row);
if (! viewable)
{
if (gimp_dnd_viewable_source_remove (GTK_WIDGET (row),
G_TYPE_FROM_INSTANCE (priv->viewable)))
{
if (gimp_viewable_get_size (priv->viewable, NULL, NULL))
gimp_dnd_pixbuf_source_remove (GTK_WIDGET (row));
gtk_drag_source_unset (GTK_WIDGET (row));
}
}
}
else if (viewable)
{
if (gimp_dnd_drag_source_set_by_type (GTK_WIDGET (row),
GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
viewable_type,
GDK_ACTION_COPY))
{
gimp_dnd_viewable_source_add (GTK_WIDGET (row),
viewable_type,
gimp_row_drag_viewable,
NULL);
if (gimp_viewable_get_size (viewable, NULL, NULL))
gimp_dnd_pixbuf_source_add (GTK_WIDGET (row),
gimp_row_drag_pixbuf,
NULL);
}
}
g_set_weak_pointer (&priv->viewable, viewable);
if (priv->viewable)
{
g_signal_connect (priv->viewable,
GIMP_VIEWABLE_GET_CLASS (viewable)->name_changed_signal,
G_CALLBACK (gimp_row_name_changed),
row);
g_signal_connect (priv->viewable, "notify::icon-name",
G_CALLBACK (gimp_row_icon_changed),
row);
preview = gimp_viewable_has_preview (priv->viewable);
}
gimp_row_name_changed (priv->viewable, row);
gtk_widget_set_visible (priv->icon, ! preview);
gimp_row_icon_changed (priv->viewable, NULL, row);
if (priv->view)
{
gtk_widget_set_visible (priv->view, preview);
gimp_view_set_viewable (GIMP_VIEW (priv->view), priv->viewable);
}
}
static void
gimp_row_real_set_view_size (GimpRow *row)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
gtk_image_set_pixel_size (GTK_IMAGE (priv->icon),
priv->view_size);
if (priv->view)
gimp_view_renderer_set_size (GIMP_VIEW (priv->view)->renderer,
priv->view_size,
priv->view_border_width);
}
static void
gimp_row_real_icon_changed (GimpRow *row)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
const gchar *icon_name = NULL;
if (priv->viewable)
icon_name = gimp_viewable_get_icon_name (priv->viewable);
gtk_image_set_from_icon_name (GTK_IMAGE (priv->icon), icon_name,
GTK_ICON_SIZE_BUTTON);
}
static void
gimp_row_real_name_changed (GimpRow *row)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
const gchar *description = NULL;
if (priv->viewable)
description = gimp_viewable_get_description (priv->viewable, NULL);
gtk_label_set_text (GTK_LABEL (priv->label), description);
}
static void
gimp_row_real_monitor_changed (GimpRow *row)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
if (priv->view)
gimp_view_renderer_free_color_transform (GIMP_VIEW (priv->view)->renderer);
}
static void
gimp_row_real_edit_name (GimpRow *row)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
GtkWidget *box;
GtkWidget *label;
GtkWidget *entry;
const gchar *default_name;
gchar *title;
if (! priv->viewable ||
! gimp_viewable_is_name_editable (priv->viewable))
{
gtk_widget_error_bell (GTK_WIDGET (row));
return;
}
priv->rename_popover = gtk_popover_new (priv->label);
gtk_popover_set_modal (GTK_POPOVER (priv->rename_popover), TRUE);
g_object_add_weak_pointer (G_OBJECT (priv->rename_popover),
(gpointer) &priv->rename_popover);
g_signal_connect (priv->rename_popover, "closed",
G_CALLBACK (gtk_widget_destroy),
NULL);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_container_add (GTK_CONTAINER (priv->rename_popover), box);
gtk_widget_show (box);
default_name = GIMP_VIEWABLE_GET_CLASS (priv->viewable)->default_name;
title = g_strdup_printf (_("Rename %s"), default_name);
label = gtk_label_new (title);
g_free (title);
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
gtk_widget_show (label);
entry = gtk_entry_new ();
gtk_entry_set_text (GTK_ENTRY (entry), gimp_object_get_name (priv->viewable));
gtk_box_pack_start (GTK_BOX (box), entry, FALSE, FALSE, 0);
gtk_widget_show (entry);
g_signal_connect (entry, "activate",
G_CALLBACK (gimp_row_rename_entry_activate),
row);
gtk_popover_popup (GTK_POPOVER (priv->rename_popover));
}
static gboolean
gimp_row_real_name_edited (GimpRow *row,
const gchar *new_name)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
gimp_object_set_name (GIMP_OBJECT (priv->viewable), new_name);
return TRUE;
}
/* public functions */
GtkWidget *
gimp_row_new (GimpContext *context,
GimpViewable *viewable,
gint view_size,
gint view_border_width)
{
GType row_type;
g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL);
g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL);
g_return_val_if_fail (view_size > 0 &&
view_size <= GIMP_VIEWABLE_MAX_PREVIEW_SIZE, NULL);
g_return_val_if_fail (view_border_width >= 0 &&
view_border_width <= GIMP_VIEW_MAX_BORDER_WIDTH,
NULL);
row_type = gimp_row_type_from_viewable (viewable);
return g_object_new (row_type,
"context", context,
"viewable", viewable,
"view-size", view_size,
"view-border-width", view_border_width,
NULL);
}
void
gimp_row_set_context (GimpRow *row,
GimpContext *context)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
g_return_if_fail (GIMP_IS_ROW (row));
g_return_if_fail (context == NULL || GIMP_IS_CONTEXT (context));
if (context != priv->context)
{
GIMP_ROW_GET_CLASS (row)->set_context (row, context);
g_object_notify_by_pspec (G_OBJECT (row), obj_props[PROP_CONTEXT]);
}
}
GimpContext *
gimp_row_get_context (GimpRow *row)
{
g_return_val_if_fail (GIMP_IS_ROW (row), NULL);
return GET_PRIVATE (row)->context;
}
void
gimp_row_set_viewable (GimpRow *row,
GimpViewable *viewable)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
g_return_if_fail (GIMP_IS_ROW (row));
g_return_if_fail (viewable == NULL || GIMP_IS_VIEWABLE (viewable));
if (viewable != priv->viewable)
{
GIMP_ROW_GET_CLASS (row)->set_viewable (row, viewable);
g_object_notify_by_pspec (G_OBJECT (row), obj_props[PROP_VIEWABLE]);
}
}
GimpViewable *
gimp_row_get_viewable (GimpRow *row)
{
g_return_val_if_fail (GIMP_IS_ROW (row), NULL);
return GET_PRIVATE (row)->viewable;
}
void
gimp_row_set_view_size (GimpRow *row,
gint view_size,
gint view_border_width)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
g_return_if_fail (GIMP_IS_ROW (row));
g_return_if_fail (view_size > 0 &&
view_size <= GIMP_VIEWABLE_MAX_PREVIEW_SIZE);
g_return_if_fail (view_border_width >= 0 &&
view_border_width <= GIMP_VIEW_MAX_BORDER_WIDTH);
if (priv->view_size != view_size ||
priv->view_border_width != view_border_width)
{
priv->view_size = view_size;
priv->view_border_width = view_border_width;
GIMP_ROW_GET_CLASS (row)->set_view_size (row);
g_object_freeze_notify (G_OBJECT (row));
g_object_notify_by_pspec (G_OBJECT (row), obj_props[PROP_VIEW_SIZE]);
g_object_notify_by_pspec (G_OBJECT (row), obj_props[PROP_VIEW_BORDER_WIDTH]);
g_object_thaw_notify (G_OBJECT (row));
}
}
gint
gimp_row_get_view_size (GimpRow *row,
gint *view_border_width)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
g_return_val_if_fail (GIMP_IS_ROW (row), 1);
if (view_border_width)
*view_border_width = priv->view_border_width;
return priv->view_size;
}
void
gimp_row_monitor_changed (GimpRow *row)
{
g_return_if_fail (GIMP_IS_ROW (row));
GIMP_ROW_GET_CLASS (row)->monitor_changed (row);
}
GtkWidget *
_gimp_row_get_box (GimpRow *row)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
g_return_val_if_fail (GIMP_IS_ROW (row), NULL);
return priv->box;
}
GtkWidget *
_gimp_row_get_icon (GimpRow *row)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
g_return_val_if_fail (GIMP_IS_ROW (row), NULL);
return priv->icon;
}
GtkWidget *
_gimp_row_get_view (GimpRow *row)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
g_return_val_if_fail (GIMP_IS_ROW (row), NULL);
return priv->view;
}
GtkWidget *
_gimp_row_get_label (GimpRow *row)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
g_return_val_if_fail (GIMP_IS_ROW (row), NULL);
return priv->label;
}
/* private functions */
static void
gimp_row_icon_changed (GimpViewable *viewable,
const GParamSpec *pspec,
GimpRow *row)
{
GIMP_ROW_GET_CLASS (row)->icon_changed (row);
}
static void
gimp_row_name_changed (GimpViewable *viewable,
GimpRow *row)
{
GIMP_ROW_GET_CLASS (row)->name_changed (row);
}
static void
gimp_row_label_long_pressed (GtkGesture *gesture,
gdouble x,
gdouble y,
GimpRow *row)
{
g_signal_emit (row, row_signals[EDIT_NAME], 0);
}
static void
gimp_row_rename_entry_activate (GtkEntry *entry,
GimpRow *row)
{
GimpRowPrivate *priv = GET_PRIVATE (row);
const gchar *old_name;
gchar *new_name;
old_name = gimp_object_get_name (priv->viewable);
/* Dup the new name, and popdown before renaming, because it can
* destroy the row and the popup.
*/
new_name = g_strdup (gtk_entry_get_text (entry));
gtk_popover_popdown (GTK_POPOVER (priv->rename_popover));
if (g_strcmp0 (old_name, new_name))
{
if (! GIMP_ROW_GET_CLASS (row)->name_edited (row, new_name))
{
gtk_widget_error_bell (GTK_WIDGET (row));
}
}
g_free (new_name);
}
static GimpViewable *
gimp_row_drag_viewable (GtkWidget *widget,
GimpContext **context,
gpointer data)
{
GimpRowPrivate *priv = GET_PRIVATE (widget);
if (context)
*context = priv->context;
return priv->viewable;
}
static GdkPixbuf *
gimp_row_drag_pixbuf (GtkWidget *widget,
gpointer data)
{
GimpRowPrivate *priv = GET_PRIVATE (widget);
gint width;
gint height;
g_printerr ("drag pixbuf\n");
if (priv->viewable &&
gimp_viewable_get_size (priv->viewable, &width, &height))
{
return gimp_viewable_get_new_pixbuf (priv->viewable,
priv->context,
width, height, NULL);
}
g_printerr ("failed\n");
return NULL;
}