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