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