modify the python context access so invalid names will raise an exception rather...
[blender-staging.git] / source / blender / blenkernel / intern / context.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): Blender Foundation (2008).
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #include "MEM_guardedalloc.h"
29
30 #include "DNA_ID.h"
31 #include "DNA_listBase.h"
32 #include "DNA_scene_types.h"
33 #include "DNA_screen_types.h"
34 #include "DNA_space_types.h"
35 #include "DNA_view3d_types.h"
36 #include "DNA_windowmanager_types.h"
37 #include "DNA_object_types.h"
38
39 #include "RNA_access.h"
40
41 #include "BLI_listbase.h"
42 #include "BLI_string.h"
43
44 #include "BKE_context.h"
45 #include "BKE_main.h"
46 #include "BKE_screen.h"
47 #include "BKE_global.h"
48
49 #include <string.h>
50
51 /* struct */
52
53 struct bContext {
54         int thread;
55
56         /* windowmanager context */
57         struct {
58                 struct wmWindowManager *manager;
59                 struct wmWindow *window;
60                 struct bScreen *screen;
61                 struct ScrArea *area;
62                 struct ARegion *region;
63                 struct ARegion *menu;
64                 struct bContextStore *store;
65         } wm;
66         
67         /* data context */
68         struct {
69                 struct Main *main;
70                 struct Scene *scene;
71
72                 int recursion;
73                 int py_init; /* true if python is initialized */
74                 void *py_context;
75         } data;
76         
77         /* data evaluation */
78         struct {
79                 int render;
80         } eval;
81 };
82
83 /* context */
84
85 bContext *CTX_create()
86 {
87         bContext *C;
88         
89         C= MEM_callocN(sizeof(bContext), "bContext");
90
91         return C;
92 }
93
94 bContext *CTX_copy(const bContext *C)
95 {
96         bContext *newC= MEM_dupallocN((void*)C);
97
98         return newC;
99 }
100
101 void CTX_free(bContext *C)
102 {
103         MEM_freeN(C);
104 }
105
106 /* store */
107
108 bContextStore *CTX_store_add(ListBase *contexts, char *name, PointerRNA *ptr)
109 {
110         bContextStoreEntry *entry;
111         bContextStore *ctx, *lastctx;
112
113         /* ensure we have a context to put the entry in, if it was already used
114          * we have to copy the context to ensure */
115         ctx= contexts->last;
116
117         if(!ctx || ctx->used) {
118                 if(ctx) {
119                         lastctx= ctx;
120                         ctx= MEM_dupallocN(lastctx);
121                         BLI_duplicatelist(&ctx->entries, &lastctx->entries);
122                 }
123                 else
124                         ctx= MEM_callocN(sizeof(bContextStore), "bContextStore");
125
126                 BLI_addtail(contexts, ctx);
127         }
128
129         entry= MEM_callocN(sizeof(bContextStoreEntry), "bContextStoreEntry");
130         BLI_strncpy(entry->name, name, sizeof(entry->name));
131         entry->ptr= *ptr;
132
133         BLI_addtail(&ctx->entries, entry);
134
135         return ctx;
136 }
137
138 void CTX_store_set(bContext *C, bContextStore *store)
139 {
140         C->wm.store= store;
141 }
142
143 bContextStore *CTX_store_copy(bContextStore *store)
144 {
145         bContextStore *ctx;
146
147         ctx= MEM_dupallocN(store);
148         BLI_duplicatelist(&ctx->entries, &store->entries);
149
150         return ctx;
151 }
152
153 void CTX_store_free(bContextStore *store)
154 {
155         BLI_freelistN(&store->entries);
156         MEM_freeN(store);
157 }
158
159 void CTX_store_free_list(ListBase *contexts)
160 {
161         bContextStore *ctx;
162
163         while((ctx= contexts->first)) {
164                 BLI_remlink(contexts, ctx);
165                 CTX_store_free(ctx);
166         }
167 }
168
169 /* is python initialied? */
170 int CTX_py_init_get(bContext *C)
171 {
172         return C->data.py_init;
173 }
174 void CTX_py_init_set(bContext *C, int value)
175 {
176         C->data.py_init= value;
177 }
178
179 void *CTX_py_dict_get(bContext *C)
180 {
181         return C->data.py_context;
182 }
183 void CTX_py_dict_set(bContext *C, void *value)
184 {
185         C->data.py_context= value;
186 }
187
188 /* window manager context */
189
190 wmWindowManager *CTX_wm_manager(const bContext *C)
191 {
192         return C->wm.manager;
193 }
194
195 wmWindow *CTX_wm_window(const bContext *C)
196 {
197         return C->wm.window;
198 }
199
200 bScreen *CTX_wm_screen(const bContext *C)
201 {
202         return C->wm.screen;
203 }
204
205 ScrArea *CTX_wm_area(const bContext *C)
206 {
207         return C->wm.area;
208 }
209
210 SpaceLink *CTX_wm_space_data(const bContext *C)
211 {
212         return (C->wm.area)? C->wm.area->spacedata.first: NULL;
213 }
214
215 ARegion *CTX_wm_region(const bContext *C)
216 {
217         return C->wm.region;
218 }
219
220 void *CTX_wm_region_data(const bContext *C)
221 {
222         return (C->wm.region)? C->wm.region->regiondata: NULL;
223 }
224
225 struct ARegion *CTX_wm_menu(const bContext *C)
226 {
227         return C->wm.menu;
228 }
229
230 struct ReportList *CTX_wm_reports(const bContext *C)
231 {
232         if (C->wm.manager)
233                 return &(C->wm.manager->reports);
234
235         return NULL;
236 }
237
238 View3D *CTX_wm_view3d(const bContext *C)
239 {
240         if(C->wm.area && C->wm.area->spacetype==SPACE_VIEW3D)
241                 return C->wm.area->spacedata.first;
242         return NULL;
243 }
244
245 RegionView3D *CTX_wm_region_view3d(const bContext *C)
246 {
247         if(C->wm.area && C->wm.area->spacetype==SPACE_VIEW3D)
248                 if(C->wm.region)
249                         return C->wm.region->regiondata;
250         return NULL;
251 }
252
253 struct SpaceText *CTX_wm_space_text(const bContext *C)
254 {
255         if(C->wm.area && C->wm.area->spacetype==SPACE_TEXT)
256                 return C->wm.area->spacedata.first;
257         return NULL;
258 }
259
260 struct SpaceConsole *CTX_wm_space_console(const bContext *C)
261 {
262         if(C->wm.area && C->wm.area->spacetype==SPACE_CONSOLE)
263                 return C->wm.area->spacedata.first;
264         return NULL;
265 }
266
267 struct SpaceImage *CTX_wm_space_image(const bContext *C)
268 {
269         if(C->wm.area && C->wm.area->spacetype==SPACE_IMAGE)
270                 return C->wm.area->spacedata.first;
271         return NULL;
272 }
273
274 struct SpaceButs *CTX_wm_space_buts(const bContext *C)
275 {
276         if(C->wm.area && C->wm.area->spacetype==SPACE_BUTS)
277                 return C->wm.area->spacedata.first;
278         return NULL;
279 }
280
281 struct SpaceFile *CTX_wm_space_file(const bContext *C)
282 {
283         if(C->wm.area && C->wm.area->spacetype==SPACE_FILE)
284                 return C->wm.area->spacedata.first;
285         return NULL;
286 }
287
288 struct SpaceSeq *CTX_wm_space_seq(const bContext *C)
289 {
290         if(C->wm.area && C->wm.area->spacetype==SPACE_SEQ)
291                 return C->wm.area->spacedata.first;
292         return NULL;
293 }
294
295 struct SpaceOops *CTX_wm_space_outliner(const bContext *C)
296 {
297         if(C->wm.area && C->wm.area->spacetype==SPACE_OUTLINER)
298                 return C->wm.area->spacedata.first;
299         return NULL;
300 }
301
302 struct SpaceNla *CTX_wm_space_nla(const bContext *C)
303 {
304         if(C->wm.area && C->wm.area->spacetype==SPACE_NLA)
305                 return C->wm.area->spacedata.first;
306         return NULL;
307 }
308
309 struct SpaceTime *CTX_wm_space_time(const bContext *C)
310 {
311         if(C->wm.area && C->wm.area->spacetype==SPACE_TIME)
312                 return C->wm.area->spacedata.first;
313         return NULL;
314 }
315
316 struct SpaceNode *CTX_wm_space_node(const bContext *C)
317 {
318         if(C->wm.area && C->wm.area->spacetype==SPACE_NODE)
319                 return C->wm.area->spacedata.first;
320         return NULL;
321 }
322
323 struct SpaceLogic *CTX_wm_space_logic(const bContext *C)
324 {
325         if(C->wm.area && C->wm.area->spacetype==SPACE_LOGIC)
326                 return C->wm.area->spacedata.first;
327         return NULL;
328 }
329
330 struct SpaceIpo *CTX_wm_space_graph(const bContext *C)
331 {
332         if(C->wm.area && C->wm.area->spacetype==SPACE_IPO)
333                 return C->wm.area->spacedata.first;
334         return NULL;
335 }
336
337 struct SpaceAction *CTX_wm_space_action(const bContext *C)
338 {
339         if(C->wm.area && C->wm.area->spacetype==SPACE_ACTION)
340                 return C->wm.area->spacedata.first;
341         return NULL;
342 }
343
344 struct SpaceInfo *CTX_wm_space_info(const bContext *C)
345 {
346         if(C->wm.area && C->wm.area->spacetype==SPACE_INFO)
347                 return C->wm.area->spacedata.first;
348         return NULL;
349 }
350
351 struct SpaceUserPref *CTX_wm_space_userpref(const bContext *C)
352 {
353         if(C->wm.area && C->wm.area->spacetype==SPACE_USERPREF)
354                 return C->wm.area->spacedata.first;
355         return NULL;
356 }
357
358 void CTX_wm_manager_set(bContext *C, wmWindowManager *wm)
359 {
360         C->wm.manager= wm;
361         C->wm.window= NULL;
362         C->wm.screen= NULL;
363         C->wm.area= NULL;
364         C->wm.region= NULL;
365 }
366
367 void CTX_wm_window_set(bContext *C, wmWindow *win)
368 {
369         C->wm.window= win;
370         C->wm.screen= (win)? win->screen: NULL;
371         C->data.scene= (C->wm.screen)? C->wm.screen->scene: NULL;
372         C->wm.area= NULL;
373         C->wm.region= NULL;
374 }
375
376 void CTX_wm_screen_set(bContext *C, bScreen *screen)
377 {
378         C->wm.screen= screen;
379         C->data.scene= (C->wm.screen)? C->wm.screen->scene: NULL;
380         C->wm.area= NULL;
381         C->wm.region= NULL;
382 }
383
384 void CTX_wm_area_set(bContext *C, ScrArea *area)
385 {
386         C->wm.area= area;
387         C->wm.region= NULL;
388 }
389
390 void CTX_wm_region_set(bContext *C, ARegion *region)
391 {
392         C->wm.region= region;
393 }
394
395 void CTX_wm_menu_set(bContext *C, ARegion *menu)
396 {
397         C->wm.menu= menu;
398 }
399
400 /* data context utility functions */
401
402 struct bContextDataResult {
403         PointerRNA ptr;
404         ListBase list;
405         const char **dir;
406 };
407
408 static int ctx_data_get(bContext *C, const char *member, bContextDataResult *result)
409 {
410         int done= 0, recursion= C->data.recursion;
411         int ret= 0;
412
413         memset(result, 0, sizeof(bContextDataResult));
414
415         if(CTX_py_dict_get(C)) {
416                 return bpy_context_get(C, member, result);
417         }
418
419         /* we check recursion to ensure that we do not get infinite
420          * loops requesting data from ourselfs in a context callback */
421
422         /* Ok, this looks evil...
423          * if(ret) done= -(-ret | -done);
424          *
425          * Values in order of importance
426          * (0, -1, 1) - Where 1 is highest priority
427          * */
428         if(done!=1 && recursion < 1 && C->wm.store) {
429                 bContextStoreEntry *entry;
430
431                 C->data.recursion= 1;
432
433                 for(entry=C->wm.store->entries.first; entry; entry=entry->next) {
434                         if(strcmp(entry->name, member) == 0) {
435                                 result->ptr= entry->ptr;
436                                 done= 1;
437                         }
438                 }
439         }
440         if(done!=1 && recursion < 2 && C->wm.region) {
441                 C->data.recursion= 2;
442                 if(C->wm.region->type && C->wm.region->type->context) {
443                         ret = C->wm.region->type->context(C, member, result);
444                         if(ret) done= -(-ret | -done);
445
446                 }
447         }
448         if(done!=1 && recursion < 3 && C->wm.area) {
449                 C->data.recursion= 3;
450                 if(C->wm.area->type && C->wm.area->type->context) {
451                         ret = C->wm.area->type->context(C, member, result);
452                         if(ret) done= -(-ret | -done);
453                 }
454         }
455         if(done!=1 && recursion < 4 && C->wm.screen) {
456                 bContextDataCallback cb= C->wm.screen->context;
457                 C->data.recursion= 4;
458                 if(cb) {
459                         ret = cb(C, member, result);
460                         if(ret) done= -(-ret | -done);
461                 }
462         }
463
464         C->data.recursion= recursion;
465
466         return done;
467 }
468
469 static void *ctx_data_pointer_get(const bContext *C, const char *member)
470 {
471         bContextDataResult result;
472
473         if(C && ctx_data_get((bContext*)C, member, &result)==1)
474                 return result.ptr.data;
475
476         return NULL;
477 }
478
479 static int ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer)
480 {
481         bContextDataResult result;
482
483         if(ctx_data_get((bContext*)C, member, &result)==1) {
484                 *pointer= result.ptr.data;
485                 return 1;
486         }
487         else {
488                 *pointer= NULL;
489                 return 0;
490         }
491 }
492
493 static int ctx_data_collection_get(const bContext *C, const char *member, ListBase *list)
494 {
495         bContextDataResult result;
496
497         if(ctx_data_get((bContext*)C, member, &result)==1) {
498                 *list= result.list;
499                 return 1;
500         }
501
502         list->first= NULL;
503         list->last= NULL;
504
505         return 0;
506 }
507
508 PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
509 {
510         bContextDataResult result;
511
512         if(ctx_data_get((bContext*)C, member, &result)==1)
513                 return result.ptr;
514         else
515                 return PointerRNA_NULL;
516 }
517
518 PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
519 {
520         PointerRNA ptr = CTX_data_pointer_get(C, member);
521
522         if(ptr.data && RNA_struct_is_a(ptr.type, type))
523                 return ptr;
524         
525         return PointerRNA_NULL;
526 }
527
528 ListBase CTX_data_collection_get(const bContext *C, const char *member)
529 {
530         bContextDataResult result;
531
532         if(ctx_data_get((bContext*)C, member, &result)==1) {
533                 return result.list;
534         }
535         else {
536                 ListBase list;
537                 memset(&list, 0, sizeof(list));
538                 return list;
539         }
540 }
541
542 /* 1:found,  -1:found but not set,  0:not found */
543 int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb)
544 {
545         bContextDataResult result;
546         int ret= ctx_data_get((bContext*)C, member, &result);
547
548         if(ret==1) {
549                 *r_ptr= result.ptr;
550                 *r_lb= result.list;
551         }
552         else {
553                 memset(r_ptr, 0, sizeof(*r_ptr));
554                 memset(r_lb, 0, sizeof(*r_lb));
555         }
556
557         return ret;
558 }
559
560 static void data_dir_add(ListBase *lb, const char *member)
561 {
562         LinkData *link;
563
564         if(strcmp(member, "scene") == 0) /* exception */
565                 return;
566
567         for(link=lb->first; link; link=link->next)
568                 if(strcmp(link->data, member) == 0)
569                         return;
570         
571         link= MEM_callocN(sizeof(LinkData), "LinkData");
572         link->data= (void*)member;
573         BLI_addtail(lb, link);
574 }
575
576 ListBase CTX_data_dir_get(const bContext *C)
577 {
578         bContextDataResult result;
579         ListBase lb;
580         int a;
581
582         memset(&lb, 0, sizeof(lb));
583
584         if(C->wm.store) {
585                 bContextStoreEntry *entry;
586
587                 for(entry=C->wm.store->entries.first; entry; entry=entry->next)
588                         data_dir_add(&lb, entry->name);
589         }
590         if(C->wm.region && C->wm.region->type && C->wm.region->type->context) {
591                 memset(&result, 0, sizeof(result));
592                 C->wm.region->type->context(C, "", &result);
593
594                 if(result.dir)
595                         for(a=0; result.dir[a]; a++)
596                                 data_dir_add(&lb, result.dir[a]);
597         }
598         if(C->wm.area && C->wm.area->type && C->wm.area->type->context) {
599                 memset(&result, 0, sizeof(result));
600                 C->wm.area->type->context(C, "", &result);
601
602                 if(result.dir)
603                         for(a=0; result.dir[a]; a++)
604                                 data_dir_add(&lb, result.dir[a]);
605         }
606         if(C->wm.screen && C->wm.screen->context) {
607                 bContextDataCallback cb= C->wm.screen->context;
608                 memset(&result, 0, sizeof(result));
609                 cb(C, "", &result);
610
611                 if(result.dir)
612                         for(a=0; result.dir[a]; a++)
613                                 data_dir_add(&lb, result.dir[a]);
614         }
615
616         return lb;
617 }
618
619 int CTX_data_equals(const char *member, const char *str)
620 {
621         return (strcmp(member, str) == 0);
622 }
623
624 int CTX_data_dir(const char *member)
625 {
626         return (strcmp(member, "") == 0);
627 }
628
629 void CTX_data_id_pointer_set(bContextDataResult *result, ID *id)
630 {
631         RNA_id_pointer_create(id, &result->ptr);
632 }
633
634 void CTX_data_pointer_set(bContextDataResult *result, ID *id, StructRNA *type, void *data)
635 {
636         RNA_pointer_create(id, type, data, &result->ptr);
637 }
638
639 void CTX_data_id_list_add(bContextDataResult *result, ID *id)
640 {
641         CollectionPointerLink *link;
642
643         link= MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_id_list_add");
644         RNA_id_pointer_create(id, &link->ptr);
645
646         BLI_addtail(&result->list, link);
647 }
648
649 void CTX_data_list_add(bContextDataResult *result, ID *id, StructRNA *type, void *data)
650 {
651         CollectionPointerLink *link;
652
653         link= MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_list_add");
654         RNA_pointer_create(id, type, data, &link->ptr);
655
656         BLI_addtail(&result->list, link);
657 }
658
659 int ctx_data_list_count(const bContext *C, int (*func)(const bContext*, ListBase*))
660 {
661         ListBase list;
662
663         if(func(C, &list)) {
664                 int tot= BLI_countlist(&list);
665                 BLI_freelistN(&list);
666                 return tot;
667         }
668         else
669                 return 0;
670 }
671
672 void CTX_data_dir_set(bContextDataResult *result, const char **dir)
673 {
674         result->dir= dir;
675 }
676
677 /* data context */
678
679 Main *CTX_data_main(const bContext *C)
680 {
681         Main *bmain;
682
683         if(ctx_data_pointer_verify(C, "main", (void*)&bmain))
684                 return bmain;
685         else
686                 return C->data.main;
687 }
688
689 void CTX_data_main_set(bContext *C, Main *bmain)
690 {
691         C->data.main= bmain;
692 }
693
694 Scene *CTX_data_scene(const bContext *C)
695 {
696         Scene *scene;
697
698         if(ctx_data_pointer_verify(C, "scene", (void*)&scene))
699                 return scene;
700         else
701                 return C->data.scene;
702 }
703
704 int CTX_data_mode_enum(const bContext *C)
705 {
706         Object *obedit= CTX_data_edit_object(C);
707
708         if(obedit) {
709                 switch(obedit->type) {
710                         case OB_MESH:
711                                 return CTX_MODE_EDIT_MESH;
712                         case OB_CURVE:
713                                 return CTX_MODE_EDIT_CURVE;
714                         case OB_SURF:
715                                 return CTX_MODE_EDIT_SURFACE;
716                         case OB_FONT:
717                                 return CTX_MODE_EDIT_TEXT;
718                         case OB_ARMATURE:
719                                 return CTX_MODE_EDIT_ARMATURE;
720                         case OB_MBALL:
721                                 return CTX_MODE_EDIT_METABALL;
722                         case OB_LATTICE:
723                                 return CTX_MODE_EDIT_LATTICE;
724                 }
725         }
726         else {
727                 Object *ob = CTX_data_active_object(C);
728
729                 if(ob) {
730                         if(ob->mode & OB_MODE_POSE) return CTX_MODE_POSE;
731                         else if(ob->mode & OB_MODE_SCULPT)  return CTX_MODE_SCULPT;
732                         else if(ob->mode & OB_MODE_WEIGHT_PAINT) return CTX_MODE_PAINT_WEIGHT;
733                         else if(ob->mode & OB_MODE_VERTEX_PAINT) return CTX_MODE_PAINT_VERTEX;
734                         else if(ob->mode & OB_MODE_TEXTURE_PAINT) return CTX_MODE_PAINT_TEXTURE;
735                         else if(ob->mode & OB_MODE_PARTICLE_EDIT) return CTX_MODE_PARTICLE;
736                 }
737         }
738
739         return CTX_MODE_OBJECT;
740 }
741
742
743 /* would prefer if we can use the enum version below over this one - Campbell */
744 /* must be aligned with above enum  */
745 static char *data_mode_strings[] = {
746         "mesh_edit",
747         "curve_edit",
748         "surface_edit",
749         "text_edit",
750         "armature_edit",
751         "mball_edit",
752         "lattice_edit",
753         "posemode",
754         "sculpt_mode",
755         "weightpaint",
756         "vertexpaint",
757         "texturepaint",
758         "particlemode",
759         "objectmode",
760         0
761 };
762 char *CTX_data_mode_string(const bContext *C)
763 {
764         return data_mode_strings[CTX_data_mode_enum(C)];
765 }
766
767 void CTX_data_scene_set(bContext *C, Scene *scene)
768 {
769         C->data.scene= scene;
770 }
771
772 ToolSettings *CTX_data_tool_settings(const bContext *C)
773 {
774         Scene *scene = CTX_data_scene(C);
775
776         if(scene)
777                 return scene->toolsettings;
778         else
779                 return NULL;
780 }
781
782 int CTX_data_selected_nodes(const bContext *C, ListBase *list)
783 {
784         return ctx_data_collection_get(C, "selected_nodes", list);
785 }
786
787 int CTX_data_selected_editable_objects(const bContext *C, ListBase *list)
788 {
789         return ctx_data_collection_get(C, "selected_editable_objects", list);
790 }
791
792 int CTX_data_selected_editable_bases(const bContext *C, ListBase *list)
793 {
794         return ctx_data_collection_get(C, "selected_editable_bases", list);
795 }
796
797 int CTX_data_selected_objects(const bContext *C, ListBase *list)
798 {
799         return ctx_data_collection_get(C, "selected_objects", list);
800 }
801
802 int CTX_data_selected_bases(const bContext *C, ListBase *list)
803 {
804         return ctx_data_collection_get(C, "selected_bases", list);
805 }
806
807 int CTX_data_visible_objects(const bContext *C, ListBase *list)
808 {
809         return ctx_data_collection_get(C, "visible_objects", list);
810 }
811
812 int CTX_data_visible_bases(const bContext *C, ListBase *list)
813 {
814         return ctx_data_collection_get(C, "visible_bases", list);
815 }
816
817 int CTX_data_selectable_objects(const bContext *C, ListBase *list)
818 {
819         return ctx_data_collection_get(C, "selectable_objects", list);
820 }
821
822 int CTX_data_selectable_bases(const bContext *C, ListBase *list)
823 {
824         return ctx_data_collection_get(C, "selectable_bases", list);
825 }
826
827 struct Object *CTX_data_active_object(const bContext *C)
828 {
829         return ctx_data_pointer_get(C, "active_object");
830 }
831
832 struct Base *CTX_data_active_base(const bContext *C)
833 {
834         return ctx_data_pointer_get(C, "active_base");
835 }
836
837 struct Object *CTX_data_edit_object(const bContext *C)
838 {
839         return ctx_data_pointer_get(C, "edit_object");
840 }
841
842 struct Image *CTX_data_edit_image(const bContext *C)
843 {
844         return ctx_data_pointer_get(C, "edit_image");
845 }
846
847 struct Text *CTX_data_edit_text(const bContext *C)
848 {
849         return ctx_data_pointer_get(C, "edit_text");
850 }
851
852 struct EditBone *CTX_data_active_bone(const bContext *C)
853 {
854         return ctx_data_pointer_get(C, "active_bone");
855 }
856
857 int CTX_data_selected_bones(const bContext *C, ListBase *list)
858 {
859         return ctx_data_collection_get(C, "selected_bones", list);
860 }
861
862 int CTX_data_selected_editable_bones(const bContext *C, ListBase *list)
863 {
864         return ctx_data_collection_get(C, "selected_editable_bones", list);
865 }
866
867 int CTX_data_visible_bones(const bContext *C, ListBase *list)
868 {
869         return ctx_data_collection_get(C, "visible_bones", list);
870 }
871
872 int CTX_data_editable_bones(const bContext *C, ListBase *list)
873 {
874         return ctx_data_collection_get(C, "editable_bones", list);
875 }
876
877 struct bPoseChannel *CTX_data_active_pchan(const bContext *C)
878 {
879         return ctx_data_pointer_get(C, "active_pchan");
880 }
881
882 int CTX_data_selected_pchans(const bContext *C, ListBase *list)
883 {
884         return ctx_data_collection_get(C, "selected_pchans", list);
885 }
886
887 int CTX_data_visible_pchans(const bContext *C, ListBase *list)
888 {
889         return ctx_data_collection_get(C, "visible_pchans", list);
890 }
891