913 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			913 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/**
 | 
						|
 * $Id$
 | 
						|
 *
 | 
						|
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or
 | 
						|
 * modify it under the terms of the GNU General Public License
 | 
						|
 * as published by the Free Software Foundation; either version 2
 | 
						|
 * of the License, or (at your option) any later version.
 | 
						|
 *
 | 
						|
 * This program is distributed in the hope that it will be useful,
 | 
						|
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
 * GNU General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU General Public License
 | 
						|
 * along with this program; if not, write to the Free Software Foundation,
 | 
						|
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
						|
 *
 | 
						|
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 | 
						|
 * All rights reserved.
 | 
						|
 *
 | 
						|
 * Contributor(s): Blender Foundation (2008).
 | 
						|
 *
 | 
						|
 * ***** END GPL LICENSE BLOCK *****
 | 
						|
 */
 | 
						|
 | 
						|
#include "MEM_guardedalloc.h"
 | 
						|
 | 
						|
#include "DNA_scene_types.h"
 | 
						|
#include "DNA_screen_types.h"
 | 
						|
#include "DNA_space_types.h"
 | 
						|
#include "DNA_view3d_types.h"
 | 
						|
#include "DNA_windowmanager_types.h"
 | 
						|
#include "DNA_object_types.h"
 | 
						|
 | 
						|
#include "RNA_access.h"
 | 
						|
 | 
						|
#include "BLI_listbase.h"
 | 
						|
#include "BLI_string.h"
 | 
						|
 | 
						|
#include "BKE_context.h"
 | 
						|
#include "BKE_main.h"
 | 
						|
#include "BKE_screen.h"
 | 
						|
 | 
						|
#ifndef DISABLE_PYTHON
 | 
						|
#include "BPY_extern.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
/* struct */
 | 
						|
 | 
						|
struct bContext {
 | 
						|
	int thread;
 | 
						|
 | 
						|
	/* windowmanager context */
 | 
						|
	struct {
 | 
						|
		struct wmWindowManager *manager;
 | 
						|
		struct wmWindow *window;
 | 
						|
		struct bScreen *screen;
 | 
						|
		struct ScrArea *area;
 | 
						|
		struct ARegion *region;
 | 
						|
		struct ARegion *menu;
 | 
						|
		struct bContextStore *store;
 | 
						|
	} wm;
 | 
						|
	
 | 
						|
	/* data context */
 | 
						|
	struct {
 | 
						|
		struct Main *main;
 | 
						|
		struct Scene *scene;
 | 
						|
 | 
						|
		int recursion;
 | 
						|
		int py_init; /* true if python is initialized */
 | 
						|
		void *py_context;
 | 
						|
	} data;
 | 
						|
	
 | 
						|
	/* data evaluation */
 | 
						|
	struct {
 | 
						|
		int render;
 | 
						|
	} eval;
 | 
						|
};
 | 
						|
 | 
						|
/* context */
 | 
						|
 | 
						|
bContext *CTX_create()
 | 
						|
{
 | 
						|
	bContext *C;
 | 
						|
	
 | 
						|
	C= MEM_callocN(sizeof(bContext), "bContext");
 | 
						|
 | 
						|
	return C;
 | 
						|
}
 | 
						|
 | 
						|
bContext *CTX_copy(const bContext *C)
 | 
						|
{
 | 
						|
	bContext *newC= MEM_dupallocN((void*)C);
 | 
						|
 | 
						|
	return newC;
 | 
						|
}
 | 
						|
 | 
						|
void CTX_free(bContext *C)
 | 
						|
{
 | 
						|
	MEM_freeN(C);
 | 
						|
}
 | 
						|
 | 
						|
/* store */
 | 
						|
 | 
						|
bContextStore *CTX_store_add(ListBase *contexts, char *name, PointerRNA *ptr)
 | 
						|
{
 | 
						|
	bContextStoreEntry *entry;
 | 
						|
	bContextStore *ctx, *lastctx;
 | 
						|
 | 
						|
	/* ensure we have a context to put the entry in, if it was already used
 | 
						|
	 * we have to copy the context to ensure */
 | 
						|
	ctx= contexts->last;
 | 
						|
 | 
						|
	if(!ctx || ctx->used) {
 | 
						|
		if(ctx) {
 | 
						|
			lastctx= ctx;
 | 
						|
			ctx= MEM_dupallocN(lastctx);
 | 
						|
			BLI_duplicatelist(&ctx->entries, &lastctx->entries);
 | 
						|
		}
 | 
						|
		else
 | 
						|
			ctx= MEM_callocN(sizeof(bContextStore), "bContextStore");
 | 
						|
 | 
						|
		BLI_addtail(contexts, ctx);
 | 
						|
	}
 | 
						|
 | 
						|
	entry= MEM_callocN(sizeof(bContextStoreEntry), "bContextStoreEntry");
 | 
						|
	BLI_strncpy(entry->name, name, sizeof(entry->name));
 | 
						|
	entry->ptr= *ptr;
 | 
						|
 | 
						|
	BLI_addtail(&ctx->entries, entry);
 | 
						|
 | 
						|
	return ctx;
 | 
						|
}
 | 
						|
 | 
						|
void CTX_store_set(bContext *C, bContextStore *store)
 | 
						|
{
 | 
						|
	C->wm.store= store;
 | 
						|
}
 | 
						|
 | 
						|
bContextStore *CTX_store_copy(bContextStore *store)
 | 
						|
{
 | 
						|
	bContextStore *ctx;
 | 
						|
 | 
						|
	ctx= MEM_dupallocN(store);
 | 
						|
	BLI_duplicatelist(&ctx->entries, &store->entries);
 | 
						|
 | 
						|
	return ctx;
 | 
						|
}
 | 
						|
 | 
						|
void CTX_store_free(bContextStore *store)
 | 
						|
{
 | 
						|
	BLI_freelistN(&store->entries);
 | 
						|
	MEM_freeN(store);
 | 
						|
}
 | 
						|
 | 
						|
void CTX_store_free_list(ListBase *contexts)
 | 
						|
{
 | 
						|
	bContextStore *ctx;
 | 
						|
 | 
						|
	while((ctx= contexts->first)) {
 | 
						|
		BLI_remlink(contexts, ctx);
 | 
						|
		CTX_store_free(ctx);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/* is python initialied? */
 | 
						|
int CTX_py_init_get(bContext *C)
 | 
						|
{
 | 
						|
	return C->data.py_init;
 | 
						|
}
 | 
						|
void CTX_py_init_set(bContext *C, int value)
 | 
						|
{
 | 
						|
	C->data.py_init= value;
 | 
						|
}
 | 
						|
 | 
						|
void *CTX_py_dict_get(bContext *C)
 | 
						|
{
 | 
						|
	return C->data.py_context;
 | 
						|
}
 | 
						|
void CTX_py_dict_set(bContext *C, void *value)
 | 
						|
{
 | 
						|
	C->data.py_context= value;
 | 
						|
}
 | 
						|
 | 
						|
/* window manager context */
 | 
						|
 | 
						|
wmWindowManager *CTX_wm_manager(const bContext *C)
 | 
						|
{
 | 
						|
	return C->wm.manager;
 | 
						|
}
 | 
						|
 | 
						|
wmWindow *CTX_wm_window(const bContext *C)
 | 
						|
{
 | 
						|
	return C->wm.window;
 | 
						|
}
 | 
						|
 | 
						|
bScreen *CTX_wm_screen(const bContext *C)
 | 
						|
{
 | 
						|
	return C->wm.screen;
 | 
						|
}
 | 
						|
 | 
						|
ScrArea *CTX_wm_area(const bContext *C)
 | 
						|
{
 | 
						|
	return C->wm.area;
 | 
						|
}
 | 
						|
 | 
						|
SpaceLink *CTX_wm_space_data(const bContext *C)
 | 
						|
{
 | 
						|
	return (C->wm.area)? C->wm.area->spacedata.first: NULL;
 | 
						|
}
 | 
						|
 | 
						|
ARegion *CTX_wm_region(const bContext *C)
 | 
						|
{
 | 
						|
	return C->wm.region;
 | 
						|
}
 | 
						|
 | 
						|
void *CTX_wm_region_data(const bContext *C)
 | 
						|
{
 | 
						|
	return (C->wm.region)? C->wm.region->regiondata: NULL;
 | 
						|
}
 | 
						|
 | 
						|
struct ARegion *CTX_wm_menu(const bContext *C)
 | 
						|
{
 | 
						|
	return C->wm.menu;
 | 
						|
}
 | 
						|
 | 
						|
struct ReportList *CTX_wm_reports(const bContext *C)
 | 
						|
{
 | 
						|
	if (C->wm.manager)
 | 
						|
		return &(C->wm.manager->reports);
 | 
						|
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
View3D *CTX_wm_view3d(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_VIEW3D)
 | 
						|
		return C->wm.area->spacedata.first;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
RegionView3D *CTX_wm_region_view3d(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_VIEW3D)
 | 
						|
		if(C->wm.region)
 | 
						|
			return C->wm.region->regiondata;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
struct SpaceText *CTX_wm_space_text(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_TEXT)
 | 
						|
		return C->wm.area->spacedata.first;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
struct SpaceConsole *CTX_wm_space_console(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_CONSOLE)
 | 
						|
		return C->wm.area->spacedata.first;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
struct SpaceImage *CTX_wm_space_image(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_IMAGE)
 | 
						|
		return C->wm.area->spacedata.first;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
struct SpaceButs *CTX_wm_space_buts(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_BUTS)
 | 
						|
		return C->wm.area->spacedata.first;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
struct SpaceFile *CTX_wm_space_file(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_FILE)
 | 
						|
		return C->wm.area->spacedata.first;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
struct SpaceSeq *CTX_wm_space_seq(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_SEQ)
 | 
						|
		return C->wm.area->spacedata.first;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
struct SpaceOops *CTX_wm_space_outliner(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_OUTLINER)
 | 
						|
		return C->wm.area->spacedata.first;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
struct SpaceNla *CTX_wm_space_nla(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_NLA)
 | 
						|
		return C->wm.area->spacedata.first;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
struct SpaceTime *CTX_wm_space_time(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_TIME)
 | 
						|
		return C->wm.area->spacedata.first;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
struct SpaceNode *CTX_wm_space_node(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_NODE)
 | 
						|
		return C->wm.area->spacedata.first;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
struct SpaceLogic *CTX_wm_space_logic(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_LOGIC)
 | 
						|
		return C->wm.area->spacedata.first;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
struct SpaceIpo *CTX_wm_space_graph(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_IPO)
 | 
						|
		return C->wm.area->spacedata.first;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
struct SpaceAction *CTX_wm_space_action(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_ACTION)
 | 
						|
		return C->wm.area->spacedata.first;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
struct SpaceInfo *CTX_wm_space_info(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_INFO)
 | 
						|
		return C->wm.area->spacedata.first;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
struct SpaceUserPref *CTX_wm_space_userpref(const bContext *C)
 | 
						|
{
 | 
						|
	if(C->wm.area && C->wm.area->spacetype==SPACE_USERPREF)
 | 
						|
		return C->wm.area->spacedata.first;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
void CTX_wm_manager_set(bContext *C, wmWindowManager *wm)
 | 
						|
{
 | 
						|
	C->wm.manager= wm;
 | 
						|
	C->wm.window= NULL;
 | 
						|
	C->wm.screen= NULL;
 | 
						|
	C->wm.area= NULL;
 | 
						|
	C->wm.region= NULL;
 | 
						|
}
 | 
						|
 | 
						|
void CTX_wm_window_set(bContext *C, wmWindow *win)
 | 
						|
{
 | 
						|
	C->wm.window= win;
 | 
						|
	C->wm.screen= (win)? win->screen: NULL;
 | 
						|
	C->data.scene= (C->wm.screen)? C->wm.screen->scene: NULL;
 | 
						|
	C->wm.area= NULL;
 | 
						|
	C->wm.region= NULL;
 | 
						|
}
 | 
						|
 | 
						|
void CTX_wm_screen_set(bContext *C, bScreen *screen)
 | 
						|
{
 | 
						|
	C->wm.screen= screen;
 | 
						|
	C->data.scene= (C->wm.screen)? C->wm.screen->scene: NULL;
 | 
						|
	C->wm.area= NULL;
 | 
						|
	C->wm.region= NULL;
 | 
						|
}
 | 
						|
 | 
						|
void CTX_wm_area_set(bContext *C, ScrArea *area)
 | 
						|
{
 | 
						|
	C->wm.area= area;
 | 
						|
	C->wm.region= NULL;
 | 
						|
}
 | 
						|
 | 
						|
void CTX_wm_region_set(bContext *C, ARegion *region)
 | 
						|
{
 | 
						|
	C->wm.region= region;
 | 
						|
}
 | 
						|
 | 
						|
void CTX_wm_menu_set(bContext *C, ARegion *menu)
 | 
						|
{
 | 
						|
	C->wm.menu= menu;
 | 
						|
}
 | 
						|
 | 
						|
/* data context utility functions */
 | 
						|
 | 
						|
struct bContextDataResult {
 | 
						|
	PointerRNA ptr;
 | 
						|
	ListBase list;
 | 
						|
	const char **dir;
 | 
						|
	short type; /* 0: normal, 1: seq */
 | 
						|
};
 | 
						|
 | 
						|
static int ctx_data_get(bContext *C, const char *member, bContextDataResult *result)
 | 
						|
{
 | 
						|
	int done= 0, recursion= C->data.recursion;
 | 
						|
	int ret= 0;
 | 
						|
 | 
						|
	memset(result, 0, sizeof(bContextDataResult));
 | 
						|
#ifndef DISABLE_PYTHON
 | 
						|
	if(CTX_py_dict_get(C)) {
 | 
						|
		return BPY_context_get(C, member, result);
 | 
						|
//		if (BPY_context_get(C, member, result))
 | 
						|
//			return 1;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
	/* we check recursion to ensure that we do not get infinite
 | 
						|
	 * loops requesting data from ourselfs in a context callback */
 | 
						|
 | 
						|
	/* Ok, this looks evil...
 | 
						|
	 * if(ret) done= -(-ret | -done);
 | 
						|
	 *
 | 
						|
	 * Values in order of importance
 | 
						|
	 * (0, -1, 1) - Where 1 is highest priority
 | 
						|
	 * */
 | 
						|
	if(done!=1 && recursion < 1 && C->wm.store) {
 | 
						|
		bContextStoreEntry *entry;
 | 
						|
 | 
						|
		C->data.recursion= 1;
 | 
						|
 | 
						|
		for(entry=C->wm.store->entries.first; entry; entry=entry->next) {
 | 
						|
			if(strcmp(entry->name, member) == 0) {
 | 
						|
				result->ptr= entry->ptr;
 | 
						|
				done= 1;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if(done!=1 && recursion < 2 && C->wm.region) {
 | 
						|
		C->data.recursion= 2;
 | 
						|
		if(C->wm.region->type && C->wm.region->type->context) {
 | 
						|
			ret = C->wm.region->type->context(C, member, result);
 | 
						|
			if(ret) done= -(-ret | -done);
 | 
						|
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if(done!=1 && recursion < 3 && C->wm.area) {
 | 
						|
		C->data.recursion= 3;
 | 
						|
		if(C->wm.area->type && C->wm.area->type->context) {
 | 
						|
			ret = C->wm.area->type->context(C, member, result);
 | 
						|
			if(ret) done= -(-ret | -done);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if(done!=1 && recursion < 4 && C->wm.screen) {
 | 
						|
		bContextDataCallback cb= C->wm.screen->context;
 | 
						|
		C->data.recursion= 4;
 | 
						|
		if(cb) {
 | 
						|
			ret = cb(C, member, result);
 | 
						|
			if(ret) done= -(-ret | -done);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	C->data.recursion= recursion;
 | 
						|
 | 
						|
	return done;
 | 
						|
}
 | 
						|
 | 
						|
static void *ctx_data_pointer_get(const bContext *C, const char *member)
 | 
						|
{
 | 
						|
	bContextDataResult result;
 | 
						|
 | 
						|
	if(C && ctx_data_get((bContext*)C, member, &result)==1)
 | 
						|
		return result.ptr.data;
 | 
						|
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static int ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer)
 | 
						|
{
 | 
						|
	bContextDataResult result;
 | 
						|
 | 
						|
	/* if context is NULL, pointer must be NULL too and that is a valid return */
 | 
						|
	if (C == NULL) {
 | 
						|
		*pointer= NULL;
 | 
						|
		return 1;
 | 
						|
	}
 | 
						|
	else if(ctx_data_get((bContext*)C, member, &result)==1) {
 | 
						|
		*pointer= result.ptr.data;
 | 
						|
		return 1;
 | 
						|
	}
 | 
						|
	else {
 | 
						|
		*pointer= NULL;
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static int ctx_data_collection_get(const bContext *C, const char *member, ListBase *list)
 | 
						|
{
 | 
						|
	bContextDataResult result;
 | 
						|
 | 
						|
	if(ctx_data_get((bContext*)C, member, &result)==1) {
 | 
						|
		*list= result.list;
 | 
						|
		return 1;
 | 
						|
	}
 | 
						|
 | 
						|
	list->first= NULL;
 | 
						|
	list->last= NULL;
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
 | 
						|
{
 | 
						|
	bContextDataResult result;
 | 
						|
 | 
						|
	if(ctx_data_get((bContext*)C, member, &result)==1)
 | 
						|
		return result.ptr;
 | 
						|
	else
 | 
						|
		return PointerRNA_NULL;
 | 
						|
}
 | 
						|
 | 
						|
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
 | 
						|
{
 | 
						|
	PointerRNA ptr = CTX_data_pointer_get(C, member);
 | 
						|
 | 
						|
	if(ptr.data && RNA_struct_is_a(ptr.type, type))
 | 
						|
		return ptr;
 | 
						|
	
 | 
						|
	return PointerRNA_NULL;
 | 
						|
}
 | 
						|
 | 
						|
ListBase CTX_data_collection_get(const bContext *C, const char *member)
 | 
						|
{
 | 
						|
	bContextDataResult result;
 | 
						|
 | 
						|
	if(ctx_data_get((bContext*)C, member, &result)==1) {
 | 
						|
		return result.list;
 | 
						|
	}
 | 
						|
	else {
 | 
						|
		ListBase list;
 | 
						|
		memset(&list, 0, sizeof(list));
 | 
						|
		return list;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/* 1:found,  -1:found but not set,  0:not found */
 | 
						|
int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb, short *r_type)
 | 
						|
{
 | 
						|
	bContextDataResult result;
 | 
						|
	int ret= ctx_data_get((bContext*)C, member, &result);
 | 
						|
 | 
						|
	if(ret==1) {
 | 
						|
		*r_ptr= result.ptr;
 | 
						|
		*r_lb= result.list;
 | 
						|
		*r_type= result.type;
 | 
						|
	}
 | 
						|
	else {
 | 
						|
		memset(r_ptr, 0, sizeof(*r_ptr));
 | 
						|
		memset(r_lb, 0, sizeof(*r_lb));
 | 
						|
		*r_type= 0;
 | 
						|
	}
 | 
						|
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
static void data_dir_add(ListBase *lb, const char *member)
 | 
						|
{
 | 
						|
	LinkData *link;
 | 
						|
 | 
						|
	if(strcmp(member, "scene") == 0) /* exception */
 | 
						|
		return;
 | 
						|
 | 
						|
	for(link=lb->first; link; link=link->next)
 | 
						|
		if(strcmp(link->data, member) == 0)
 | 
						|
			return;
 | 
						|
	
 | 
						|
	link= MEM_callocN(sizeof(LinkData), "LinkData");
 | 
						|
	link->data= (void*)member;
 | 
						|
	BLI_addtail(lb, link);
 | 
						|
}
 | 
						|
 | 
						|
ListBase CTX_data_dir_get(const bContext *C)
 | 
						|
{
 | 
						|
	bContextDataResult result;
 | 
						|
	ListBase lb;
 | 
						|
	int a;
 | 
						|
 | 
						|
	memset(&lb, 0, sizeof(lb));
 | 
						|
 | 
						|
	if(C->wm.store) {
 | 
						|
		bContextStoreEntry *entry;
 | 
						|
 | 
						|
		for(entry=C->wm.store->entries.first; entry; entry=entry->next)
 | 
						|
			data_dir_add(&lb, entry->name);
 | 
						|
	}
 | 
						|
	if(C->wm.region && C->wm.region->type && C->wm.region->type->context) {
 | 
						|
		memset(&result, 0, sizeof(result));
 | 
						|
		C->wm.region->type->context(C, "", &result);
 | 
						|
 | 
						|
		if(result.dir)
 | 
						|
			for(a=0; result.dir[a]; a++)
 | 
						|
				data_dir_add(&lb, result.dir[a]);
 | 
						|
	}
 | 
						|
	if(C->wm.area && C->wm.area->type && C->wm.area->type->context) {
 | 
						|
		memset(&result, 0, sizeof(result));
 | 
						|
		C->wm.area->type->context(C, "", &result);
 | 
						|
 | 
						|
		if(result.dir)
 | 
						|
			for(a=0; result.dir[a]; a++)
 | 
						|
				data_dir_add(&lb, result.dir[a]);
 | 
						|
	}
 | 
						|
	if(C->wm.screen && C->wm.screen->context) {
 | 
						|
		bContextDataCallback cb= C->wm.screen->context;
 | 
						|
		memset(&result, 0, sizeof(result));
 | 
						|
		cb(C, "", &result);
 | 
						|
 | 
						|
		if(result.dir)
 | 
						|
			for(a=0; result.dir[a]; a++)
 | 
						|
				data_dir_add(&lb, result.dir[a]);
 | 
						|
	}
 | 
						|
 | 
						|
	return lb;
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_equals(const char *member, const char *str)
 | 
						|
{
 | 
						|
	return (strcmp(member, str) == 0);
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_dir(const char *member)
 | 
						|
{
 | 
						|
	return (strcmp(member, "") == 0);
 | 
						|
}
 | 
						|
 | 
						|
void CTX_data_id_pointer_set(bContextDataResult *result, ID *id)
 | 
						|
{
 | 
						|
	RNA_id_pointer_create(id, &result->ptr);
 | 
						|
}
 | 
						|
 | 
						|
void CTX_data_pointer_set(bContextDataResult *result, ID *id, StructRNA *type, void *data)
 | 
						|
{
 | 
						|
	RNA_pointer_create(id, type, data, &result->ptr);
 | 
						|
}
 | 
						|
 | 
						|
void CTX_data_id_list_add(bContextDataResult *result, ID *id)
 | 
						|
{
 | 
						|
	CollectionPointerLink *link;
 | 
						|
 | 
						|
	link= MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_id_list_add");
 | 
						|
	RNA_id_pointer_create(id, &link->ptr);
 | 
						|
 | 
						|
	BLI_addtail(&result->list, link);
 | 
						|
}
 | 
						|
 | 
						|
void CTX_data_list_add(bContextDataResult *result, ID *id, StructRNA *type, void *data)
 | 
						|
{
 | 
						|
	CollectionPointerLink *link;
 | 
						|
 | 
						|
	link= MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_list_add");
 | 
						|
	RNA_pointer_create(id, type, data, &link->ptr);
 | 
						|
 | 
						|
	BLI_addtail(&result->list, link);
 | 
						|
}
 | 
						|
 | 
						|
int ctx_data_list_count(const bContext *C, int (*func)(const bContext*, ListBase*))
 | 
						|
{
 | 
						|
	ListBase list;
 | 
						|
 | 
						|
	if(func(C, &list)) {
 | 
						|
		int tot= BLI_countlist(&list);
 | 
						|
		BLI_freelistN(&list);
 | 
						|
		return tot;
 | 
						|
	}
 | 
						|
	else
 | 
						|
		return 0;
 | 
						|
}
 | 
						|
 | 
						|
void CTX_data_dir_set(bContextDataResult *result, const char **dir)
 | 
						|
{
 | 
						|
	result->dir= dir;
 | 
						|
}
 | 
						|
 | 
						|
void CTX_data_type_set(bContextDataResult *result, short type)
 | 
						|
{
 | 
						|
	result->type= type;
 | 
						|
}
 | 
						|
 | 
						|
short CTX_data_type_get(bContextDataResult *result)
 | 
						|
{
 | 
						|
	return result->type;
 | 
						|
}
 | 
						|
 | 
						|
/* data context */
 | 
						|
 | 
						|
Main *CTX_data_main(const bContext *C)
 | 
						|
{
 | 
						|
	Main *bmain;
 | 
						|
 | 
						|
	if(ctx_data_pointer_verify(C, "main", (void*)&bmain))
 | 
						|
		return bmain;
 | 
						|
	else
 | 
						|
		return C->data.main;
 | 
						|
}
 | 
						|
 | 
						|
void CTX_data_main_set(bContext *C, Main *bmain)
 | 
						|
{
 | 
						|
	C->data.main= bmain;
 | 
						|
}
 | 
						|
 | 
						|
Scene *CTX_data_scene(const bContext *C)
 | 
						|
{
 | 
						|
	Scene *scene;
 | 
						|
 | 
						|
	if(ctx_data_pointer_verify(C, "scene", (void*)&scene))
 | 
						|
		return scene;
 | 
						|
	else
 | 
						|
		return C->data.scene;
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_mode_enum(const bContext *C)
 | 
						|
{
 | 
						|
	Object *obedit= CTX_data_edit_object(C);
 | 
						|
 | 
						|
	if(obedit) {
 | 
						|
		switch(obedit->type) {
 | 
						|
			case OB_MESH:
 | 
						|
				return CTX_MODE_EDIT_MESH;
 | 
						|
			case OB_CURVE:
 | 
						|
				return CTX_MODE_EDIT_CURVE;
 | 
						|
			case OB_SURF:
 | 
						|
				return CTX_MODE_EDIT_SURFACE;
 | 
						|
			case OB_FONT:
 | 
						|
				return CTX_MODE_EDIT_TEXT;
 | 
						|
			case OB_ARMATURE:
 | 
						|
				return CTX_MODE_EDIT_ARMATURE;
 | 
						|
			case OB_MBALL:
 | 
						|
				return CTX_MODE_EDIT_METABALL;
 | 
						|
			case OB_LATTICE:
 | 
						|
				return CTX_MODE_EDIT_LATTICE;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else {
 | 
						|
		Object *ob = CTX_data_active_object(C);
 | 
						|
 | 
						|
		if(ob) {
 | 
						|
			if(ob->mode & OB_MODE_POSE) return CTX_MODE_POSE;
 | 
						|
			else if(ob->mode & OB_MODE_SCULPT)  return CTX_MODE_SCULPT;
 | 
						|
			else if(ob->mode & OB_MODE_WEIGHT_PAINT) return CTX_MODE_PAINT_WEIGHT;
 | 
						|
			else if(ob->mode & OB_MODE_VERTEX_PAINT) return CTX_MODE_PAINT_VERTEX;
 | 
						|
			else if(ob->mode & OB_MODE_TEXTURE_PAINT) return CTX_MODE_PAINT_TEXTURE;
 | 
						|
			else if(ob->mode & OB_MODE_PARTICLE_EDIT) return CTX_MODE_PARTICLE;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return CTX_MODE_OBJECT;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* would prefer if we can use the enum version below over this one - Campbell */
 | 
						|
/* must be aligned with above enum  */
 | 
						|
static char *data_mode_strings[] = {
 | 
						|
	"mesh_edit",
 | 
						|
	"curve_edit",
 | 
						|
	"surface_edit",
 | 
						|
	"text_edit",
 | 
						|
	"armature_edit",
 | 
						|
	"mball_edit",
 | 
						|
	"lattice_edit",
 | 
						|
	"posemode",
 | 
						|
	"sculpt_mode",
 | 
						|
	"weightpaint",
 | 
						|
	"vertexpaint",
 | 
						|
	"texturepaint",
 | 
						|
	"particlemode",
 | 
						|
	"objectmode",
 | 
						|
	0
 | 
						|
};
 | 
						|
char *CTX_data_mode_string(const bContext *C)
 | 
						|
{
 | 
						|
	return data_mode_strings[CTX_data_mode_enum(C)];
 | 
						|
}
 | 
						|
 | 
						|
void CTX_data_scene_set(bContext *C, Scene *scene)
 | 
						|
{
 | 
						|
	C->data.scene= scene;
 | 
						|
}
 | 
						|
 | 
						|
ToolSettings *CTX_data_tool_settings(const bContext *C)
 | 
						|
{
 | 
						|
	Scene *scene = CTX_data_scene(C);
 | 
						|
 | 
						|
	if(scene)
 | 
						|
		return scene->toolsettings;
 | 
						|
	else
 | 
						|
		return NULL;
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_selected_nodes(const bContext *C, ListBase *list)
 | 
						|
{
 | 
						|
	return ctx_data_collection_get(C, "selected_nodes", list);
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_selected_editable_objects(const bContext *C, ListBase *list)
 | 
						|
{
 | 
						|
	return ctx_data_collection_get(C, "selected_editable_objects", list);
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_selected_editable_bases(const bContext *C, ListBase *list)
 | 
						|
{
 | 
						|
	return ctx_data_collection_get(C, "selected_editable_bases", list);
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_selected_objects(const bContext *C, ListBase *list)
 | 
						|
{
 | 
						|
	return ctx_data_collection_get(C, "selected_objects", list);
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_selected_bases(const bContext *C, ListBase *list)
 | 
						|
{
 | 
						|
	return ctx_data_collection_get(C, "selected_bases", list);
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_visible_objects(const bContext *C, ListBase *list)
 | 
						|
{
 | 
						|
	return ctx_data_collection_get(C, "visible_objects", list);
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_visible_bases(const bContext *C, ListBase *list)
 | 
						|
{
 | 
						|
	return ctx_data_collection_get(C, "visible_bases", list);
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_selectable_objects(const bContext *C, ListBase *list)
 | 
						|
{
 | 
						|
	return ctx_data_collection_get(C, "selectable_objects", list);
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_selectable_bases(const bContext *C, ListBase *list)
 | 
						|
{
 | 
						|
	return ctx_data_collection_get(C, "selectable_bases", list);
 | 
						|
}
 | 
						|
 | 
						|
struct Object *CTX_data_active_object(const bContext *C)
 | 
						|
{
 | 
						|
	return ctx_data_pointer_get(C, "active_object");
 | 
						|
}
 | 
						|
 | 
						|
struct Base *CTX_data_active_base(const bContext *C)
 | 
						|
{
 | 
						|
	return ctx_data_pointer_get(C, "active_base");
 | 
						|
}
 | 
						|
 | 
						|
struct Object *CTX_data_edit_object(const bContext *C)
 | 
						|
{
 | 
						|
	return ctx_data_pointer_get(C, "edit_object");
 | 
						|
}
 | 
						|
 | 
						|
struct Image *CTX_data_edit_image(const bContext *C)
 | 
						|
{
 | 
						|
	return ctx_data_pointer_get(C, "edit_image");
 | 
						|
}
 | 
						|
 | 
						|
struct Text *CTX_data_edit_text(const bContext *C)
 | 
						|
{
 | 
						|
	return ctx_data_pointer_get(C, "edit_text");
 | 
						|
}
 | 
						|
 | 
						|
struct EditBone *CTX_data_active_bone(const bContext *C)
 | 
						|
{
 | 
						|
	return ctx_data_pointer_get(C, "active_bone");
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_selected_bones(const bContext *C, ListBase *list)
 | 
						|
{
 | 
						|
	return ctx_data_collection_get(C, "selected_bones", list);
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_selected_editable_bones(const bContext *C, ListBase *list)
 | 
						|
{
 | 
						|
	return ctx_data_collection_get(C, "selected_editable_bones", list);
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_visible_bones(const bContext *C, ListBase *list)
 | 
						|
{
 | 
						|
	return ctx_data_collection_get(C, "visible_bones", list);
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_editable_bones(const bContext *C, ListBase *list)
 | 
						|
{
 | 
						|
	return ctx_data_collection_get(C, "editable_bones", list);
 | 
						|
}
 | 
						|
 | 
						|
struct bPoseChannel *CTX_data_active_pose_bone(const bContext *C)
 | 
						|
{
 | 
						|
	return ctx_data_pointer_get(C, "active_pose_bone");
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_selected_pose_bones(const bContext *C, ListBase *list)
 | 
						|
{
 | 
						|
	return ctx_data_collection_get(C, "selected_pose_bones", list);
 | 
						|
}
 | 
						|
 | 
						|
int CTX_data_visible_pose_bones(const bContext *C, ListBase *list)
 | 
						|
{
 | 
						|
	return ctx_data_collection_get(C, "visible_pose_bones", list);
 | 
						|
}
 | 
						|
 |