Workspace: Move engines to workspace and Properties Editor cleanup
[blender.git] / source / blender / editors / screen / screen_context.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2008 Blender Foundation.
19  * All rights reserved.
20  *
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 /** \file blender/editors/screen/screen_context.c
26  *  \ingroup edscr
27  */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "DNA_object_types.h"
34 #include "DNA_armature_types.h"
35 #include "DNA_gpencil_types.h"
36 #include "DNA_sequence_types.h"
37 #include "DNA_scene_types.h"
38 #include "DNA_screen_types.h"
39 #include "DNA_space_types.h"
40 #include "DNA_windowmanager_types.h"
41 #include "DNA_workspace_types.h"
42
43 #include "BLI_utildefines.h"
44
45
46 #include "BKE_context.h"
47 #include "BKE_object.h"
48 #include "BKE_action.h"
49 #include "BKE_armature.h"
50 #include "BKE_gpencil.h"
51 #include "BKE_layer.h"
52 #include "BKE_screen.h"
53 #include "BKE_sequencer.h"
54 #include "BKE_workspace.h"
55
56 #include "RNA_access.h"
57
58 #include "ED_armature.h"
59 #include "ED_gpencil.h"
60 #include "ED_anim_api.h"
61
62 #include "WM_api.h"
63 #include "UI_interface.h"
64
65 #include "screen_intern.h"
66
67 const char *screen_context_dir[] = {
68         "scene", "render_layer", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases",
69         "selected_objects", "selected_bases",
70         "editable_objects", "editable_bases",
71         "selected_editable_objects", "selected_editable_bases",
72         "visible_bones", "editable_bones", "selected_bones", "selected_editable_bones",
73         "visible_pose_bones", "selected_pose_bones", "active_bone", "active_pose_bone",
74         "active_base", "active_object", "object", "edit_object",
75         "sculpt_object", "vertex_paint_object", "weight_paint_object",
76         "image_paint_object", "particle_edit_object",
77         "sequences", "selected_sequences", "selected_editable_sequences", /* sequencer */
78         "gpencil_data", "gpencil_data_owner", /* grease pencil data */
79         "visible_gpencil_layers", "editable_gpencil_layers", "editable_gpencil_strokes",
80         "active_gpencil_layer", "active_gpencil_frame", "active_gpencil_palette", 
81         "active_gpencil_palettecolor", "active_gpencil_brush",
82         "active_operator", "selected_editable_fcurves",
83         NULL};
84
85 int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result)
86 {
87         wmWindow *win = CTX_wm_window(C);
88         bScreen *sc = CTX_wm_screen(C);
89         ScrArea *sa = CTX_wm_area(C);
90         Scene *scene = WM_window_get_active_scene(win);
91         WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
92         SceneLayer *sl = BKE_scene_layer_from_workspace_get(scene, workspace);
93         Object *obedit = scene->obedit;
94         Object *obact = sl->basact ? sl->basact->object : NULL;
95
96         if (CTX_data_dir(member)) {
97                 CTX_data_dir_set(result, screen_context_dir);
98                 return 1;
99         }
100         else if (CTX_data_equals(member, "scene")) {
101                 CTX_data_id_pointer_set(result, &scene->id);
102                 return 1;
103         }
104         else if (CTX_data_equals(member, "visible_objects")) {
105                 FOREACH_VISIBLE_OBJECT(sl, ob)
106                 {
107                         CTX_data_id_list_add(result, &ob->id);
108                 }
109                 FOREACH_VISIBLE_BASE_END
110                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
111                 return 1;
112         }
113         else if (CTX_data_equals(member, "selectable_objects")) {
114                 for (Base *base = sl->object_bases.first; base; base = base->next) {
115                         if (((base->flag & BASE_VISIBLED) != 0) && ((base->flag & BASE_SELECTABLED) != 0)) {
116                                 CTX_data_id_list_add(result, &base->object->id);
117                         }
118                 }
119                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
120                 return 1;
121         }
122         else if (CTX_data_equals(member, "selected_objects")) {
123                 FOREACH_SELECTED_OBJECT(sl, ob)
124                 {
125                         CTX_data_id_list_add(result, &ob->id);
126                 }
127                 FOREACH_SELECTED_OBJECT_END
128                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
129                 return 1;
130         }
131         else if (CTX_data_equals(member, "selected_editable_objects")) {
132                 FOREACH_SELECTED_OBJECT(sl, ob)
133                 {
134                         if (0 == BKE_object_is_libdata(ob)) {
135                                 CTX_data_id_list_add(result, &ob->id);
136                         }
137                 }
138                 FOREACH_SELECTED_OBJECT_END
139                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
140                 return 1;
141         }
142         else if (CTX_data_equals(member, "editable_objects")) {
143                 /* Visible + Editable, but not necessarily selected */
144                 FOREACH_VISIBLE_OBJECT(sl, ob)
145                 {
146                         if (0 == BKE_object_is_libdata(ob)) {
147                                 CTX_data_id_list_add(result, &ob->id);
148                         }
149                 }
150                 FOREACH_VISIBLE_OBJECT_END
151                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
152                 return 1;
153         }
154         else if ( CTX_data_equals(member, "visible_bases")) {
155                 FOREACH_VISIBLE_BASE(sl, base)
156                 {
157                         CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
158                 }
159                 FOREACH_VISIBLE_BASE_END
160                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
161                 return 1;
162         }
163         else if (CTX_data_equals(member, "selectable_bases")) {
164                 for (Base *base = sl->object_bases.first; base; base = base->next) {
165                         if ((base->flag & BASE_SELECTABLED) != 0) {
166                                 CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
167                         }
168                 }
169                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
170                 return 1;
171         }
172         else if (CTX_data_equals(member, "selected_bases")) {
173                 for (Base *base = sl->object_bases.first; base; base = base->next) {
174                         if ((base->flag & BASE_SELECTED) != 0) {
175                                 CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
176                         }
177                 }
178                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
179                 return 1;
180         }
181         else if (CTX_data_equals(member, "selected_editable_bases")) {
182                 for (Base *base = sl->object_bases.first; base; base = base->next) {
183                         if ((base->flag & BASE_SELECTED) != 0) {
184                                 if (0 == BKE_object_is_libdata(base->object)) {
185                                         CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
186                                 }
187                         }
188                 }
189                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
190                 return 1;
191         }
192         else if (CTX_data_equals(member, "editable_bases")) {
193                 /* Visible + Editable, but not necessarily selected */
194                 for (Base *base = sl->object_bases.first; base; base = base->next) {
195                         if ((base->flag & BASE_VISIBLED) != 0) {
196                                 if (0 == BKE_object_is_libdata(base->object)) {
197                                         CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
198                                 }
199                         }
200                 }
201                 CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
202                 return 1;
203         }
204         else if (CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) {
205                 bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
206                 EditBone *ebone, *flipbone = NULL;
207                 const bool editable_bones = CTX_data_equals(member, "editable_bones");
208                 
209                 if (arm && arm->edbo) {
210                         /* Attention: X-Axis Mirroring is also handled here... */
211                         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
212                                 /* first and foremost, bone must be visible and selected */
213                                 if (EBONE_VISIBLE(arm, ebone)) {
214                                         /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
215                                          * so that most users of this data don't need to explicitly check for it themselves.
216                                          * 
217                                          * We need to make sure that these mirrored copies are not selected, otherwise some
218                                          * bones will be operated on twice.
219                                          */
220                                         if (arm->flag & ARM_MIRROR_EDIT)
221                                                 flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
222                                         
223                                         /* if we're filtering for editable too, use the check for that instead, as it has selection check too */
224                                         if (editable_bones) {
225                                                 /* only selected + editable */
226                                                 if (EBONE_EDITABLE(ebone)) {
227                                                         CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
228                                                 
229                                                         if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
230                                                                 CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
231                                                 }
232                                         }
233                                         else {
234                                                 /* only include bones if visible */
235                                                 CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
236                                                 
237                                                 if ((flipbone) && EBONE_VISIBLE(arm, flipbone) == 0)
238                                                         CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
239                                         }
240                                 }
241                         }
242                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
243                         return 1;
244                 }
245         }
246         else if (CTX_data_equals(member, "selected_bones") || CTX_data_equals(member, "selected_editable_bones")) {
247                 bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
248                 EditBone *ebone, *flipbone = NULL;
249                 const bool selected_editable_bones = CTX_data_equals(member, "selected_editable_bones");
250                 
251                 if (arm && arm->edbo) {
252                         /* Attention: X-Axis Mirroring is also handled here... */
253                         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
254                                 /* first and foremost, bone must be visible and selected */
255                                 if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) {
256                                         /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
257                                          * so that most users of this data don't need to explicitly check for it themselves.
258                                          * 
259                                          * We need to make sure that these mirrored copies are not selected, otherwise some
260                                          * bones will be operated on twice.
261                                          */
262                                         if (arm->flag & ARM_MIRROR_EDIT)
263                                                 flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
264                                         
265                                         /* if we're filtering for editable too, use the check for that instead, as it has selection check too */
266                                         if (selected_editable_bones) {
267                                                 /* only selected + editable */
268                                                 if (EBONE_EDITABLE(ebone)) {
269                                                         CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
270                                                 
271                                                         if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
272                                                                 CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
273                                                 }
274                                         }
275                                         else {
276                                                 /* only include bones if selected */
277                                                 CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
278                                                 
279                                                 if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
280                                                         CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
281                                         }
282                                 }
283                         }
284                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
285                         return 1;
286                 }
287         }
288         else if (CTX_data_equals(member, "visible_pose_bones")) {
289                 Object *obpose = BKE_object_pose_armature_get(obact);
290                 bArmature *arm = (obpose) ? obpose->data : NULL;
291                 bPoseChannel *pchan;
292                 
293                 if (obpose && obpose->pose && arm) {
294                         for (pchan = obpose->pose->chanbase.first; pchan; pchan = pchan->next) {
295                                 /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
296                                 if (PBONE_VISIBLE(arm, pchan->bone)) {
297                                         CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan);
298                                 }
299                         }
300                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
301                         return 1;
302                 }
303         }
304         else if (CTX_data_equals(member, "selected_pose_bones")) {
305                 Object *obpose = BKE_object_pose_armature_get(obact);
306                 bArmature *arm = (obpose) ? obpose->data : NULL;
307                 bPoseChannel *pchan;
308                 
309                 if (obpose && obpose->pose && arm) {
310                         for (pchan = obpose->pose->chanbase.first; pchan; pchan = pchan->next) {
311                                 /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
312                                 if (PBONE_VISIBLE(arm, pchan->bone)) {
313                                         if (pchan->bone->flag & BONE_SELECTED)
314                                                 CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan);
315                                 }
316                         }
317                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
318                         return 1;
319                 }
320         }
321         else if (CTX_data_equals(member, "active_bone")) {
322                 if (obact && obact->type == OB_ARMATURE) {
323                         bArmature *arm = obact->data;
324                         if (arm->edbo) {
325                                 if (arm->act_edbone) {
326                                         CTX_data_pointer_set(result, &arm->id, &RNA_EditBone, arm->act_edbone);
327                                         return 1;
328                                 }
329                         }
330                         else {
331                                 if (arm->act_bone) {
332                                         CTX_data_pointer_set(result, &arm->id, &RNA_Bone, arm->act_bone);
333                                         return 1;
334                                 }
335                         }
336                 }
337         }
338         else if (CTX_data_equals(member, "active_pose_bone")) {
339                 bPoseChannel *pchan;
340                 Object *obpose = BKE_object_pose_armature_get(obact);
341                 
342                 pchan = BKE_pose_channel_active(obpose);
343                 if (pchan) {
344                         CTX_data_pointer_set(result, &obpose->id, &RNA_PoseBone, pchan);
345                         return 1;
346                 }
347         }
348         else if (CTX_data_equals(member, "active_base")) {
349                 if (sl->basact)
350                         CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, sl->basact);
351
352                 return 1;
353         }
354         else if (CTX_data_equals(member, "active_object")) {
355                 if (obact)
356                         CTX_data_id_pointer_set(result, &obact->id);
357
358                 return 1;
359         }
360         else if (CTX_data_equals(member, "object")) {
361                 if (obact)
362                         CTX_data_id_pointer_set(result, &obact->id);
363
364                 return 1;
365         }
366         else if (CTX_data_equals(member, "edit_object")) {
367                 /* convenience for now, 1 object per scene in editmode */
368                 if (obedit)
369                         CTX_data_id_pointer_set(result, &obedit->id);
370                 
371                 return 1;
372         }
373         else if (CTX_data_equals(member, "sculpt_object")) {
374                 if (obact && (obact->mode & OB_MODE_SCULPT))
375                         CTX_data_id_pointer_set(result, &obact->id);
376
377                 return 1;
378         }
379         else if (CTX_data_equals(member, "vertex_paint_object")) {
380                 if (obact && (obact->mode & OB_MODE_VERTEX_PAINT))
381                         CTX_data_id_pointer_set(result, &obact->id);
382
383                 return 1;
384         }
385         else if (CTX_data_equals(member, "weight_paint_object")) {
386                 if (obact && (obact->mode & OB_MODE_WEIGHT_PAINT))
387                         CTX_data_id_pointer_set(result, &obact->id);
388
389                 return 1;
390         }
391         else if (CTX_data_equals(member, "image_paint_object")) {
392                 if (obact && (obact->mode & OB_MODE_TEXTURE_PAINT))
393                         CTX_data_id_pointer_set(result, &obact->id);
394
395                 return 1;
396         }
397         else if (CTX_data_equals(member, "particle_edit_object")) {
398                 if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT))
399                         CTX_data_id_pointer_set(result, &obact->id);
400
401                 return 1;
402         }
403         else if (CTX_data_equals(member, "sequences")) {
404                 Editing *ed = BKE_sequencer_editing_get(scene, false);
405                 if (ed) {
406                         Sequence *seq;
407                         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
408                                 CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
409                         }
410                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
411                         return 1;
412                 }
413         }
414         else if (CTX_data_equals(member, "selected_sequences")) {
415                 Editing *ed = BKE_sequencer_editing_get(scene, false);
416                 if (ed) {
417                         Sequence *seq;
418                         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
419                                 if (seq->flag & SELECT) {
420                                         CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
421                                 }
422                         }
423                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
424                         return 1;
425                 }
426         }
427         else if (CTX_data_equals(member, "selected_editable_sequences")) {
428                 Editing *ed = BKE_sequencer_editing_get(scene, false);
429                 if (ed) {
430                         Sequence *seq;
431                         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
432                                 if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) {
433                                         CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
434                                 }
435                         }
436                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
437                         return 1;
438                 }
439         }
440         else if (CTX_data_equals(member, "gpencil_data")) {
441                 /* FIXME: for some reason, CTX_data_active_object(C) returns NULL when called from these situations
442                  * (as outlined above - see Campbell's #ifdefs). That causes the get_active function to fail when 
443                  * called from context. For that reason, we end up using an alternative where we pass everything in!
444                  */
445                 bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
446                 
447                 if (gpd) {
448                         CTX_data_id_pointer_set(result, &gpd->id);
449                         return 1;
450                 }
451         }
452         else if (CTX_data_equals(member, "gpencil_data_owner")) {
453                 /* pointer to which data/datablock owns the reference to the Grease Pencil data being used (as gpencil_data)
454                  * XXX: see comment for gpencil_data case... 
455                  */
456                 bGPdata **gpd_ptr = NULL;
457                 PointerRNA ptr;
458                 
459                 /* get pointer to Grease Pencil Data */
460                 gpd_ptr = ED_gpencil_data_get_pointers_direct((ID *)sc, scene, sa, obact, &ptr);
461                 
462                 if (gpd_ptr) {
463                         CTX_data_pointer_set(result, ptr.id.data, ptr.type, ptr.data);
464                         return 1;
465                 }
466         }
467         else if (CTX_data_equals(member, "active_gpencil_layer")) {
468                 /* XXX: see comment for gpencil_data case... */
469                 bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
470                 
471                 if (gpd) {
472                         bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
473                         
474                         if (gpl) {
475                                 CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl);
476                                 return 1;
477                         }
478                 }
479         }
480         else if (CTX_data_equals(member, "active_gpencil_palette")) {
481                 /* XXX: see comment for gpencil_data case... */
482                 bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
483
484                 if (gpd) {
485                         bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
486
487                         if (palette) {
488                                 CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilPalette, palette);
489                                 return 1;
490                         }
491                 }
492         }
493         else if (CTX_data_equals(member, "active_gpencil_palettecolor")) {
494                 /* XXX: see comment for gpencil_data case... */
495                 bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
496
497                 if (gpd) {
498                         bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
499
500                         if (palette) {
501                                 bGPDpalettecolor *palcolor = BKE_gpencil_palettecolor_getactive(palette);
502                                 if (palcolor) {
503                                         CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilPaletteColor, palcolor);
504                                         return 1;
505                                 }
506                         }
507                 }
508         }
509         else if (CTX_data_equals(member, "active_gpencil_brush")) {
510                 /* XXX: see comment for gpencil_data case... */
511                 bGPDbrush *brush = BKE_gpencil_brush_getactive(scene->toolsettings);
512
513                 if (brush) {
514                         CTX_data_pointer_set(result, &scene->id, &RNA_GPencilBrush, brush);
515                         return 1;
516                 }
517         }
518         else if (CTX_data_equals(member, "active_gpencil_frame")) {
519                 /* XXX: see comment for gpencil_data case... */
520                 bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
521                 
522                 if (gpd) {
523                         bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
524                         
525                         if (gpl) {
526                                 CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl->actframe);
527                                 return 1;
528                         }
529                 }
530         }
531         else if (CTX_data_equals(member, "visible_gpencil_layers")) {
532                 /* XXX: see comment for gpencil_data case... */
533                 bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
534                 
535                 if (gpd) {
536                         bGPDlayer *gpl;
537                         
538                         for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
539                                 if ((gpl->flag & GP_LAYER_HIDE) == 0) {
540                                         CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl);
541                                 }
542                         }
543                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
544                         return 1;
545                 }
546         }
547         else if (CTX_data_equals(member, "editable_gpencil_layers")) {
548                 /* XXX: see comment for gpencil_data case... */
549                 bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
550                 
551                 if (gpd) {
552                         bGPDlayer *gpl;
553                         
554                         for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
555                                 if (gpencil_layer_is_editable(gpl)) {
556                                         CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl);
557                                 }
558                         }
559                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
560                         return 1;
561                 }
562         }
563         else if (CTX_data_equals(member, "editable_gpencil_strokes")) {
564                 /* XXX: see comment for gpencil_data case... */
565                 bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
566                 
567                 if (gpd) {
568                         bGPDlayer *gpl;
569                         
570                         for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
571                                 if (gpencil_layer_is_editable(gpl) && (gpl->actframe)) {
572                                         bGPDframe *gpf = gpl->actframe;
573                                         bGPDstroke *gps;
574                                         
575                                         for (gps = gpf->strokes.first; gps; gps = gps->next) {
576                                                 if (ED_gpencil_stroke_can_use_direct(sa, gps)) {
577                                                         /* check if the color is editable */
578                                                         if (ED_gpencil_stroke_color_use(gpl, gps) == false) {
579                                                                 continue;
580                                                         }
581
582                                                         CTX_data_list_add(result, &gpd->id, &RNA_GPencilStroke, gps);
583                                                 }
584                                         }
585                                 }
586                         }
587                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
588                         return 1;
589                 }
590         }
591         else if (CTX_data_equals(member, "active_operator")) {
592                 wmOperator *op = NULL;
593
594                 SpaceFile *sfile = CTX_wm_space_file(C);
595                 if (sfile) {
596                         op = sfile->op;
597                 }
598                 else if ((op = UI_context_active_operator_get(C))) {
599                         /* do nothing */
600                 }
601                 else {
602                         /* note, this checks poll, could be a problem, but this also
603                          * happens for the toolbar */
604                         op = WM_operator_last_redo(C);
605                 }
606                 /* TODO, get the operator from popup's */
607
608                 if (op && op->ptr) {
609                         CTX_data_pointer_set(result, NULL, &RNA_Operator, op);
610                         return 1;
611                 }
612         }
613         else if (CTX_data_equals(member, "selected_editable_fcurves")) {
614                 bAnimContext ac;
615
616                 if (ANIM_animdata_get_context(C, &ac) && ELEM(ac.spacetype, SPACE_ACTION, SPACE_IPO)) {
617                         bAnimListElem *ale;
618                         ListBase anim_data = {NULL, NULL};
619
620                         int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS | ANIMFILTER_SEL) |
621                                      (ac.spacetype == SPACE_IPO ? ANIMFILTER_CURVE_VISIBLE : ANIMFILTER_LIST_VISIBLE);
622
623                         ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
624
625                         for (ale = anim_data.first; ale; ale = ale->next) {
626                                 if (ale->type == ANIMTYPE_FCURVE)
627                                         CTX_data_list_add(result, ale->id, &RNA_FCurve, ale->data);
628                         }
629
630                         ANIM_animdata_freelist(&anim_data);
631
632                         CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
633                         return 1;
634                 }
635         }
636         else {
637                 return 0; /* not found */
638         }
639
640         return -1; /* found but not available */
641 }
642