~ubuntu-branches/ubuntu/vivid/gimp/vivid

« back to all changes in this revision

Viewing changes to app/widgets/gimpcontainertreeview.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach
  • Date: 2012-05-08 18:50:03 UTC
  • mto: (1.1.26) (0.5.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 71.
  • Revision ID: package-import@ubuntu.com-20120508185003-tltkvbaysf8d2426
ImportĀ upstreamĀ versionĀ 2.8.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3
3
 *
4
4
 * gimpcontainertreeview.c
5
 
 * Copyright (C) 2003-2004 Michael Natterer <mitch@gimp.org>
 
5
 * Copyright (C) 2003-2010 Michael Natterer <mitch@gimp.org>
6
6
 *
7
 
 * This program is free software; you can redistribute it and/or modify
 
7
 * This program is free software: you can redistribute it and/or modify
8
8
 * it under the terms of the GNU General Public License as published by
9
 
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * the Free Software Foundation; either version 3 of the License, or
10
10
 * (at your option) any later version.
11
11
 *
12
12
 * This program is distributed in the hope that it will be useful,
15
15
 * GNU General Public License for more details.
16
16
 *
17
17
 * You should have received a copy of the GNU General Public License
18
 
 * along with this program; if not, write to the Free Software
19
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
19
 */
21
20
 
22
21
#include "config.h"
23
22
 
24
23
#include <string.h>
25
24
 
 
25
#include <gdk/gdkkeysyms.h>
26
26
#include <gtk/gtk.h>
27
27
 
28
28
#include "libgimpwidgets/gimpwidgets.h"
31
31
 
32
32
#include "core/gimpcontainer.h"
33
33
#include "core/gimpcontext.h"
 
34
#include "core/gimpmarshal.h"
34
35
#include "core/gimpviewable.h"
35
36
 
36
37
#include "gimpcellrendererviewable.h"
 
38
#include "gimpcontainertreestore.h"
37
39
#include "gimpcontainertreeview.h"
38
40
#include "gimpcontainertreeview-dnd.h"
 
41
#include "gimpcontainertreeview.h"
 
42
#include "gimpcontainertreeview-private.h"
39
43
#include "gimpcontainerview.h"
40
44
#include "gimpdnd.h"
41
45
#include "gimpviewrenderer.h"
44
48
 
45
49
enum
46
50
{
47
 
  COLUMN_RENDERER,
48
 
  COLUMN_NAME,
49
 
  COLUMN_NAME_ATTRIBUTES,
50
 
  NUM_COLUMNS
 
51
  EDIT_NAME,
 
52
  LAST_SIGNAL
51
53
};
52
54
 
53
55
 
54
 
static void  gimp_container_tree_view_view_iface_init (GimpContainerViewInterface *iface);
55
 
 
56
 
static GObject *gimp_container_tree_view_constructor  (GType                   type,
57
 
                                                       guint                   n_params,
58
 
                                                       GObjectConstructParam  *params);
59
 
 
60
 
static void    gimp_container_tree_view_finalize      (GObject                *object);
61
 
static void    gimp_container_tree_view_unmap         (GtkWidget              *widget);
62
 
static gboolean  gimp_container_tree_view_popup_menu  (GtkWidget              *widget);
63
 
 
64
 
static void    gimp_container_tree_view_set_container (GimpContainerView      *view,
65
 
                                                       GimpContainer          *container);
66
 
static void    gimp_container_tree_view_set_context   (GimpContainerView      *view,
67
 
                                                       GimpContext            *context);
68
 
static gpointer gimp_container_tree_view_insert_item  (GimpContainerView      *view,
69
 
                                                       GimpViewable           *viewable,
70
 
                                                       gint                    index);
71
 
static void     gimp_container_tree_view_remove_item  (GimpContainerView      *view,
72
 
                                                       GimpViewable           *viewable,
73
 
                                                       gpointer                insert_data);
74
 
static void     gimp_container_tree_view_reorder_item (GimpContainerView      *view,
75
 
                                                       GimpViewable           *viewable,
76
 
                                                       gint                    new_index,
77
 
                                                       gpointer                insert_data);
78
 
static void     gimp_container_tree_view_rename_item  (GimpContainerView      *view,
79
 
                                                       GimpViewable           *viewable,
80
 
                                                       gpointer                insert_data);
81
 
static gboolean  gimp_container_tree_view_select_item (GimpContainerView      *view,
82
 
                                                       GimpViewable           *viewable,
83
 
                                                       gpointer                insert_data);
84
 
static void     gimp_container_tree_view_clear_items  (GimpContainerView      *view);
85
 
static void    gimp_container_tree_view_set_view_size (GimpContainerView      *view);
86
 
 
87
 
static void gimp_container_tree_view_name_canceled    (GtkCellRendererText    *cell,
88
 
                                                       GimpContainerTreeView  *tree_view);
89
 
 
90
 
static void gimp_container_tree_view_selection_changed (GtkTreeSelection      *sel,
91
 
                                                        GimpContainerTreeView *tree_view);
92
 
static gboolean gimp_container_tree_view_button_press (GtkWidget              *widget,
93
 
                                                       GdkEventButton         *bevent,
94
 
                                                       GimpContainerTreeView  *tree_view);
95
 
static gboolean  gimp_container_tree_view_tooltip     (GtkWidget              *widget,
96
 
                                                       gint                    x,
97
 
                                                       gint                    y,
98
 
                                                       gboolean                keyboard_tip,
99
 
                                                       GtkTooltip             *tooltip,
100
 
                                                       GimpContainerTreeView  *tree_view);
101
 
static void gimp_container_tree_view_renderer_update  (GimpViewRenderer       *renderer,
102
 
                                                       GimpContainerTreeView  *tree_view);
103
 
 
104
 
static GimpViewable * gimp_container_tree_view_drag_viewable (GtkWidget       *widget,
105
 
                                                              GimpContext    **context,
106
 
                                                              gpointer         data);
107
 
static GdkPixbuf    * gimp_container_tree_view_drag_pixbuf   (GtkWidget       *widget,
108
 
                                                              gpointer         data);
 
56
static void          gimp_container_tree_view_view_iface_init   (GimpContainerViewInterface  *iface);
 
57
 
 
58
static void          gimp_container_tree_view_constructed       (GObject                     *object);
 
59
static void          gimp_container_tree_view_finalize          (GObject                     *object);
 
60
 
 
61
static void          gimp_container_tree_view_unmap             (GtkWidget                   *widget);
 
62
static gboolean      gimp_container_tree_view_popup_menu        (GtkWidget                   *widget);
 
63
 
 
64
static void          gimp_container_tree_view_set_container     (GimpContainerView           *view,
 
65
                                                                 GimpContainer               *container);
 
66
static void          gimp_container_tree_view_set_context       (GimpContainerView           *view,
 
67
                                                                 GimpContext                 *context);
 
68
static void          gimp_container_tree_view_set_selection_mode(GimpContainerView           *view,
 
69
                                                                 GtkSelectionMode             mode);
 
70
 
 
71
static gpointer      gimp_container_tree_view_insert_item       (GimpContainerView           *view,
 
72
                                                                 GimpViewable                *viewable,
 
73
                                                                 gpointer                     parent_insert_data,
 
74
                                                                 gint                         index);
 
75
static void          gimp_container_tree_view_remove_item       (GimpContainerView           *view,
 
76
                                                                 GimpViewable                *viewable,
 
77
                                                                 gpointer                     insert_data);
 
78
static void          gimp_container_tree_view_reorder_item      (GimpContainerView           *view,
 
79
                                                                 GimpViewable                *viewable,
 
80
                                                                 gint                         new_index,
 
81
                                                                 gpointer                     insert_data);
 
82
static void          gimp_container_tree_view_rename_item       (GimpContainerView           *view,
 
83
                                                                 GimpViewable                *viewable,
 
84
                                                                 gpointer                     insert_data);
 
85
static gboolean      gimp_container_tree_view_select_item       (GimpContainerView           *view,
 
86
                                                                 GimpViewable                *viewable,
 
87
                                                                 gpointer                     insert_data);
 
88
static void          gimp_container_tree_view_clear_items       (GimpContainerView           *view);
 
89
static void          gimp_container_tree_view_set_view_size     (GimpContainerView           *view);
 
90
 
 
91
static void          gimp_container_tree_view_real_edit_name    (GimpContainerTreeView       *tree_view);
 
92
 
 
93
static void          gimp_container_tree_view_name_started      (GtkCellRendererText         *cell,
 
94
                                                                 GtkCellEditable             *editable,
 
95
                                                                 const gchar                 *path_str,
 
96
                                                                 GimpContainerTreeView       *tree_view);
 
97
static void          gimp_container_tree_view_name_canceled     (GtkCellRendererText         *cell,
 
98
                                                                 GimpContainerTreeView       *tree_view);
 
99
 
 
100
static void          gimp_container_tree_view_selection_changed (GtkTreeSelection            *sel,
 
101
                                                                 GimpContainerTreeView       *tree_view);
 
102
static gboolean      gimp_container_tree_view_button_press      (GtkWidget                   *widget,
 
103
                                                                 GdkEventButton              *bevent,
 
104
                                                                 GimpContainerTreeView       *tree_view);
 
105
static gboolean      gimp_container_tree_view_tooltip           (GtkWidget                   *widget,
 
106
                                                                 gint                         x,
 
107
                                                                 gint                         y,
 
108
                                                                 gboolean                     keyboard_tip,
 
109
                                                                 GtkTooltip                  *tooltip,
 
110
                                                                 GimpContainerTreeView       *tree_view);
 
111
static GimpViewable *gimp_container_tree_view_drag_viewable     (GtkWidget                   *widget,
 
112
                                                                 GimpContext                **context,
 
113
                                                                 gpointer                     data);
 
114
static GdkPixbuf    *gimp_container_tree_view_drag_pixbuf       (GtkWidget                   *widget,
 
115
                                                                 gpointer                     data);
 
116
 
 
117
static gboolean      gimp_container_tree_view_get_selected_single (GimpContainerTreeView  *tree_view,
 
118
                                                                   GtkTreeIter            *iter);
 
119
static gint          gimp_container_tree_view_get_selected        (GimpContainerView    *view,
 
120
                                                                   GList               **items);
 
121
static void          gimp_container_tree_view_row_expanded        (GtkTreeView               *tree_view,
 
122
                                                                   GtkTreeIter               *iter,
 
123
                                                                   GtkTreePath               *path,
 
124
                                                                   GimpContainerTreeView     *view);
 
125
static void          gimp_container_tree_view_expand_rows         (GtkTreeModel             *model,
 
126
                                                                   GtkTreeView              *view,
 
127
                                                                   GtkTreeIter              *parent);
109
128
 
110
129
 
111
130
G_DEFINE_TYPE_WITH_CODE (GimpContainerTreeView, gimp_container_tree_view,
117
136
 
118
137
static GimpContainerViewInterface *parent_view_iface = NULL;
119
138
 
 
139
static guint tree_view_signals[LAST_SIGNAL] = { 0 };
 
140
 
120
141
 
121
142
static void
122
143
gimp_container_tree_view_class_init (GimpContainerTreeViewClass *klass)
123
144
{
124
145
  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
125
146
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
147
  GtkBindingSet  *binding_set;
126
148
 
127
 
  object_class->constructor = gimp_container_tree_view_constructor;
 
149
  object_class->constructed = gimp_container_tree_view_constructed;
128
150
  object_class->finalize    = gimp_container_tree_view_finalize;
129
151
 
130
152
  widget_class->unmap       = gimp_container_tree_view_unmap;
131
153
  widget_class->popup_menu  = gimp_container_tree_view_popup_menu;
132
154
 
 
155
  klass->edit_name          = gimp_container_tree_view_real_edit_name;
133
156
  klass->drop_possible      = gimp_container_tree_view_real_drop_possible;
134
157
  klass->drop_viewable      = gimp_container_tree_view_real_drop_viewable;
135
158
  klass->drop_color         = NULL;
137
160
  klass->drop_svg           = NULL;
138
161
  klass->drop_component     = NULL;
139
162
  klass->drop_pixbuf        = NULL;
 
163
 
 
164
  tree_view_signals[EDIT_NAME] =
 
165
    g_signal_new ("edit-name",
 
166
                  G_TYPE_FROM_CLASS (klass),
 
167
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
 
168
                  G_STRUCT_OFFSET (GimpContainerTreeViewClass, edit_name),
 
169
                  NULL, NULL,
 
170
                  gimp_marshal_VOID__VOID,
 
171
                  G_TYPE_NONE, 0);
 
172
 
 
173
  binding_set = gtk_binding_set_by_class (klass);
 
174
 
 
175
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_F2, 0,
 
176
                                "edit-name", 0);
 
177
 
 
178
  g_type_class_add_private (klass, sizeof (GimpContainerTreeViewPriv));
140
179
}
141
180
 
142
181
static void
144
183
{
145
184
  parent_view_iface = g_type_interface_peek_parent (iface);
146
185
 
147
 
  iface->set_container = gimp_container_tree_view_set_container;
148
 
  iface->set_context   = gimp_container_tree_view_set_context;
149
 
  iface->insert_item   = gimp_container_tree_view_insert_item;
150
 
  iface->remove_item   = gimp_container_tree_view_remove_item;
151
 
  iface->reorder_item  = gimp_container_tree_view_reorder_item;
152
 
  iface->rename_item   = gimp_container_tree_view_rename_item;
153
 
  iface->select_item   = gimp_container_tree_view_select_item;
154
 
  iface->clear_items   = gimp_container_tree_view_clear_items;
155
 
  iface->set_view_size = gimp_container_tree_view_set_view_size;
 
186
  if (! parent_view_iface)
 
187
    parent_view_iface = g_type_default_interface_peek (GIMP_TYPE_CONTAINER_VIEW);
 
188
 
 
189
  iface->set_container      = gimp_container_tree_view_set_container;
 
190
  iface->set_context        = gimp_container_tree_view_set_context;
 
191
  iface->set_selection_mode = gimp_container_tree_view_set_selection_mode;
 
192
  iface->insert_item        = gimp_container_tree_view_insert_item;
 
193
  iface->remove_item        = gimp_container_tree_view_remove_item;
 
194
  iface->reorder_item       = gimp_container_tree_view_reorder_item;
 
195
  iface->rename_item        = gimp_container_tree_view_rename_item;
 
196
  iface->select_item        = gimp_container_tree_view_select_item;
 
197
  iface->clear_items        = gimp_container_tree_view_clear_items;
 
198
  iface->set_view_size      = gimp_container_tree_view_set_view_size;
 
199
  iface->get_selected       = gimp_container_tree_view_get_selected;
156
200
 
157
201
  iface->insert_data_free = (GDestroyNotify) gtk_tree_iter_free;
158
202
}
162
206
{
163
207
  GimpContainerBox *box = GIMP_CONTAINER_BOX (tree_view);
164
208
 
165
 
  tree_view->n_model_columns = NUM_COLUMNS;
166
 
 
167
 
  tree_view->model_columns[COLUMN_RENDERER]        = GIMP_TYPE_VIEW_RENDERER;
168
 
  tree_view->model_columns[COLUMN_NAME]            = G_TYPE_STRING;
169
 
  tree_view->model_columns[COLUMN_NAME_ATTRIBUTES] = PANGO_TYPE_ATTR_LIST;
170
 
 
171
 
  tree_view->model_column_renderer        = COLUMN_RENDERER;
172
 
  tree_view->model_column_name            = COLUMN_NAME;
173
 
  tree_view->model_column_name_attributes = COLUMN_NAME_ATTRIBUTES;
 
209
  tree_view->priv = G_TYPE_INSTANCE_GET_PRIVATE (tree_view,
 
210
                                                 GIMP_TYPE_CONTAINER_TREE_VIEW,
 
211
                                                 GimpContainerTreeViewPriv);
 
212
 
 
213
  gimp_container_tree_store_columns_init (tree_view->model_columns,
 
214
                                          &tree_view->n_model_columns);
174
215
 
175
216
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (box->scrolled_win),
176
217
                                       GTK_SHADOW_IN);
178
219
                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
179
220
}
180
221
 
181
 
static GObject *
182
 
gimp_container_tree_view_constructor (GType                  type,
183
 
                                      guint                  n_params,
184
 
                                      GObjectConstructParam *params)
 
222
static void
 
223
gimp_container_tree_view_constructed (GObject *object)
185
224
{
186
 
  GimpContainerTreeView *tree_view;
187
 
  GimpContainerView     *view;
188
 
  GimpContainerBox      *box;
189
 
  GtkListStore          *list;
190
 
  GObject               *object;
191
 
 
192
 
  object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
193
 
 
194
 
  tree_view = GIMP_CONTAINER_TREE_VIEW (object);
195
 
  view      = GIMP_CONTAINER_VIEW (object);
196
 
  box       = GIMP_CONTAINER_BOX (object);
197
 
 
198
 
  list = gtk_list_store_newv (tree_view->n_model_columns,
199
 
                              tree_view->model_columns);
200
 
  tree_view->model = GTK_TREE_MODEL (list);
 
225
  GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (object);
 
226
  GimpContainerView     *view      = GIMP_CONTAINER_VIEW (object);
 
227
  GimpContainerBox      *box       = GIMP_CONTAINER_BOX (object);
 
228
 
 
229
  if (G_OBJECT_CLASS (parent_class)->constructed)
 
230
    G_OBJECT_CLASS (parent_class)->constructed (object);
 
231
 
 
232
  tree_view->model = gimp_container_tree_store_new (view,
 
233
                                                    tree_view->n_model_columns,
 
234
                                                    tree_view->model_columns);
201
235
 
202
236
  tree_view->view = g_object_new (GTK_TYPE_TREE_VIEW,
203
 
                                  "model",           list,
204
 
                                  "search-column",   COLUMN_NAME,
 
237
                                  "model",           tree_view->model,
 
238
                                  "search-column",   GIMP_CONTAINER_TREE_STORE_COLUMN_NAME,
205
239
                                  "enable-search",   FALSE,
206
240
                                  "headers-visible", FALSE,
207
241
                                  "has-tooltip",     TRUE,
 
242
                                  "show-expanders",  GIMP_CONTAINER_VIEW_GET_INTERFACE (view)->model_is_tree,
208
243
                                  NULL);
209
 
  g_object_unref (list);
 
244
  g_object_unref (tree_view->model);
210
245
 
211
246
  gtk_container_add (GTK_CONTAINER (box->scrolled_win),
212
247
                     GTK_WIDGET (tree_view->view));
217
252
  tree_view->main_column = gtk_tree_view_column_new ();
218
253
  gtk_tree_view_insert_column (tree_view->view, tree_view->main_column, 0);
219
254
 
 
255
  gtk_tree_view_set_expander_column (tree_view->view, tree_view->main_column);
 
256
  gtk_tree_view_set_enable_tree_lines (tree_view->view, TRUE);
 
257
 
220
258
  tree_view->renderer_cell = gimp_cell_renderer_viewable_new ();
221
259
  gtk_tree_view_column_pack_start (tree_view->main_column,
222
260
                                   tree_view->renderer_cell,
224
262
 
225
263
  gtk_tree_view_column_set_attributes (tree_view->main_column,
226
264
                                       tree_view->renderer_cell,
227
 
                                       "renderer", COLUMN_RENDERER,
 
265
                                       "renderer", GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER,
228
266
                                       NULL);
229
267
 
230
 
  tree_view->name_cell = gtk_cell_renderer_text_new ();
231
 
  g_object_set (tree_view->name_cell, "xalign", 0.0, NULL);
 
268
  tree_view->priv->name_cell = gtk_cell_renderer_text_new ();
 
269
  g_object_set (tree_view->priv->name_cell, "xalign", 0.0, NULL);
232
270
  gtk_tree_view_column_pack_end (tree_view->main_column,
233
 
                                 tree_view->name_cell,
 
271
                                 tree_view->priv->name_cell,
234
272
                                 FALSE);
235
273
 
236
274
  gtk_tree_view_column_set_attributes (tree_view->main_column,
237
 
                                       tree_view->name_cell,
238
 
                                       "text",       COLUMN_NAME,
239
 
                                       "attributes", COLUMN_NAME_ATTRIBUTES,
 
275
                                       tree_view->priv->name_cell,
 
276
                                       "text",       GIMP_CONTAINER_TREE_STORE_COLUMN_NAME,
 
277
                                       "attributes", GIMP_CONTAINER_TREE_STORE_COLUMN_NAME_ATTRIBUTES,
 
278
                                       "sensitive",  GIMP_CONTAINER_TREE_STORE_COLUMN_NAME_SENSITIVE,
240
279
                                       NULL);
241
280
 
242
 
  g_signal_connect (tree_view->name_cell, "editing-canceled",
 
281
  g_signal_connect (tree_view->priv->name_cell, "editing-started",
 
282
                    G_CALLBACK (gimp_container_tree_view_name_started),
 
283
                    tree_view);
 
284
  g_signal_connect (tree_view->priv->name_cell, "editing-canceled",
243
285
                    G_CALLBACK (gimp_container_tree_view_name_canceled),
244
286
                    tree_view);
245
287
 
246
 
  tree_view->renderer_cells = g_list_prepend (tree_view->renderer_cells,
 
288
  gimp_container_tree_view_add_renderer_cell (tree_view,
247
289
                                              tree_view->renderer_cell);
248
290
 
249
 
  tree_view->selection = gtk_tree_view_get_selection (tree_view->view);
 
291
  tree_view->priv->selection = gtk_tree_view_get_selection (tree_view->view);
250
292
 
251
 
  g_signal_connect (tree_view->selection, "changed",
 
293
  g_signal_connect (tree_view->priv->selection, "changed",
252
294
                    G_CALLBACK (gimp_container_tree_view_selection_changed),
253
295
                    tree_view);
254
296
 
268
310
  g_signal_connect (tree_view->view, "query-tooltip",
269
311
                    G_CALLBACK (gimp_container_tree_view_tooltip),
270
312
                    tree_view);
271
 
 
272
 
  return object;
273
313
}
274
314
 
275
315
static void
277
317
{
278
318
  GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (object);
279
319
 
280
 
  if (tree_view->toggle_cells)
281
 
    {
282
 
      g_list_free (tree_view->toggle_cells);
283
 
      tree_view->toggle_cells = NULL;
284
 
    }
285
 
 
286
 
  if (tree_view->renderer_cells)
287
 
    {
288
 
      g_list_free (tree_view->renderer_cells);
289
 
      tree_view->renderer_cells = NULL;
290
 
    }
291
 
 
292
 
  if (tree_view->editable_cells)
293
 
    {
294
 
      g_list_free (tree_view->editable_cells);
295
 
      tree_view->editable_cells = NULL;
 
320
  if (tree_view->priv->toggle_cells)
 
321
    {
 
322
      g_list_free (tree_view->priv->toggle_cells);
 
323
      tree_view->priv->toggle_cells = NULL;
 
324
    }
 
325
 
 
326
  if (tree_view->priv->renderer_cells)
 
327
    {
 
328
      g_list_free (tree_view->priv->renderer_cells);
 
329
      tree_view->priv->renderer_cells = NULL;
 
330
    }
 
331
 
 
332
  if (tree_view->priv->editable_cells)
 
333
    {
 
334
      g_list_free (tree_view->priv->editable_cells);
 
335
      tree_view->priv->editable_cells = NULL;
296
336
    }
297
337
 
298
338
  G_OBJECT_CLASS (parent_class)->finalize (object);
303
343
{
304
344
  GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (widget);
305
345
 
306
 
  if (tree_view->scroll_timeout_id)
 
346
  if (tree_view->priv->scroll_timeout_id)
307
347
    {
308
 
      g_source_remove (tree_view->scroll_timeout_id);
309
 
      tree_view->scroll_timeout_id = 0;
 
348
      g_source_remove (tree_view->priv->scroll_timeout_id);
 
349
      tree_view->priv->scroll_timeout_id = 0;
310
350
    }
311
351
 
312
352
  GTK_WIDGET_CLASS (parent_class)->unmap (widget);
320
360
{
321
361
  GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (data);
322
362
  GtkWidget             *widget    = GTK_WIDGET (tree_view->view);
 
363
  GtkAllocation          allocation;
323
364
  GtkTreeIter            selected_iter;
324
365
 
325
 
  gdk_window_get_origin (widget->window, x, y);
326
 
 
327
 
  if (GTK_WIDGET_NO_WINDOW (widget))
 
366
  gtk_widget_get_allocation (widget, &allocation);
 
367
 
 
368
  gdk_window_get_origin (gtk_widget_get_window (widget), x, y);
 
369
 
 
370
  if (! gtk_widget_get_has_window (widget))
328
371
    {
329
 
      *x += widget->allocation.x;
330
 
      *y += widget->allocation.y;
 
372
      *x += allocation.x;
 
373
      *y += allocation.y;
331
374
    }
332
375
 
333
 
  if (gtk_tree_selection_get_selected (tree_view->selection, NULL,
334
 
                                       &selected_iter))
 
376
  if (gimp_container_tree_view_get_selected_single (tree_view, &selected_iter))
335
377
    {
336
378
      GtkTreePath  *path;
337
379
      GdkRectangle  cell_rect;
343
385
      gtk_tree_path_free (path);
344
386
 
345
387
      center = cell_rect.y + cell_rect.height / 2;
346
 
      center = CLAMP (center, 0, widget->allocation.height);
 
388
      center = CLAMP (center, 0, allocation.height);
347
389
 
348
 
      *x += widget->allocation.width / 2;
 
390
      *x += allocation.width / 2;
349
391
      *y += center;
350
392
    }
351
393
  else
401
443
}
402
444
 
403
445
void
 
446
gimp_container_tree_view_set_main_column_title (GimpContainerTreeView *tree_view,
 
447
                                                const gchar           *title)
 
448
{
 
449
  g_return_if_fail (GIMP_IS_CONTAINER_TREE_VIEW (tree_view));
 
450
 
 
451
  gtk_tree_view_column_set_title (tree_view->main_column,
 
452
                                  title);
 
453
}
 
454
 
 
455
void
 
456
gimp_container_tree_view_add_toggle_cell (GimpContainerTreeView *tree_view,
 
457
                                          GtkCellRenderer       *cell)
 
458
{
 
459
  g_return_if_fail (GIMP_IS_CONTAINER_TREE_VIEW (tree_view));
 
460
  g_return_if_fail (GIMP_IS_CELL_RENDERER_TOGGLE (cell));
 
461
 
 
462
  tree_view->priv->toggle_cells = g_list_prepend (tree_view->priv->toggle_cells,
 
463
                                                  cell);
 
464
}
 
465
 
 
466
void
 
467
gimp_container_tree_view_add_renderer_cell (GimpContainerTreeView *tree_view,
 
468
                                            GtkCellRenderer       *cell)
 
469
{
 
470
  g_return_if_fail (GIMP_IS_CONTAINER_TREE_VIEW (tree_view));
 
471
  g_return_if_fail (GIMP_IS_CELL_RENDERER_VIEWABLE (cell));
 
472
 
 
473
  tree_view->priv->renderer_cells = g_list_prepend (tree_view->priv->renderer_cells,
 
474
                                                    cell);
 
475
 
 
476
  gimp_container_tree_store_add_renderer_cell (GIMP_CONTAINER_TREE_STORE (tree_view->model),
 
477
                                               cell);
 
478
}
 
479
 
 
480
void
 
481
gimp_container_tree_view_set_dnd_drop_to_empty (GimpContainerTreeView *tree_view,
 
482
                                                gboolean               dnd_drop_to_empty)
 
483
{
 
484
  g_return_if_fail (GIMP_IS_CONTAINER_TREE_VIEW (tree_view));
 
485
 
 
486
  tree_view->priv->dnd_drop_to_empty = dnd_drop_to_empty;
 
487
}
 
488
 
 
489
void
404
490
gimp_container_tree_view_connect_name_edited (GimpContainerTreeView *tree_view,
405
491
                                              GCallback              callback,
406
492
                                              gpointer               data)
408
494
  g_return_if_fail (GIMP_IS_CONTAINER_TREE_VIEW (tree_view));
409
495
  g_return_if_fail (callback != NULL);
410
496
 
411
 
  g_object_set (tree_view->name_cell,
 
497
  g_object_set (tree_view->priv->name_cell,
412
498
                "mode",     GTK_CELL_RENDERER_MODE_EDITABLE,
413
499
                "editable", TRUE,
414
500
                NULL);
415
501
 
416
 
  if (! g_list_find (tree_view->editable_cells, tree_view->name_cell))
417
 
    tree_view->editable_cells = g_list_prepend (tree_view->editable_cells,
418
 
                                                tree_view->name_cell);
 
502
  if (! g_list_find (tree_view->priv->editable_cells, tree_view->priv->name_cell))
 
503
    tree_view->priv->editable_cells = g_list_prepend (tree_view->priv->editable_cells,
 
504
                                                      tree_view->priv->name_cell);
419
505
 
420
 
  g_signal_connect (tree_view->name_cell, "edited",
 
506
  g_signal_connect (tree_view->priv->name_cell, "edited",
421
507
                    callback,
422
508
                    data);
423
509
}
424
510
 
425
 
static void
426
 
gimp_container_tree_view_set (GimpContainerTreeView *tree_view,
427
 
                              GtkTreeIter           *iter,
428
 
                              GimpViewable          *viewable)
429
 
{
430
 
  GimpContainerView *view = GIMP_CONTAINER_VIEW (tree_view);
431
 
  GimpViewRenderer  *renderer;
432
 
  gchar             *name;
433
 
  gint               view_size;
434
 
  gint               border_width;
435
 
 
436
 
  view_size = gimp_container_view_get_view_size (view, &border_width);
437
 
 
438
 
  renderer = gimp_view_renderer_new (gimp_container_view_get_context (view),
439
 
                                     G_TYPE_FROM_INSTANCE (viewable),
440
 
                                     view_size, border_width,
441
 
                                     FALSE);
442
 
  gimp_view_renderer_set_viewable (renderer, viewable);
443
 
  gimp_view_renderer_remove_idle (renderer);
444
 
 
445
 
  g_signal_connect (renderer, "update",
446
 
                    G_CALLBACK (gimp_container_tree_view_renderer_update),
447
 
                    tree_view);
448
 
 
449
 
  name = gimp_viewable_get_description (viewable, NULL);
450
 
 
451
 
  gtk_list_store_set (GTK_LIST_STORE (tree_view->model), iter,
452
 
                      COLUMN_RENDERER, renderer,
453
 
                      COLUMN_NAME,     name,
454
 
                      -1);
455
 
 
456
 
  g_free (name);
457
 
  g_object_unref (renderer);
458
 
}
459
511
 
460
512
/*  GimpContainerView methods  */
461
513
 
470
522
 
471
523
  if (old_container)
472
524
    {
 
525
      g_signal_handlers_disconnect_by_func (tree_view->view,
 
526
                                            gimp_container_tree_view_row_expanded,
 
527
                                            tree_view);
473
528
      if (! container)
474
529
        {
475
530
          if (gimp_dnd_viewable_source_remove (GTK_WIDGET (tree_view->view),
476
 
                                               old_container->children_type))
 
531
                                               gimp_container_get_children_type (old_container)))
477
532
            {
478
 
              if (GIMP_VIEWABLE_CLASS (g_type_class_peek (old_container->children_type))->get_size)
 
533
              if (GIMP_VIEWABLE_CLASS (g_type_class_peek (gimp_container_get_children_type (old_container)))->get_size)
479
534
                gimp_dnd_pixbuf_source_remove (GTK_WIDGET (tree_view->view));
480
535
 
481
536
              gtk_drag_source_unset (GTK_WIDGET (tree_view->view));
490
545
    {
491
546
      if (gimp_dnd_drag_source_set_by_type (GTK_WIDGET (tree_view->view),
492
547
                                            GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
493
 
                                            container->children_type,
 
548
                                            gimp_container_get_children_type (container),
494
549
                                            GDK_ACTION_COPY))
495
550
        {
496
551
          gimp_dnd_viewable_source_add (GTK_WIDGET (tree_view->view),
497
 
                                        container->children_type,
 
552
                                        gimp_container_get_children_type (container),
498
553
                                        gimp_container_tree_view_drag_viewable,
499
554
                                        tree_view);
500
555
 
501
 
          if (GIMP_VIEWABLE_CLASS (g_type_class_peek (container->children_type))->get_size)
 
556
          if (GIMP_VIEWABLE_CLASS (g_type_class_peek (gimp_container_get_children_type (container)))->get_size)
502
557
            gimp_dnd_pixbuf_source_add (GTK_WIDGET (tree_view->view),
503
558
                                        gimp_container_tree_view_drag_pixbuf,
504
559
                                        tree_view);
514
569
 
515
570
  parent_view_iface->set_container (view, container);
516
571
 
 
572
  if (container)
 
573
    {
 
574
      gimp_container_tree_view_expand_rows (tree_view->model,
 
575
                                            tree_view->view,
 
576
                                            NULL);
 
577
 
 
578
      g_signal_connect (tree_view->view,
 
579
                        "row-collapsed",
 
580
                        G_CALLBACK (gimp_container_tree_view_row_expanded),
 
581
                        tree_view);
 
582
      g_signal_connect (tree_view->view,
 
583
                        "row-expanded",
 
584
                        G_CALLBACK (gimp_container_tree_view_row_expanded),
 
585
                        tree_view);
 
586
    }
 
587
 
517
588
  gtk_tree_view_columns_autosize (tree_view->view);
518
589
}
519
590
 
523
594
{
524
595
  GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
525
596
 
 
597
  if (tree_view->model)
 
598
    gimp_container_tree_store_set_context (GIMP_CONTAINER_TREE_STORE (tree_view->model),
 
599
                                           context);
 
600
 
526
601
  parent_view_iface->set_context (view, context);
527
 
 
528
 
  if (tree_view->model)
529
 
    {
530
 
      GtkTreeIter iter;
531
 
      gboolean    iter_valid;
532
 
 
533
 
      for (iter_valid = gtk_tree_model_get_iter_first (tree_view->model, &iter);
534
 
           iter_valid;
535
 
           iter_valid = gtk_tree_model_iter_next (tree_view->model, &iter))
536
 
        {
537
 
          GimpViewRenderer *renderer;
538
 
 
539
 
          gtk_tree_model_get (tree_view->model, &iter,
540
 
                              COLUMN_RENDERER, &renderer,
541
 
                              -1);
542
 
 
543
 
          gimp_view_renderer_set_context (renderer, context);
544
 
          g_object_unref (renderer);
545
 
        }
546
 
    }
 
602
}
 
603
 
 
604
static void
 
605
gimp_container_tree_view_set_selection_mode (GimpContainerView *view,
 
606
                                             GtkSelectionMode   mode)
 
607
{
 
608
  GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
 
609
 
 
610
  gtk_tree_selection_set_mode (tree_view->priv->selection, mode);
 
611
 
 
612
  parent_view_iface->set_selection_mode (view, mode);
547
613
}
548
614
 
549
615
static gpointer
550
616
gimp_container_tree_view_insert_item (GimpContainerView *view,
551
617
                                      GimpViewable      *viewable,
 
618
                                      gpointer           parent_insert_data,
552
619
                                      gint               index)
553
620
{
554
621
  GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
555
 
  GtkTreeIter            iter;
556
 
 
557
 
  if (index == -1)
558
 
    gtk_list_store_append (GTK_LIST_STORE (tree_view->model), &iter);
559
 
  else
560
 
    gtk_list_store_insert (GTK_LIST_STORE (tree_view->model), &iter, index);
561
 
 
562
 
  gimp_container_tree_view_set (tree_view, &iter, viewable);
563
 
 
564
 
  return gtk_tree_iter_copy (&iter);
 
622
  GtkTreeIter           *iter;
 
623
 
 
624
  iter = gimp_container_tree_store_insert_item (GIMP_CONTAINER_TREE_STORE (tree_view->model),
 
625
                                                viewable,
 
626
                                                parent_insert_data,
 
627
                                                index);
 
628
  return iter;
565
629
}
566
630
 
567
631
static void
572
636
  GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
573
637
  GtkTreeIter           *iter      = (GtkTreeIter *) insert_data;
574
638
 
 
639
  gimp_container_tree_store_remove_item (GIMP_CONTAINER_TREE_STORE (tree_view->model),
 
640
                                         viewable,
 
641
                                         iter);
 
642
 
575
643
  if (iter)
576
 
    {
577
 
      gtk_list_store_remove (GTK_LIST_STORE (tree_view->model), iter);
578
 
 
579
 
      gtk_tree_view_columns_autosize (tree_view->view);
580
 
 
581
 
      /*  If the store is empty after this remove, clear out renderers
582
 
       *  from all cells so they don't keep refing the viewables
583
 
       *  (see bug #149906).
584
 
       */
585
 
      if (! gtk_tree_model_iter_n_children (tree_view->model, NULL))
586
 
        {
587
 
          GList *list;
588
 
 
589
 
          for (list = tree_view->renderer_cells; list; list = list->next)
590
 
            g_object_set (list->data, "renderer", NULL, NULL);
591
 
        }
592
 
    }
 
644
    gtk_tree_view_columns_autosize (tree_view->view);
593
645
}
594
646
 
595
647
static void
600
652
{
601
653
  GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
602
654
  GtkTreeIter           *iter      = (GtkTreeIter *) insert_data;
 
655
  gboolean               selected  = FALSE;
603
656
 
604
657
  if (iter)
605
658
    {
606
 
      GimpContainer *container;
607
 
      GtkTreePath   *path;
608
 
      GtkTreeIter    selected_iter;
609
 
      gboolean       selected;
610
 
 
611
 
      container = gimp_container_view_get_container (view);
612
 
 
613
 
      selected = gtk_tree_selection_get_selected (tree_view->selection,
614
 
                                                  NULL, &selected_iter);
 
659
      GtkTreeIter selected_iter;
 
660
 
 
661
      selected = gimp_container_tree_view_get_selected_single (tree_view,
 
662
                                                               &selected_iter);
615
663
 
616
664
      if (selected)
617
665
        {
618
666
          GimpViewRenderer *renderer;
619
667
 
620
668
          gtk_tree_model_get (tree_view->model, &selected_iter,
621
 
                              COLUMN_RENDERER, &renderer,
 
669
                              GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
622
670
                              -1);
623
671
 
624
672
          if (renderer->viewable != viewable)
626
674
 
627
675
          g_object_unref (renderer);
628
676
        }
629
 
 
630
 
      if (new_index == -1 || new_index == container->num_children - 1)
631
 
        {
632
 
          gtk_list_store_move_before (GTK_LIST_STORE (tree_view->model),
633
 
                                      iter, NULL);
634
 
        }
635
 
      else if (new_index == 0)
636
 
        {
637
 
          gtk_list_store_move_after (GTK_LIST_STORE (tree_view->model),
638
 
                                     iter, NULL);
639
 
        }
640
 
      else
641
 
        {
642
 
          GtkTreeIter place_iter;
643
 
          gint        old_index;
644
 
 
645
 
          path = gtk_tree_model_get_path (tree_view->model, iter);
646
 
          old_index = gtk_tree_path_get_indices (path)[0];
647
 
          gtk_tree_path_free (path);
648
 
 
649
 
          if (new_index != old_index)
650
 
            {
651
 
              path = gtk_tree_path_new_from_indices (new_index, -1);
652
 
              gtk_tree_model_get_iter (tree_view->model, &place_iter, path);
653
 
              gtk_tree_path_free (path);
654
 
 
655
 
              if (new_index > old_index)
656
 
                gtk_list_store_move_after (GTK_LIST_STORE (tree_view->model),
657
 
                                           iter, &place_iter);
658
 
              else
659
 
                gtk_list_store_move_before (GTK_LIST_STORE (tree_view->model),
660
 
                                            iter, &place_iter);
661
 
            }
662
 
        }
663
 
 
664
 
      if (selected)
665
 
        gimp_container_view_select_item (view, viewable);
666
677
    }
 
678
 
 
679
  gimp_container_tree_store_reorder_item (GIMP_CONTAINER_TREE_STORE (tree_view->model),
 
680
                                          viewable,
 
681
                                          new_index,
 
682
                                          iter);
 
683
 
 
684
  if (selected)
 
685
    gimp_container_view_select_item (view, viewable);
667
686
}
668
687
 
669
688
static void
674
693
  GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
675
694
  GtkTreeIter           *iter      = (GtkTreeIter *) insert_data;
676
695
 
677
 
  if (iter)
 
696
  if (gimp_container_tree_store_rename_item (GIMP_CONTAINER_TREE_STORE (tree_view->model),
 
697
                                             viewable,
 
698
                                             iter))
678
699
    {
679
 
      gchar *name = gimp_viewable_get_description (viewable, NULL);
680
 
      gchar *old_name;
681
 
 
682
 
      gtk_tree_model_get (tree_view->model, iter,
683
 
                          COLUMN_NAME, &old_name,
684
 
                          -1);
685
 
 
686
 
      gtk_list_store_set (GTK_LIST_STORE (tree_view->model), iter,
687
 
                          COLUMN_NAME, name,
688
 
                          -1);
689
 
 
690
 
      if (name && old_name && strlen (name) < strlen (old_name))
691
 
        gtk_tree_view_columns_autosize (tree_view->view);
692
 
 
693
 
      g_free (name);
694
 
      g_free (old_name);
 
700
      gtk_tree_view_columns_autosize (tree_view->view);
695
701
    }
696
702
}
697
703
 
701
707
                                      gpointer           insert_data)
702
708
{
703
709
  GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
704
 
  GtkTreeIter           *iter      = (GtkTreeIter *) insert_data;
705
710
 
706
 
  if (iter)
 
711
  if (viewable && insert_data)
707
712
    {
708
713
      GtkTreePath *path;
 
714
      GtkTreePath *parent_path;
 
715
      GtkTreeIter *iter = (GtkTreeIter *) insert_data;
709
716
 
710
717
      path = gtk_tree_model_get_path (tree_view->model, iter);
711
718
 
712
 
      g_signal_handlers_block_by_func (tree_view->selection,
 
719
      parent_path = gtk_tree_path_copy (path);
 
720
 
 
721
      if (gtk_tree_path_up (parent_path))
 
722
        gtk_tree_view_expand_to_path (tree_view->view, parent_path);
 
723
 
 
724
      gtk_tree_path_free (parent_path);
 
725
 
 
726
      g_signal_handlers_block_by_func (tree_view->priv->selection,
713
727
                                       gimp_container_tree_view_selection_changed,
714
728
                                       tree_view);
715
729
 
716
730
      gtk_tree_view_set_cursor (tree_view->view, path, NULL, FALSE);
717
731
 
718
 
      g_signal_handlers_unblock_by_func (tree_view->selection,
 
732
      g_signal_handlers_unblock_by_func (tree_view->priv->selection,
719
733
                                         gimp_container_tree_view_selection_changed,
720
734
                                         tree_view);
721
735
 
724
738
 
725
739
      gtk_tree_path_free (path);
726
740
    }
727
 
  else
 
741
  else if (insert_data == NULL)
728
742
    {
729
 
      gtk_tree_selection_unselect_all (tree_view->selection);
 
743
      /* viewable == NULL && insert_data != NULL means multiple selection.
 
744
       * viewable == NULL && insert_data == NULL means no selection. */
 
745
      gtk_tree_selection_unselect_all (tree_view->priv->selection);
730
746
    }
731
747
 
732
748
  return TRUE;
737
753
{
738
754
  GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
739
755
 
740
 
  gtk_list_store_clear (GTK_LIST_STORE (tree_view->model));
741
 
 
742
 
  /*  Clear out renderers from all cells so they don't keep refing the
743
 
   *  viewables (see bug #149906).
744
 
   */
745
 
  if (! gtk_tree_model_iter_n_children (tree_view->model, NULL))
746
 
    {
747
 
      GList *list;
748
 
 
749
 
      for (list = tree_view->renderer_cells; list; list = list->next)
750
 
        g_object_set (list->data, "renderer", NULL, NULL);
751
 
    }
 
756
  gimp_container_tree_store_clear_items (GIMP_CONTAINER_TREE_STORE (tree_view->model));
752
757
 
753
758
  parent_view_iface->clear_items (view);
754
759
}
765
770
  view_size = gimp_container_view_get_view_size (view, &border_width);
766
771
 
767
772
  if (tree_view->model)
768
 
    {
769
 
      GtkTreeIter iter;
770
 
      gboolean    iter_valid;
771
 
 
772
 
      for (iter_valid = gtk_tree_model_get_iter_first (tree_view->model, &iter);
773
 
           iter_valid;
774
 
           iter_valid = gtk_tree_model_iter_next (tree_view->model, &iter))
775
 
        {
776
 
          GimpViewRenderer *renderer;
777
 
 
778
 
          gtk_tree_model_get (tree_view->model, &iter,
779
 
                              COLUMN_RENDERER, &renderer,
780
 
                              -1);
781
 
 
782
 
          gimp_view_renderer_set_size (renderer, view_size, border_width);
783
 
          g_object_unref (renderer);
784
 
        }
785
 
    }
 
773
    gimp_container_tree_store_set_view_size (GIMP_CONTAINER_TREE_STORE (tree_view->model));
786
774
 
787
775
  tree_widget = GTK_WIDGET (tree_view->view);
788
776
 
789
777
  if (! tree_widget)
790
778
    return;
791
779
 
792
 
  for (list = tree_view->toggle_cells; list; list = g_list_next (list))
 
780
  for (list = tree_view->priv->toggle_cells; list; list = g_list_next (list))
793
781
    {
794
782
      gchar       *stock_id;
795
783
      GtkIconSize  icon_size;
818
806
}
819
807
 
820
808
 
 
809
/*  GimpContainerTreeView methods  */
 
810
 
 
811
static void
 
812
gimp_container_tree_view_real_edit_name (GimpContainerTreeView *tree_view)
 
813
{
 
814
  GtkTreeIter selected_iter;
 
815
 
 
816
  if (g_list_find (tree_view->priv->editable_cells,
 
817
                   tree_view->priv->name_cell) &&
 
818
      gimp_container_tree_view_get_selected_single (tree_view,
 
819
                                                    &selected_iter))
 
820
    {
 
821
      GtkTreePath *path;
 
822
 
 
823
      path = gtk_tree_model_get_path (tree_view->model, &selected_iter);
 
824
 
 
825
      gtk_tree_view_set_cursor_on_cell (tree_view->view, path,
 
826
                                        tree_view->main_column,
 
827
                                        tree_view->priv->name_cell,
 
828
                                        TRUE);
 
829
 
 
830
      gtk_tree_path_free (path);
 
831
    }
 
832
}
 
833
 
 
834
 
821
835
/*  callbacks  */
822
836
 
823
837
static void
 
838
gimp_container_tree_view_name_started (GtkCellRendererText   *cell,
 
839
                                       GtkCellEditable       *editable,
 
840
                                       const gchar           *path_str,
 
841
                                       GimpContainerTreeView *tree_view)
 
842
{
 
843
  GtkTreePath *path;
 
844
  GtkTreeIter  iter;
 
845
 
 
846
  path = gtk_tree_path_new_from_string (path_str);
 
847
 
 
848
  if (gtk_tree_model_get_iter (tree_view->model, &iter, path))
 
849
    {
 
850
      GimpViewRenderer *renderer;
 
851
      const gchar      *real_name;
 
852
 
 
853
      gtk_tree_model_get (tree_view->model, &iter,
 
854
                          GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
 
855
                          -1);
 
856
 
 
857
      real_name = gimp_object_get_name (renderer->viewable);
 
858
 
 
859
      g_object_unref (renderer);
 
860
 
 
861
      gtk_entry_set_text (GTK_ENTRY (editable), real_name);
 
862
    }
 
863
 
 
864
  gtk_tree_path_free (path);
 
865
}
 
866
 
 
867
static void
824
868
gimp_container_tree_view_name_canceled (GtkCellRendererText   *cell,
825
869
                                        GimpContainerTreeView *tree_view)
826
870
{
827
871
  GtkTreeIter iter;
828
872
 
829
 
  if (gtk_tree_selection_get_selected (tree_view->selection, NULL, &iter))
 
873
  if (gimp_container_tree_view_get_selected_single (tree_view, &iter))
830
874
    {
831
875
      GimpViewRenderer *renderer;
832
876
      gchar            *name;
833
877
 
834
878
      gtk_tree_model_get (tree_view->model, &iter,
835
 
                          tree_view->model_column_renderer, &renderer,
 
879
                          GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
836
880
                          -1);
837
881
 
838
882
      name = gimp_viewable_get_description (renderer->viewable, NULL);
839
883
 
840
 
      gtk_list_store_set (GTK_LIST_STORE (tree_view->model), &iter,
841
 
                          tree_view->model_column_name, name,
 
884
      gtk_tree_store_set (GTK_TREE_STORE (tree_view->model), &iter,
 
885
                          GIMP_CONTAINER_TREE_STORE_COLUMN_NAME, name,
842
886
                          -1);
843
887
 
844
888
      g_free (name);
850
894
gimp_container_tree_view_selection_changed (GtkTreeSelection      *selection,
851
895
                                            GimpContainerTreeView *tree_view)
852
896
{
853
 
  GtkTreeIter iter;
854
 
 
855
 
  if (gtk_tree_selection_get_selected (selection, NULL, &iter))
856
 
    {
857
 
      GimpViewRenderer *renderer;
858
 
 
859
 
      gtk_tree_model_get (tree_view->model, &iter,
860
 
                          COLUMN_RENDERER, &renderer,
861
 
                          -1);
862
 
 
863
 
      gimp_container_view_item_selected (GIMP_CONTAINER_VIEW (tree_view),
864
 
                                         renderer->viewable);
865
 
      g_object_unref (renderer);
866
 
    }
 
897
  GimpContainerView    *view = GIMP_CONTAINER_VIEW (tree_view);
 
898
  GList                *items;
 
899
 
 
900
  gimp_container_tree_view_get_selected (view, &items);
 
901
  gimp_container_view_multi_selected (view, items);
 
902
  g_list_free (items);
867
903
}
868
904
 
869
905
static GtkCellRenderer *
883
919
      gint             start;
884
920
      gint             width;
885
921
 
886
 
      if (renderer->visible &&
 
922
      if (gtk_cell_renderer_get_visible (renderer) &&
887
923
          gtk_tree_view_column_cell_get_position (column, renderer,
888
924
                                                  &start, &width))
889
925
        {
 
926
          gint xpad, ypad;
890
927
          gint x;
891
928
 
 
929
          gtk_cell_renderer_get_padding (renderer, &xpad, &ypad);
 
930
 
892
931
          if (rtl)
893
932
            x = column_area->x + column_area->width - start - width;
894
933
          else
895
934
            x = start + column_area->x;
896
935
 
897
 
          if (tree_x >= x + renderer->xpad &&
898
 
              tree_x < x + width - renderer->xpad)
 
936
          if (tree_x >= x + xpad &&
 
937
              tree_x <  x + width - xpad)
899
938
            {
900
939
              return renderer;
901
940
            }
914
953
  GtkTreeViewColumn *column;
915
954
  GtkTreePath       *path;
916
955
 
917
 
  tree_view->dnd_renderer = NULL;
 
956
  tree_view->priv->dnd_renderer = NULL;
918
957
 
919
 
  if (! GTK_WIDGET_HAS_FOCUS (widget))
 
958
  if (! gtk_widget_has_focus (widget))
920
959
    gtk_widget_grab_focus (widget);
921
960
 
922
961
  if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
929
968
      GtkCellRenderer          *edit_cell    = NULL;
930
969
      GdkRectangle              column_area;
931
970
      GtkTreeIter               iter;
 
971
      gboolean                  handled = TRUE;
 
972
      gboolean                  multisel_mode;
 
973
 
 
974
      multisel_mode = (gtk_tree_selection_get_mode (tree_view->priv->selection)
 
975
                       == GTK_SELECTION_MULTIPLE);
932
976
 
933
977
      gtk_tree_model_get_iter (tree_view->model, &iter, path);
934
978
 
935
979
      gtk_tree_model_get (tree_view->model, &iter,
936
 
                          COLUMN_RENDERER, &renderer,
 
980
                          GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
937
981
                          -1);
938
982
 
939
 
      tree_view->dnd_renderer = renderer;
 
983
      tree_view->priv->dnd_renderer = renderer;
940
984
 
941
 
      gtk_tree_view_get_background_area (tree_view->view, path,
942
 
                                         column, &column_area);
 
985
      gtk_tree_view_get_cell_area (tree_view->view, path,
 
986
                                   column, &column_area);
943
987
 
944
988
      gtk_tree_view_column_cell_set_cell_data (column,
945
989
                                               tree_view->model,
946
990
                                               &iter,
947
991
                                               FALSE, FALSE);
948
992
 
 
993
      if (bevent->button == 1                                     &&
 
994
          gtk_tree_model_iter_has_child (tree_view->model, &iter) &&
 
995
          column == gtk_tree_view_get_expander_column (tree_view->view))
 
996
        {
 
997
          GList *cells;
 
998
 
 
999
          cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
 
1000
 
 
1001
          if (! gimp_container_tree_view_find_click_cell (widget,
 
1002
                                                          cells,
 
1003
                                                          column, &column_area,
 
1004
                                                          bevent->x, bevent->y))
 
1005
            {
 
1006
              /*  we didn't click on any cell, but we clicked on empty
 
1007
               *  space in the expander column of a row that has
 
1008
               *  children; let GtkTreeView process the button press
 
1009
               *  to maybe handle a click on an expander.
 
1010
               */
 
1011
              g_list_free (cells);
 
1012
              gtk_tree_path_free (path);
 
1013
              g_object_unref (renderer);
 
1014
 
 
1015
              return FALSE;
 
1016
            }
 
1017
 
 
1018
          g_list_free (cells);
 
1019
        }
 
1020
 
949
1021
      toggled_cell = (GimpCellRendererToggle *)
950
1022
        gimp_container_tree_view_find_click_cell (widget,
951
 
                                                  tree_view->toggle_cells,
 
1023
                                                  tree_view->priv->toggle_cells,
952
1024
                                                  column, &column_area,
953
1025
                                                  bevent->x, bevent->y);
954
1026
 
955
1027
      if (! toggled_cell)
956
1028
        clicked_cell = (GimpCellRendererViewable *)
957
1029
          gimp_container_tree_view_find_click_cell (widget,
958
 
                                                    tree_view->renderer_cells,
 
1030
                                                    tree_view->priv->renderer_cells,
959
1031
                                                    column, &column_area,
960
1032
                                                    bevent->x, bevent->y);
961
1033
 
962
1034
      if (! toggled_cell && ! clicked_cell)
963
1035
        edit_cell =
964
1036
          gimp_container_tree_view_find_click_cell (widget,
965
 
                                                    tree_view->editable_cells,
 
1037
                                                    tree_view->priv->editable_cells,
966
1038
                                                    column, &column_area,
967
1039
                                                    bevent->x, bevent->y);
968
1040
 
969
1041
      g_object_ref (tree_view);
970
1042
 
971
 
      switch (bevent->button)
972
 
        {
973
 
        case 1:
 
1043
      if (gdk_event_triggers_context_menu ((GdkEvent *) bevent))
 
1044
        {
 
1045
          if (gimp_container_view_item_selected (container_view,
 
1046
                                                 renderer->viewable))
 
1047
            {
 
1048
              if (gimp_container_view_get_container (container_view))
 
1049
                gimp_container_view_item_context (container_view,
 
1050
                                                  renderer->viewable);
 
1051
            }
 
1052
        }
 
1053
      else if (bevent->button == 1)
 
1054
        {
974
1055
          if (bevent->type == GDK_BUTTON_PRESS)
975
1056
            {
976
 
              gboolean success = TRUE;
977
 
 
978
1057
              /*  don't select item if a toggle was clicked */
979
1058
              if (! toggled_cell)
980
 
                success = gimp_container_view_item_selected (container_view,
981
 
                                                             renderer->viewable);
 
1059
                {
 
1060
                  gchar *path_str = gtk_tree_path_to_string (path);
 
1061
 
 
1062
                  handled = FALSE;
 
1063
 
 
1064
                  if (clicked_cell)
 
1065
                    handled =
 
1066
                      gimp_cell_renderer_viewable_pre_clicked (clicked_cell,
 
1067
                                                               path_str,
 
1068
                                                               bevent->state);
 
1069
 
 
1070
                  if (! handled)
 
1071
                    {
 
1072
                      if (multisel_mode)
 
1073
                        {
 
1074
                          /* let parent do the work */
 
1075
                        }
 
1076
                      else
 
1077
                        {
 
1078
                          handled =
 
1079
                            gimp_container_view_item_selected (container_view,
 
1080
                                                               renderer->viewable);
 
1081
                        }
 
1082
                    }
 
1083
 
 
1084
                  g_free (path_str);
 
1085
                }
982
1086
 
983
1087
              /*  a callback invoked by selecting the item may have
984
1088
               *  destroyed us, so check if the container is still there
1025
1129
                {
1026
1130
                  if (edit_cell)
1027
1131
                    {
1028
 
                      if (edit_cell == tree_view->name_cell)
1029
 
                        {
1030
 
                          const gchar *real_name;
1031
 
 
1032
 
                          real_name =
1033
 
                            gimp_object_get_name (GIMP_OBJECT (renderer->viewable));
1034
 
 
1035
 
                          gtk_list_store_set (GTK_LIST_STORE (tree_view->model),
1036
 
                                              &iter,
1037
 
                                              tree_view->model_column_name,
1038
 
                                              real_name,
1039
 
                                              -1);
1040
 
                        }
1041
 
 
1042
1132
                      gtk_tree_view_set_cursor_on_cell (tree_view->view, path,
1043
1133
                                                        column, edit_cell, TRUE);
1044
1134
                    }
1045
 
                  else if (! toggled_cell) /* ignore double click on toggles */
 
1135
                  else if (! toggled_cell &&
 
1136
                           ! (bevent->state & gimp_get_all_modifiers_mask ()))
1046
1137
                    {
 
1138
                      /* Only activate if we're not in a toggled cell
 
1139
                       * and no modifier keys are pressed
 
1140
                       */
1047
1141
                      gimp_container_view_item_activated (container_view,
1048
1142
                                                          renderer->viewable);
1049
1143
                    }
1050
1144
                }
1051
1145
            }
1052
 
          break;
1053
 
 
1054
 
        case 2:
 
1146
        }
 
1147
      else if (bevent->button == 2)
 
1148
        {
1055
1149
          if (bevent->type == GDK_BUTTON_PRESS)
1056
1150
            {
1057
1151
              if (clicked_cell)
1065
1159
                  g_free (path_str);
1066
1160
                }
1067
1161
            }
1068
 
          break;
1069
 
 
1070
 
        case 3:
1071
 
          if (gimp_container_view_item_selected (container_view,
1072
 
                                                 renderer->viewable))
1073
 
            {
1074
 
              if (gimp_container_view_get_container (container_view))
1075
 
                gimp_container_view_item_context (container_view,
1076
 
                                                  renderer->viewable);
1077
 
            }
1078
 
          break;
1079
 
 
1080
 
        default:
1081
 
          break;
1082
1162
        }
1083
1163
 
1084
1164
      g_object_unref (tree_view);
1085
1165
 
1086
1166
      gtk_tree_path_free (path);
1087
1167
      g_object_unref (renderer);
 
1168
 
 
1169
      return multisel_mode ? handled : TRUE;
1088
1170
    }
1089
1171
  else
1090
1172
    {
1091
 
      switch (bevent->button)
 
1173
      if (gdk_event_triggers_context_menu ((GdkEvent *) bevent))
1092
1174
        {
1093
 
        case 3:
1094
1175
          gimp_editor_popup_menu (GIMP_EDITOR (tree_view), NULL, NULL);
1095
 
          break;
1096
 
 
1097
 
        default:
1098
 
          break;
1099
1176
        }
 
1177
 
 
1178
      return TRUE;
1100
1179
    }
1101
 
 
1102
 
  return TRUE;
1103
1180
}
1104
1181
 
1105
1182
static gboolean
1121
1198
    return FALSE;
1122
1199
 
1123
1200
  gtk_tree_model_get (tree_view->model, &iter,
1124
 
                      COLUMN_RENDERER, &renderer,
 
1201
                      GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
1125
1202
                      -1);
1126
1203
 
1127
1204
  if (renderer)
1150
1227
  return show_tip;
1151
1228
}
1152
1229
 
1153
 
static void
1154
 
gimp_container_tree_view_renderer_update (GimpViewRenderer      *renderer,
1155
 
                                          GimpContainerTreeView *tree_view)
1156
 
{
1157
 
  GimpContainerView *view = GIMP_CONTAINER_VIEW (tree_view);
1158
 
  GtkTreeIter       *iter;
1159
 
 
1160
 
  iter = gimp_container_view_lookup (view, renderer->viewable);
1161
 
 
1162
 
  if (iter)
1163
 
    {
1164
 
      GtkTreePath *path;
1165
 
 
1166
 
      path = gtk_tree_model_get_path (tree_view->model, iter);
1167
 
      gtk_tree_model_row_changed (tree_view->model, path, iter);
1168
 
      gtk_tree_path_free (path);
1169
 
    }
1170
 
}
1171
 
 
1172
1230
static GimpViewable *
1173
1231
gimp_container_tree_view_drag_viewable (GtkWidget    *widget,
1174
1232
                                        GimpContext **context,
1179
1237
  if (context)
1180
1238
    *context = gimp_container_view_get_context (GIMP_CONTAINER_VIEW (data));
1181
1239
 
1182
 
  if (tree_view->dnd_renderer)
1183
 
    return tree_view->dnd_renderer->viewable;
 
1240
  if (tree_view->priv->dnd_renderer)
 
1241
    return tree_view->priv->dnd_renderer->viewable;
1184
1242
 
1185
1243
  return NULL;
1186
1244
}
1190
1248
                                      gpointer   data)
1191
1249
{
1192
1250
  GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (data);
1193
 
  GimpViewRenderer      *renderer  = tree_view->dnd_renderer;
 
1251
  GimpViewRenderer      *renderer  = tree_view->priv->dnd_renderer;
1194
1252
  gint                   width;
1195
1253
  gint                   height;
1196
1254
 
1201
1259
 
1202
1260
  return NULL;
1203
1261
}
 
1262
 
 
1263
static gboolean
 
1264
gimp_container_tree_view_get_selected_single (GimpContainerTreeView  *tree_view,
 
1265
                                               GtkTreeIter            *iter)
 
1266
{
 
1267
  GtkTreeSelection         *selection;
 
1268
 
 
1269
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view->view));
 
1270
 
 
1271
  if (gtk_tree_selection_count_selected_rows (selection) == 1)
 
1272
    {
 
1273
      GList    *selected_rows;
 
1274
 
 
1275
      selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL);
 
1276
 
 
1277
      gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_view->model), iter,
 
1278
                               (GtkTreePath *) selected_rows->data);
 
1279
 
 
1280
      g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free);
 
1281
 
 
1282
      return TRUE;
 
1283
    }
 
1284
  else
 
1285
    {
 
1286
      return FALSE;
 
1287
    }
 
1288
}
 
1289
 
 
1290
static gint
 
1291
gimp_container_tree_view_get_selected (GimpContainerView    *view,
 
1292
                                       GList               **items)
 
1293
{
 
1294
  GimpContainerTreeView *tree_view = GIMP_CONTAINER_TREE_VIEW (view);
 
1295
  GtkTreeSelection      *selection;
 
1296
  gint                   selected_count;
 
1297
  GList                 *selected_rows;
 
1298
  GList                 *current_row;
 
1299
  GtkTreeIter            iter;
 
1300
  GimpViewRenderer      *renderer;
 
1301
 
 
1302
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view->view));
 
1303
  selected_count = gtk_tree_selection_count_selected_rows (selection);
 
1304
 
 
1305
  if (items == NULL)
 
1306
    {
 
1307
      /* just provide selected count */
 
1308
      return selected_count;
 
1309
    }
 
1310
 
 
1311
  selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL);
 
1312
 
 
1313
  *items = NULL;
 
1314
  for (current_row = selected_rows;
 
1315
       current_row;
 
1316
       current_row = g_list_next (current_row))
 
1317
    {
 
1318
      gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_view->model), &iter,
 
1319
                               (GtkTreePath *) current_row->data);
 
1320
 
 
1321
      gtk_tree_model_get (tree_view->model, &iter,
 
1322
                          GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
 
1323
                          -1);
 
1324
 
 
1325
      if (renderer->viewable)
 
1326
        *items = g_list_prepend (*items, renderer->viewable);
 
1327
 
 
1328
      g_object_unref (renderer);
 
1329
    }
 
1330
 
 
1331
  g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free);
 
1332
 
 
1333
  *items = g_list_reverse (*items);
 
1334
 
 
1335
  return selected_count;
 
1336
}
 
1337
 
 
1338
static void
 
1339
gimp_container_tree_view_row_expanded (GtkTreeView           *tree_view,
 
1340
                                       GtkTreeIter           *iter,
 
1341
                                       GtkTreePath           *path,
 
1342
                                       GimpContainerTreeView *view)
 
1343
{
 
1344
  GimpViewRenderer *renderer;
 
1345
 
 
1346
  gtk_tree_model_get (view->model, iter,
 
1347
                      GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
 
1348
                      -1);
 
1349
  if (renderer)
 
1350
    {
 
1351
      gboolean expanded = gtk_tree_view_row_expanded (tree_view, path);
 
1352
 
 
1353
      gimp_viewable_set_expanded (renderer->viewable,
 
1354
                                  expanded);
 
1355
      if (expanded)
 
1356
        {
 
1357
          g_signal_handlers_block_by_func (tree_view,
 
1358
                                           gimp_container_tree_view_row_expanded,
 
1359
                                           view);
 
1360
 
 
1361
          gimp_container_tree_view_expand_rows (view->model, tree_view, iter);
 
1362
 
 
1363
          g_signal_handlers_unblock_by_func (tree_view,
 
1364
                                             gimp_container_tree_view_row_expanded,
 
1365
                                             view);
 
1366
        }
 
1367
 
 
1368
      g_object_unref (renderer);
 
1369
    }
 
1370
}
 
1371
 
 
1372
static void
 
1373
gimp_container_tree_view_expand_rows (GtkTreeModel *model,
 
1374
                                      GtkTreeView  *view,
 
1375
                                      GtkTreeIter  *parent)
 
1376
{
 
1377
  GtkTreeIter iter;
 
1378
 
 
1379
  if (gtk_tree_model_iter_children (model, &iter, parent))
 
1380
    do
 
1381
      if (gtk_tree_model_iter_has_child (model, &iter))
 
1382
        {
 
1383
          GimpViewRenderer *renderer;
 
1384
 
 
1385
          gtk_tree_model_get (model, &iter,
 
1386
                              GIMP_CONTAINER_TREE_STORE_COLUMN_RENDERER, &renderer,
 
1387
                              -1);
 
1388
          if (renderer)
 
1389
            {
 
1390
              GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
 
1391
 
 
1392
              if (gimp_viewable_get_expanded (renderer->viewable))
 
1393
                gtk_tree_view_expand_row (view, path, FALSE);
 
1394
              else
 
1395
                gtk_tree_view_collapse_row (view, path);
 
1396
 
 
1397
              gtk_tree_path_free (path);
 
1398
              g_object_unref (renderer);
 
1399
            }
 
1400
 
 
1401
          gimp_container_tree_view_expand_rows (model, view, &iter);
 
1402
        }
 
1403
    while (gtk_tree_model_iter_next (model, &iter));
 
1404
}