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