/* The GIMP -- an image manipulation program * Copyright (C) 1995 Spencer Kimball and Peter Mattis * * gimpcontainertreeview.c * Copyright (C) 2003-2004 Michael Natterer * * 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 2 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "config.h" #include #include #include "widgets-types.h" #include "base/temp-buf.h" #include "core/gimpcontainer.h" #include "core/gimpcontext.h" #include "core/gimpviewable.h" #include "gimpcellrenderertoggle.h" #include "gimpcellrendererviewable.h" #include "gimpcontainertreeview.h" #include "gimpcontainertreeview-dnd.h" #include "gimpcontainerview.h" #include "gimpdnd.h" #include "gimppreviewrenderer.h" #include "gimpwidgets-utils.h" enum { COLUMN_RENDERER, COLUMN_NAME, COLUMN_NAME_ATTRIBUTES, NUM_COLUMNS }; static void gimp_container_tree_view_class_init (GimpContainerTreeViewClass *klass); static void gimp_container_tree_view_init (GimpContainerTreeView *view); static void gimp_container_tree_view_view_iface_init (GimpContainerViewInterface *view_iface); static GObject *gimp_container_tree_view_constructor (GType type, guint n_params, GObjectConstructParam *params); static void gimp_container_tree_view_unrealize (GtkWidget *widget); static void gimp_container_tree_view_unmap (GtkWidget *widget); static gboolean gimp_container_tree_view_popup_menu (GtkWidget *widget); static void gimp_container_tree_view_set_container (GimpContainerView *view, GimpContainer *container); static gpointer gimp_container_tree_view_insert_item (GimpContainerView *view, GimpViewable *viewable, gint index); static void gimp_container_tree_view_remove_item (GimpContainerView *view, GimpViewable *viewable, gpointer insert_data); static void gimp_container_tree_view_reorder_item (GimpContainerView *view, GimpViewable *viewable, gint new_index, gpointer insert_data); static void gimp_container_tree_view_rename_item (GimpContainerView *view, GimpViewable *viewable, gpointer insert_data); static gboolean gimp_container_tree_view_select_item (GimpContainerView *view, GimpViewable *viewable, gpointer insert_data); static void gimp_container_tree_view_clear_items (GimpContainerView *view); static void gimp_container_tree_view_set_preview_size (GimpContainerView *view); static void gimp_container_tree_view_selection_changed (GtkTreeSelection *sel, GimpContainerTreeView *tree_view); static gboolean gimp_container_tree_view_button_press (GtkWidget *widget, GdkEventButton *bevent, GimpContainerTreeView *tree_view); static void gimp_container_tree_view_renderer_update (GimpPreviewRenderer *renderer, GimpContainerTreeView *tree_view); static GimpViewable * gimp_container_tree_view_drag_viewable (GtkWidget *widget, gpointer data); static GimpContainerBoxClass *parent_class = NULL; static GimpContainerViewInterface *parent_view_iface = NULL; GType gimp_container_tree_view_get_type (void) { static GType view_type = 0; if (! view_type) { static const GTypeInfo view_info = { sizeof (GimpContainerTreeViewClass), NULL, /* base_init */ NULL, /* base_finalize */ (GClassInitFunc) gimp_container_tree_view_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (GimpContainerTreeView), 0, /* n_preallocs */ (GInstanceInitFunc) gimp_container_tree_view_init, }; static const GInterfaceInfo view_iface_info = { (GInterfaceInitFunc) gimp_container_tree_view_view_iface_init, NULL, /* iface_finalize */ NULL /* iface_data */ }; view_type = g_type_register_static (GIMP_TYPE_CONTAINER_BOX, "GimpContainerTreeView", &view_info, 0); g_type_add_interface_static (view_type, GIMP_TYPE_CONTAINER_VIEW, &view_iface_info); } return view_type; } static void gimp_container_tree_view_class_init (GimpContainerTreeViewClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); parent_class = g_type_class_peek_parent (klass); object_class->constructor = gimp_container_tree_view_constructor; widget_class->unrealize = gimp_container_tree_view_unrealize; widget_class->unmap = gimp_container_tree_view_unmap; widget_class->popup_menu = gimp_container_tree_view_popup_menu; klass->drop_possible = gimp_container_tree_view_real_drop_possible; klass->drop = gimp_container_tree_view_real_drop; } static void gimp_container_tree_view_init (GimpContainerTreeView *tree_view) { GimpContainerBox *box = GIMP_CONTAINER_BOX (tree_view); tree_view->n_model_columns = NUM_COLUMNS; tree_view->model_columns[COLUMN_RENDERER] = GIMP_TYPE_PREVIEW_RENDERER; tree_view->model_columns[COLUMN_NAME] = G_TYPE_STRING; tree_view->model_columns[COLUMN_NAME_ATTRIBUTES] = PANGO_TYPE_ATTR_LIST; tree_view->model_column_renderer = COLUMN_RENDERER; tree_view->model_column_name = COLUMN_NAME; tree_view->model_column_name_attributes = COLUMN_NAME_ATTRIBUTES; gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (box->scrolled_win), GTK_SHADOW_IN); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (box->scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); } static void gimp_container_tree_view_view_iface_init (GimpContainerViewInterface *view_iface) { parent_view_iface = g_type_interface_peek_parent (view_iface); view_iface->set_container = gimp_container_tree_view_set_container; view_iface->insert_item = gimp_container_tree_view_insert_item; view_iface->remove_item = gimp_container_tree_view_remove_item; view_iface->reorder_item = gimp_container_tree_view_reorder_item; view_iface->rename_item = gimp_container_tree_view_rename_item; view_iface->select_item = gimp_container_tree_view_select_item; view_iface->clear_items = gimp_container_tree_view_clear_items; view_iface->set_preview_size = gimp_container_tree_view_set_preview_size; view_iface->insert_data_free = (GDestroyNotify) g_free; } static GObject * gimp_container_tree_view_constructor (GType type, guint n_params, GObjectConstructParam *params) { GimpContainerTreeView *tree_view; GimpContainerView *view; GimpContainerBox *box; GtkListStore *list; GObject *object; object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params); tree_view = GIMP_CONTAINER_TREE_VIEW (object); view = GIMP_CONTAINER_VIEW (object); box = GIMP_CONTAINER_BOX (object); list = gtk_list_store_newv (tree_view->n_model_columns, tree_view->model_columns); tree_view->model = GTK_TREE_MODEL (list); tree_view->view = g_object_new (GTK_TYPE_TREE_VIEW, "model", list, "search_column", COLUMN_NAME, "enable_search", TRUE, "headers_visible", FALSE, NULL); g_object_unref (list); gtk_container_add (GTK_CONTAINER (box->scrolled_win), GTK_WIDGET (tree_view->view)); gtk_widget_show (GTK_WIDGET (tree_view->view)); gimp_container_view_set_dnd_widget (view, GTK_WIDGET (tree_view->view)); tree_view->main_column = gtk_tree_view_column_new (); gtk_tree_view_insert_column (tree_view->view, tree_view->main_column, 0); tree_view->renderer_cell = gimp_cell_renderer_viewable_new (); gtk_tree_view_column_pack_start (tree_view->main_column, tree_view->renderer_cell, FALSE); gtk_tree_view_column_set_attributes (tree_view->main_column, tree_view->renderer_cell, "renderer", COLUMN_RENDERER, NULL); tree_view->name_cell = gtk_cell_renderer_text_new (); g_object_set (tree_view->name_cell, "xalign", 0.0, NULL); gtk_tree_view_column_pack_end (tree_view->main_column, tree_view->name_cell, FALSE); gtk_tree_view_column_set_attributes (tree_view->main_column, tree_view->name_cell, "text", COLUMN_NAME, "attributes", COLUMN_NAME_ATTRIBUTES, NULL); tree_view->renderer_cells = g_list_prepend (tree_view->renderer_cells, tree_view->renderer_cell); tree_view->selection = gtk_tree_view_get_selection (tree_view->view); g_signal_connect (tree_view->selection, "changed", G_CALLBACK (gimp_container_tree_view_selection_changed), tree_view); g_signal_connect (tree_view->view, "drag_leave", G_CALLBACK (gimp_container_tree_view_drag_leave), tree_view); g_signal_connect (tree_view->view, "drag_motion", G_CALLBACK (gimp_container_tree_view_drag_motion), tree_view); g_signal_connect (tree_view->view, "drag_drop", G_CALLBACK (gimp_container_tree_view_drag_drop), tree_view); return object; } static void gimp_container_tree_view_unrealize (GtkWidget *widget) { GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (widget); GtkTreeIter iter; gboolean iter_valid; for (iter_valid = gtk_tree_model_get_iter_first (tree_view->model, &iter); iter_valid; iter_valid = gtk_tree_model_iter_next (tree_view->model, &iter)) { GimpPreviewRenderer *renderer; gtk_tree_model_get (tree_view->model, &iter, COLUMN_RENDERER, &renderer, -1); gimp_preview_renderer_unrealize (renderer); g_object_unref (renderer); } GTK_WIDGET_CLASS (parent_class)->unrealize (widget); } static void gimp_container_tree_view_unmap (GtkWidget *widget) { GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (widget); if (tree_view->scroll_timeout_id) { g_source_remove (tree_view->scroll_timeout_id); tree_view->scroll_timeout_id = 0; } GTK_WIDGET_CLASS (parent_class)->unmap (widget); } static void gimp_container_tree_view_menu_position (GtkMenu *menu, gint *x, gint *y, gpointer data) { GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (data); GtkWidget *widget = GTK_WIDGET (tree_view->view); GtkTreeIter selected_iter; gdk_window_get_origin (widget->window, x, y); if (GTK_WIDGET_NO_WINDOW (widget)) { *x += widget->allocation.x; *y += widget->allocation.y; } if (gtk_tree_selection_get_selected (tree_view->selection, NULL, &selected_iter)) { GtkTreePath *path; GdkRectangle cell_rect; path = gtk_tree_model_get_path (tree_view->model, &selected_iter); gtk_tree_view_get_cell_area (tree_view->view, path, tree_view->main_column, &cell_rect); gtk_tree_path_free (path); *x += widget->allocation.width / 2; *y += cell_rect.y + cell_rect.height / 2; } else { *x += widget->style->xthickness; *y += widget->style->ythickness; } gimp_menu_position (menu, x, y); } static gboolean gimp_container_tree_view_popup_menu (GtkWidget *widget) { GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (widget); if (gtk_tree_selection_get_selected (tree_view->selection, NULL, NULL)) { return gimp_editor_popup_menu (GIMP_EDITOR (tree_view), gimp_container_tree_view_menu_position, tree_view); } return FALSE; } GtkWidget * gimp_container_tree_view_new (GimpContainer *container, GimpContext *context, gint preview_size, gint preview_border_width) { GimpContainerTreeView *tree_view; GimpContainerView *view; g_return_val_if_fail (container == NULL || GIMP_IS_CONTAINER (container), NULL); g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL); g_return_val_if_fail (preview_size > 0 && preview_size <= GIMP_VIEWABLE_MAX_PREVIEW_SIZE, NULL); g_return_val_if_fail (preview_border_width >= 0 && preview_border_width <= GIMP_PREVIEW_MAX_BORDER_WIDTH, NULL); tree_view = g_object_new (GIMP_TYPE_CONTAINER_TREE_VIEW, NULL); view = GIMP_CONTAINER_VIEW (tree_view); gimp_container_view_set_preview_size (view, preview_size, preview_border_width); if (container) gimp_container_view_set_container (view, container); if (context) gimp_container_view_set_context (view, context); return GTK_WIDGET (tree_view); } static void gimp_container_tree_view_set (GimpContainerTreeView *tree_view, GtkTreeIter *iter, GimpViewable *viewable) { GimpContainerView *view = GIMP_CONTAINER_VIEW (tree_view); GimpPreviewRenderer *renderer; gchar *name; gint preview_size; gint border_width; preview_size = gimp_container_view_get_preview_size (view, &border_width); renderer = gimp_preview_renderer_new (G_TYPE_FROM_INSTANCE (viewable), preview_size, border_width, FALSE); gimp_preview_renderer_set_viewable (renderer, viewable); gimp_preview_renderer_remove_idle (renderer); g_signal_connect (renderer, "update", G_CALLBACK (gimp_container_tree_view_renderer_update), tree_view); name = gimp_viewable_get_description (viewable, NULL); gtk_list_store_set (GTK_LIST_STORE (tree_view->model), iter, COLUMN_RENDERER, renderer, COLUMN_NAME, name, -1); g_free (name); g_object_unref (renderer); } /* GimpContainerView methods */ static void gimp_container_tree_view_set_container (GimpContainerView *view, GimpContainer *container) { GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); GimpContainer *old_container; old_container = gimp_container_view_get_container (view); if (old_container) { if (! container) { if (gimp_dnd_viewable_source_remove (GTK_WIDGET (tree_view->view), old_container->children_type)) { gtk_drag_source_unset (GTK_WIDGET (tree_view->view)); } g_signal_handlers_disconnect_by_func (tree_view->view, gimp_container_tree_view_button_press, tree_view); } } else if (container) { if (gimp_dnd_drag_source_set_by_type (GTK_WIDGET (tree_view->view), GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, container->children_type, GDK_ACTION_COPY)) { gimp_dnd_viewable_source_add (GTK_WIDGET (tree_view->view), container->children_type, gimp_container_tree_view_drag_viewable, tree_view); } /* connect button_press_event after DND so we can keep the list from * selecting the item on button2 */ g_signal_connect (tree_view->view, "button_press_event", G_CALLBACK (gimp_container_tree_view_button_press), tree_view); } parent_view_iface->set_container (view, container); } static gpointer gimp_container_tree_view_insert_item (GimpContainerView *view, GimpViewable *viewable, gint index) { GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); GtkTreeIter *iter; iter = g_new0 (GtkTreeIter, 1); if (index == -1) gtk_list_store_append (GTK_LIST_STORE (tree_view->model), iter); else gtk_list_store_insert (GTK_LIST_STORE (tree_view->model), iter, index); gimp_container_tree_view_set (tree_view, iter, viewable); return (gpointer) iter; } static void gimp_container_tree_view_remove_item (GimpContainerView *view, GimpViewable *viewable, gpointer insert_data) { GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); GtkTreeIter *iter = (GtkTreeIter *) insert_data; if (iter) gtk_list_store_remove (GTK_LIST_STORE (tree_view->model), iter); } static void gimp_container_tree_view_reorder_item (GimpContainerView *view, GimpViewable *viewable, gint new_index, gpointer insert_data) { GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); GtkTreeIter *iter = (GtkTreeIter *) insert_data; if (iter) { GimpContainer *container; GtkTreePath *path; GtkTreeIter selected_iter; gboolean selected; container = gimp_container_view_get_container (view); selected = gtk_tree_selection_get_selected (tree_view->selection, NULL, &selected_iter); if (selected) { GimpPreviewRenderer *renderer; gtk_tree_model_get (tree_view->model, &selected_iter, COLUMN_RENDERER, &renderer, -1); if (renderer->viewable != viewable) selected = FALSE; g_object_unref (renderer); } if (new_index == -1 || new_index == container->num_children - 1) { gtk_list_store_move_before (GTK_LIST_STORE (tree_view->model), iter, NULL); } else if (new_index == 0) { gtk_list_store_move_after (GTK_LIST_STORE (tree_view->model), iter, NULL); } else { GtkTreeIter place_iter; gint old_index; path = gtk_tree_model_get_path (tree_view->model, iter); old_index = gtk_tree_path_get_indices (path)[0]; gtk_tree_path_free (path); if (new_index != old_index) { path = gtk_tree_path_new_from_indices (new_index, -1); gtk_tree_model_get_iter (tree_view->model, &place_iter, path); gtk_tree_path_free (path); if (new_index > old_index) gtk_list_store_move_after (GTK_LIST_STORE (tree_view->model), iter, &place_iter); else gtk_list_store_move_before (GTK_LIST_STORE (tree_view->model), iter, &place_iter); } } if (selected) gimp_container_view_select_item (view, viewable); } } static void gimp_container_tree_view_rename_item (GimpContainerView *view, GimpViewable *viewable, gpointer insert_data) { GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); GtkTreeIter *iter = (GtkTreeIter *) insert_data; if (iter) { gchar *name = gimp_viewable_get_description (viewable, NULL); gtk_list_store_set (GTK_LIST_STORE (tree_view->model), iter, COLUMN_NAME, name, -1); g_free (name); } } static gboolean gimp_container_tree_view_select_item (GimpContainerView *view, GimpViewable *viewable, gpointer insert_data) { GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); GtkTreeIter *iter = (GtkTreeIter *) insert_data; if (iter) { GtkTreePath *path; path = gtk_tree_model_get_path (tree_view->model, iter); g_signal_handlers_block_by_func (tree_view->selection, gimp_container_tree_view_selection_changed, tree_view); gtk_tree_view_set_cursor (tree_view->view, path, NULL, FALSE); g_signal_handlers_unblock_by_func (tree_view->selection, gimp_container_tree_view_selection_changed, tree_view); gtk_tree_view_scroll_to_cell (tree_view->view, path, NULL, FALSE, 0.0, 0.0); gtk_tree_path_free (path); } else { gtk_tree_selection_unselect_all (tree_view->selection); } return TRUE; } static void gimp_container_tree_view_clear_items (GimpContainerView *view) { GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); gtk_list_store_clear (GTK_LIST_STORE (tree_view->model)); parent_view_iface->clear_items (view); } static void gimp_container_tree_view_set_preview_size (GimpContainerView *view) { GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view); GtkWidget *tree_widget; GtkTreeIter iter; gboolean iter_valid; GList *list; gint preview_size; gint border_width; preview_size = gimp_container_view_get_preview_size (view, &border_width); tree_widget = GTK_WIDGET (tree_view->view); for (list = tree_view->toggle_cells; list; list = g_list_next (list)) { gchar *stock_id; GtkIconSize icon_size; g_object_get (list->data, "stock-id", &stock_id, NULL); if (stock_id) { icon_size = gimp_get_icon_size (tree_widget, stock_id, GTK_ICON_SIZE_BUTTON, preview_size - 2 * tree_widget->style->xthickness, preview_size - 2 * tree_widget->style->ythickness); g_object_set (list->data, "stock-size", icon_size, NULL); g_free (stock_id); } } for (iter_valid = gtk_tree_model_get_iter_first (tree_view->model, &iter); iter_valid; iter_valid = gtk_tree_model_iter_next (tree_view->model, &iter)) { GimpPreviewRenderer *renderer; gtk_tree_model_get (tree_view->model, &iter, COLUMN_RENDERER, &renderer, -1); gimp_preview_renderer_set_size (renderer, preview_size, border_width); g_object_unref (renderer); } gtk_tree_view_columns_autosize (tree_view->view); } /* callbacks */ static void gimp_container_tree_view_selection_changed (GtkTreeSelection *selection, GimpContainerTreeView *tree_view) { GtkTreeIter iter; if (gtk_tree_selection_get_selected (selection, NULL, &iter)) { GimpPreviewRenderer *renderer; gtk_tree_model_get (tree_view->model, &iter, COLUMN_RENDERER, &renderer, -1); gimp_container_view_item_selected (GIMP_CONTAINER_VIEW (tree_view), renderer->viewable); g_object_unref (renderer); } } static GtkCellRenderer * gimp_container_tree_view_find_click_cell (GList *cells, GtkTreeViewColumn *column, GdkRectangle *column_area, gint tree_x, gint tree_y) { GList *list; for (list = cells; list; list = g_list_next (list)) { GtkCellRenderer *renderer = list->data; gint start_pos; gint width; if (renderer->visible && gtk_tree_view_column_cell_get_position (column, renderer, &start_pos, &width) && width > 0 && column_area->x + start_pos + renderer->xpad <= tree_x && column_area->x + start_pos + renderer->xpad + width - 1 >= tree_x) { #if 0 g_print ("click on cell at %d (%d width) (%d column->x) (%d tree_x)\n", start_pos, width, column_area->x, tree_x); #endif return renderer; } } return NULL; } static gboolean gimp_container_tree_view_button_press (GtkWidget *widget, GdkEventButton *bevent, GimpContainerTreeView *tree_view) { GimpContainerView *container_view = GIMP_CONTAINER_VIEW (tree_view); GtkTreeViewColumn *column; GtkTreePath *path; tree_view->dnd_viewable = NULL; if (! GTK_WIDGET_HAS_FOCUS (widget)) gtk_widget_grab_focus (widget); if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), bevent->x, bevent->y, &path, &column, NULL, NULL)) { GimpPreviewRenderer *renderer; GimpCellRendererToggle *toggled_cell = NULL; GimpCellRendererViewable *clicked_cell = NULL; GtkCellRenderer *edit_cell = NULL; GdkRectangle column_area; gint tree_x; gint tree_y; GtkTreeIter iter; gtk_tree_model_get_iter (tree_view->model, &iter, path); gtk_tree_model_get (tree_view->model, &iter, COLUMN_RENDERER, &renderer, -1); tree_view->dnd_viewable = renderer->viewable; gtk_tree_view_widget_to_tree_coords (tree_view->view, bevent->x, bevent->y, &tree_x, &tree_y); gtk_tree_view_get_background_area (tree_view->view, path, column, &column_area); gtk_tree_view_column_cell_set_cell_data (column, tree_view->model, &iter, FALSE, FALSE); toggled_cell = (GimpCellRendererToggle *) gimp_container_tree_view_find_click_cell (tree_view->toggle_cells, column, &column_area, tree_x, tree_y); if (! toggled_cell) clicked_cell = (GimpCellRendererViewable *) gimp_container_tree_view_find_click_cell (tree_view->renderer_cells, column, &column_area, tree_x, tree_y); if (! toggled_cell && ! clicked_cell) edit_cell = gimp_container_tree_view_find_click_cell (tree_view->editable_cells, column, &column_area, tree_x, tree_y); g_object_ref (tree_view); switch (bevent->button) { case 1: if (bevent->type == GDK_BUTTON_PRESS) { gboolean success = TRUE; /* don't select item if a toggle was clicked */ if (! toggled_cell) success = gimp_container_view_item_selected (container_view, renderer->viewable); /* a callback invoked by selecting the item may have * destroyed us, so check if the container is still there */ if (gimp_container_view_get_container (container_view)) { /* another row may have been set by selecting */ gtk_tree_view_column_cell_set_cell_data (column, tree_view->model, &iter, FALSE, FALSE); if (toggled_cell || clicked_cell) { gchar *path_str; path_str = gtk_tree_path_to_string (path); if (toggled_cell) { gimp_cell_renderer_toggle_clicked (toggled_cell, path_str, bevent->state); } else if (clicked_cell) { gimp_cell_renderer_viewable_clicked (clicked_cell, path_str, bevent->state); } g_free (path_str); } } } else if (bevent->type == GDK_2BUTTON_PRESS) { gboolean success = TRUE; /* don't select item if a toggle was clicked */ if (! toggled_cell) success = gimp_container_view_item_selected (container_view, renderer->viewable); if (success) { if (edit_cell) { #ifdef __GNUC__ #warning FIXME: make sure the orig text gets restored when cancelling editing #endif if (edit_cell == tree_view->name_cell) { const gchar *real_name; real_name = gimp_object_get_name (GIMP_OBJECT (renderer->viewable)); gtk_list_store_set (GTK_LIST_STORE (tree_view->model), &iter, tree_view->model_column_name, real_name, -1); } gtk_tree_view_set_cursor_on_cell (tree_view->view, path, column, edit_cell, TRUE); } else if (! toggled_cell) /* ignore double click on toggles */ { gimp_container_view_item_activated (container_view, renderer->viewable); } } } break; case 2: break; case 3: if (gimp_container_view_item_selected (container_view, renderer->viewable)) { if (gimp_container_view_get_container (container_view)) gimp_container_view_item_context (container_view, renderer->viewable); } break; default: break; } g_object_unref (tree_view); gtk_tree_path_free (path); g_object_unref (renderer); } return TRUE; } static void gimp_container_tree_view_renderer_update (GimpPreviewRenderer *renderer, GimpContainerTreeView *tree_view) { GimpContainerView *view = GIMP_CONTAINER_VIEW (tree_view); GtkTreeIter *iter; iter = gimp_container_view_lookup (view, renderer->viewable); if (iter) { GtkTreePath *path; path = gtk_tree_model_get_path (tree_view->model, iter); gtk_tree_model_row_changed (tree_view->model, path, iter); gtk_tree_path_free (path); } } static GimpViewable * gimp_container_tree_view_drag_viewable (GtkWidget *widget, gpointer data) { GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (data); return tree_view->dnd_viewable; }