Make local and make single user are back for ID template.

Internally these calls got unified, id_make_local and
id_copy are now used to do these operations for all types
that support it. Also reveals that for some ID types the
implementation is still missing.

Further, some small changes:

* unlink_text is now in blenkernel.
* copy_group was implemented.
* ID template now has an open operator again.
* fix preview to not change material reference count,
  even if temporary it shows up with threaded preview.
* id_unlink unifies unlink for text, object and group.
This commit is contained in:
Brecht Van Lommel 2009-09-04 21:02:43 +00:00
parent 670296dabe
commit 5dd9f7635a
20 changed files with 436 additions and 116 deletions

@ -74,7 +74,6 @@ struct bArmature *add_armature(char *name);
struct bArmature *get_armature(struct Object *ob);
void free_boneChildren(struct Bone *bone);
void free_bones (struct bArmature *arm);
void unlink_armature(struct bArmature *arm);
void free_armature(struct bArmature *arm);
void make_local_armature(struct bArmature *arm);
struct bArmature *copy_armature(struct bArmature *arm);

@ -41,6 +41,7 @@ void free_group_object(struct GroupObject *go);
void free_group(struct Group *group);
void unlink_group(struct Group *group);
struct Group *add_group(char *name);
struct Group *copy_group(struct Group *group);
void add_to_group(struct Group *group, struct Object *ob);
int rem_from_group(struct Group *group, struct Object *ob);
struct Group *find_group(struct Object *ob, struct Group *group);

@ -46,6 +46,9 @@ void *copy_libblock(void *rt);
void id_lib_extern(struct ID *id);
void id_us_plus(struct ID *id);
void id_us_min(struct ID *id);
int id_make_local(struct ID *id, int test);
int id_copy(struct ID *id, struct ID **newid, int test);
int id_unlink(struct ID *id, int test);
int check_for_dupid(struct ListBase *lb, struct ID *id, char *name);
int new_id(struct ListBase *lb, struct ID *id, const char *name);

@ -47,7 +47,6 @@ void unlink_actuators(struct ListBase *lb);
void free_actuator(struct bActuator *act);
void free_actuators(struct ListBase *lb);
void free_text_controllers(struct Text *txt);
void free_sensor(struct bSensor *sens);
void free_sensors(struct ListBase *lb);
struct bSensor *copy_sensor(struct bSensor *sens);

@ -84,7 +84,5 @@ int get_render_child_particle_number(struct RenderData *r, int num);
int get_render_shadow_samples(struct RenderData *r, int samples);
float get_render_aosss_error(struct RenderData *r, float error);
void free_dome_warp_text(struct Text *txt);
#endif

@ -35,6 +35,7 @@
extern "C" {
#endif
struct Main;
struct Text;
struct TextLine;
struct SpaceText;
@ -46,6 +47,7 @@ struct Text* add_empty_text (char *name);
int reopen_text (struct Text *text);
struct Text* add_text (char *file, const char *relpath);
struct Text* copy_text (struct Text *ta);
void unlink_text (struct Main *bmain, struct Text *text);
char* txt_to_buf (struct Text *text);
void txt_clean_text (struct Text *text);

@ -142,6 +142,16 @@ Group *add_group(char *name)
return group;
}
Group *copy_group(Group *group)
{
Group *groupn;
groupn= MEM_dupallocN(group);
BLI_duplicatelist(&groupn->gobject, &group->gobject);
return groupn;
}
/* external */
void add_to_group(Group *group, Object *ob)
{

@ -119,6 +119,13 @@
#define MAX_IDPUP 60 /* was 24 */
/* GS reads the memory pointed at in a specific ordering.
only use this definition, makes little and big endian systems
work fine, in conjunction with MAKE_ID */
/* from blendef: */
#define GS(a) (*((short *)(a)))
/* ************* general ************************ */
void id_lib_extern(ID *id)
@ -148,6 +155,217 @@ void id_us_min(ID *id)
id->us--;
}
int id_make_local(ID *id, int test)
{
if(id->flag & LIB_INDIRECT)
return 0;
switch(GS(id->name)) {
case ID_SCE:
return 0; /* not implemented */
case ID_LI:
return 0; /* can't be linked */
case ID_OB:
if(!test) make_local_object((Object*)id);
return 1;
case ID_ME:
if(!test) {
make_local_mesh((Mesh*)id);
make_local_key(((Mesh*)id)->key);
}
return 1;
case ID_CU:
if(!test) {
make_local_curve((Curve*)id);
make_local_key(((Curve*)id)->key);
}
return 1;
case ID_MB:
if(!test) make_local_mball((MetaBall*)id);
return 1;
case ID_MA:
if(!test) make_local_material((Material*)id);
return 1;
case ID_TE:
if(!test) make_local_texture((Tex*)id);
return 1;
case ID_IM:
return 0; /* not implemented */
case ID_WV:
return 0; /* deprecated */
case ID_LT:
if(!test) make_local_lattice((Lattice*)id);
return 1;
case ID_LA:
if(!test) make_local_lamp((Lamp*)id);
return 1;
case ID_CA:
if(!test) make_local_camera((Camera*)id);
return 1;
case ID_IP:
return 0; /* deprecated */
case ID_KE:
if(!test) make_local_key((Key*)id);
return 1;
case ID_WO:
if(!test) make_local_world((World*)id);
return 1;
case ID_SCR:
return 0; /* can't be linked */
case ID_VF:
return 0; /* not implemented */
case ID_TXT:
return 0; /* not implemented */
case ID_SCRIPT:
return 0; /* deprecated */
case ID_SO:
return 0; /* not implemented */
case ID_GR:
return 0; /* not implemented */
case ID_AR:
if(!test) make_local_armature((bArmature*)id);
return 1;
case ID_AC:
if(!test) make_local_action((bAction*)id);
return 1;
case ID_NT:
return 0; /* not implemented */
case ID_BR:
if(!test) make_local_brush((Brush*)id);
return 1;
case ID_PA:
if(!test) make_local_particlesettings((ParticleSettings*)id);
return 1;
case ID_WM:
return 0; /* can't be linked */
case ID_GD:
return 0; /* not implemented */
}
return 0;
}
int id_copy(ID *id, ID **newid, int test)
{
if(!test) *newid= NULL;
/* conventions:
* - make shallow copy, only this ID block
* - id.us of the new ID is set to 1 */
switch(GS(id->name)) {
case ID_SCE:
return 0; /* can't be copied from here */
case ID_LI:
return 0; /* can't be copied from here */
case ID_OB:
if(!test) *newid= (ID*)copy_object((Object*)id);
return 1;
case ID_ME:
if(!test) *newid= (ID*)copy_mesh((Mesh*)id);
return 1;
case ID_CU:
if(!test) *newid= (ID*)copy_curve((Curve*)id);
return 1;
case ID_MB:
if(!test) *newid= (ID*)copy_mball((MetaBall*)id);
return 1;
case ID_MA:
if(!test) *newid= (ID*)copy_material((Material*)id);
return 1;
case ID_TE:
if(!test) *newid= (ID*)copy_texture((Tex*)id);
return 1;
case ID_IM:
return 0; /* not implemented */
case ID_WV:
return 0; /* deprecated */
case ID_LT:
if(!test) *newid= (ID*)copy_lattice((Lattice*)id);
return 1;
case ID_LA:
if(!test) *newid= (ID*)copy_lamp((Lamp*)id);
return 1;
case ID_CA:
if(!test) *newid= (ID*)copy_camera((Camera*)id);
return 1;
case ID_IP:
return 0; /* deprecated */
case ID_KE:
if(!test) *newid= (ID*)copy_key((Key*)id);
return 1;
case ID_WO:
if(!test) *newid= (ID*)copy_world((World*)id);
return 1;
case ID_SCR:
return 0; /* can't be copied from here */
case ID_VF:
return 0; /* not implemented */
case ID_TXT:
if(!test) *newid= (ID*)copy_text((Text*)id);
return 1;
case ID_SCRIPT:
return 0; /* deprecated */
case ID_SO:
return 0; /* not implemented */
case ID_GR:
if(!test) *newid= (ID*)copy_group((Group*)id);
return 1;
case ID_AR:
if(!test) *newid= (ID*)copy_armature((bArmature*)id);
return 1;
case ID_AC:
if(!test) *newid= (ID*)copy_action((bAction*)id);
return 1;
case ID_NT:
if(!test) *newid= (ID*)ntreeCopyTree((bNodeTree*)id, 0);
return 1;
case ID_BR:
if(!test) *newid= (ID*)copy_brush((Brush*)id);
return 1;
case ID_PA:
if(!test) *newid= (ID*)psys_copy_settings((ParticleSettings*)id);
return 1;
case ID_WM:
return 0; /* can't be copied from here */
case ID_GD:
return 0; /* not implemented */
}
return 0;
}
int id_unlink(ID *id, int test)
{
Main *mainlib= G.main;
ListBase *lb;
switch(GS(id->name)) {
case ID_TXT:
if(test) return 1;
unlink_text(mainlib, (Text*)id);
break;
case ID_GR:
if(test) return 1;
unlink_group((Group*)id);
break;
case ID_OB:
if(test) return 1;
unlink_object(NULL, (Object*)id);
break;
}
if(id->us == 0) {
if(test) return 1;
lb= wich_libbase(mainlib, GS(id->name));
free_libblock(lb, id);
return 1;
}
return 0;
}
ListBase *wich_libbase(Main *mainlib, short type)
{
switch( type ) {
@ -409,13 +627,6 @@ void *alloc_libblock(ListBase *lb, short type, const char *name)
return id;
}
/* GS reads the memory pointed at in a specific ordering.
only use this definition, makes little and big endian systems
work fine, in conjunction with MAKE_ID */
/* from blendef: */
#define GS(a) (*((short *)(a)))
/* by spec, animdata is first item after ID */
/* we still read ->adt itself, to ensure compiler warns when it doesnt exist */
static void id_copy_animdata(ID *id)

@ -52,30 +52,6 @@
#include "BKE_blender.h"
#include "BKE_sca.h"
//#include "wm_event_types.h"
void free_text_controllers(Text *txt)
{
Object *ob;
bController *cont;
ob= G.main->object.first;
while(ob) {
cont= ob->controllers.first;
while(cont) {
if(cont->type==CONT_PYTHON) {
bPythonCont *pc;
pc= cont->data;
if(pc->text==txt) pc->text= NULL;
}
cont= cont->next;
}
ob= ob->id.next;
}
}
/* ******************* SENSORS ************************ */
void free_sensor(bSensor *sens)

@ -860,14 +860,3 @@ float get_render_aosss_error(RenderData *r, float error)
return error;
}
void free_dome_warp_text(struct Text *txt)
{
Scene *scene;
scene = G.main->scene.first;
while(scene) {
if (scene->r.dometext == txt)
scene->r.dometext = NULL;
scene = scene->id.next;
}
}

@ -37,14 +37,22 @@
#include "BLI_blenlib.h"
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
#include "DNA_controller_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_text_types.h"
#include "BKE_utildefines.h"
#include "BKE_text.h"
#include "BKE_library.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_text.h"
#include "BKE_utildefines.h"
#ifndef DISABLE_PYTHON
#include "BPY_extern.h"
@ -451,6 +459,85 @@ Text *copy_text(Text *ta)
return tan;
}
void unlink_text(Main *bmain, Text *text)
{
bScreen *scr;
ScrArea *area;
SpaceLink *sl;
Scene *scene;
Object *ob;
bController *cont;
bConstraint *con;
short update;
/* dome */
for(scene=bmain->scene.first; scene; scene=scene->id.next)
if(scene->r.dometext == text)
scene->r.dometext = NULL;
for(ob=bmain->object.first; ob; ob=ob->id.next) {
/* game controllers */
for(cont=ob->controllers.first; cont; cont=cont->next) {
if(cont->type==CONT_PYTHON) {
bPythonCont *pc;
pc= cont->data;
if(pc->text==text) pc->text= NULL;
}
}
/* pyconstraints */
update = 0;
if(ob->type==OB_ARMATURE && ob->pose) {
bPoseChannel *pchan;
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
for(con = pchan->constraints.first; con; con=con->next) {
if(con->type==CONSTRAINT_TYPE_PYTHON) {
bPythonConstraint *data = con->data;
if (data->text==text) data->text = NULL;
update = 1;
}
}
}
}
for(con = ob->constraints.first; con; con=con->next) {
if(con->type==CONSTRAINT_TYPE_PYTHON) {
bPythonConstraint *data = con->data;
if (data->text==text) data->text = NULL;
update = 1;
}
}
if(update)
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
}
/* pynodes */
// XXX nodeDynamicUnlinkText(&text->id);
/* text space */
for(scr= bmain->screen.first; scr; scr= scr->id.next) {
for(area= scr->areabase.first; area; area= area->next) {
for(sl= area->spacedata.first; sl; sl= sl->next) {
if(sl->spacetype==SPACE_TEXT) {
SpaceText *st= (SpaceText*) sl;
if(st->text==text) {
st->text= NULL;
st->top= 0;
}
}
}
}
}
text->id.us= 0;
}
/*****************************/
/* Editing utility functions */
/*****************************/

@ -238,7 +238,7 @@ static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, Poi
col= uiLayoutColumn(layout, 0);
/* current Grease Pencil block */
// TODO: show some info about who owns this?
uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", "GPENCIL_OT_data_unlink");
uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", NULL, "GPENCIL_OT_data_unlink");
/* add new layer button - can be used even when no data, since it can add a new block too */
uiItemO(col, NULL, 0, "GPENCIL_OT_layer_add");

@ -633,7 +633,7 @@ uiBlock *uiLayoutFreeBlock(uiLayout *layout);
/* templates */
void uiTemplateHeader(uiLayout *layout, struct bContext *C, int menus);
void uiTemplateID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
char *newop, char *unlinkop);
char *newop, char *openop, char *unlinkop);
uiLayout *uiTemplateModifier(uiLayout *layout, struct PointerRNA *ptr);
uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr);
void uiTemplatePreview(uiLayout *layout, struct ID *id, struct ID *parent, struct MTex *slot);

@ -157,7 +157,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
{
TemplateID *template= (TemplateID*)arg_litem;
PointerRNA idptr= RNA_property_pointer_get(&template->ptr, template->prop);
ID *id= idptr.data;
ID *id= idptr.data, *newid;
int event= GET_INT_FROM_POINTER(arg_event);
switch(event) {
@ -185,28 +185,48 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
}
else return;
break;
#if 0
case UI_ID_ALONE:
if(!id || id->us < 1)
return;
break;
case UI_ID_LOCAL:
if(!id || id->us < 1)
return;
if(id) {
if(id_make_local(id, 0)) {
/* reassign to get get proper updates/notifiers */
idptr= RNA_property_pointer_get(&template->ptr, template->prop);
RNA_property_pointer_set(&template->ptr, template->prop, idptr);
RNA_property_update(C, &template->ptr, template->prop);
}
}
break;
case UI_ID_ALONE:
if(id) {
/* make copy */
if(id_copy(id, &newid, 0) && newid) {
/* us is 1 by convention, but RNA_property_pointer_set
will also incremement it, so set it to zero */
newid->us= 0;
/* assign copy */
RNA_id_pointer_create(newid, &idptr);
RNA_property_pointer_set(&template->ptr, template->prop, idptr);
RNA_property_update(C, &template->ptr, template->prop);
}
}
break;
#if 0
case UI_ID_AUTO_NAME:
break;
#endif
}
}
static void template_ID(bContext *C, uiBlock *block, TemplateID *template, StructRNA *type, int flag, char *newop, char *unlinkop)
static void template_ID(bContext *C, uiBlock *block, TemplateID *template, StructRNA *type, int flag, char *newop, char *openop, char *unlinkop)
{
uiBut *but;
PointerRNA idptr;
ListBase *lb;
ID *id, *idfrom;
idptr= RNA_property_pointer_get(&template->ptr, template->prop);
id= idptr.data;
idfrom= template->ptr.id.data;
lb= template->idlb;
uiBlockBeginAlign(block);
@ -221,33 +241,86 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc
but->flag|= UI_HAS_ICON;
but->flag|= UI_ICON_LEFT;
}
if((idfrom && idfrom->lib))
uiButSetFlag(but, UI_BUT_DISABLED);
}
/* text button with name */
if(idptr.data) {
if(id) {
char name[64];
//text_idbutton(idptr.data, name);
//text_idbutton(id, name);
name[0]= '\0';
but= uiDefButR(block, TEX, 0, name, 0, 0, UI_UNIT_X*6, UI_UNIT_Y, &idptr, "name", -1, 0, 0, -1, -1, NULL);
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME));
if(id->lib) {
if(id->flag & LIB_INDIRECT) {
but= uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_INDIRECT, 0,0,UI_UNIT_X,UI_UNIT_Y, 0, 0, 0, 0, 0,
"Indirect library datablock, cannot change.");
uiButSetFlag(but, UI_BUT_DISABLED);
}
else {
but= uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_DIRECT, 0,0,UI_UNIT_X,UI_UNIT_Y, 0, 0, 0, 0, 0,
"Direct linked library datablock, click to make local.");
if(!id_make_local(id, 1 /* test */) || (idfrom && idfrom->lib))
uiButSetFlag(but, UI_BUT_DISABLED);
}
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_LOCAL));
}
if(id->us > 1) {
char str[32];
sprintf(str, "%d", id->us);
if(id->us<10)
but= uiDefBut(block, BUT, 0, str, 0,0,UI_UNIT_X,UI_UNIT_Y, 0, 0, 0, 0, 0, "Displays number of users of this data. Click to make a single-user copy.");
else
but= uiDefBut(block, BUT, 0, str, 0,0,UI_UNIT_X+10,UI_UNIT_Y, 0, 0, 0, 0, 0, "Displays number of users of this data. Click to make a single-user copy.");
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ALONE));
if(!id_copy(id, NULL, 1 /* test only */) || (idfrom && idfrom->lib))
uiButSetFlag(but, UI_BUT_DISABLED);
}
}
if(flag & UI_ID_ADD_NEW) {
int w= idptr.data?UI_UNIT_X:UI_UNIT_X*6;
int w= id?UI_UNIT_X: (flag & UI_ID_OPEN)? UI_UNIT_X*3: UI_UNIT_X*6;
if(newop) {
but= uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_REGION_WIN, ICON_ZOOMIN, (idptr.data)? "": "Add New", 0, 0, w, UI_UNIT_Y, NULL);
but= uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_REGION_WIN, ICON_ZOOMIN, (id)? "": "New", 0, 0, w, UI_UNIT_Y, NULL);
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
}
else {
but= uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (idptr.data)? "": "Add New", 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
but= uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (id)? "": "New", 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
}
if((idfrom && idfrom->lib))
uiButSetFlag(but, UI_BUT_DISABLED);
}
if(flag & UI_ID_OPEN) {
int w= id?UI_UNIT_X: (flag & UI_ID_ADD_NEW)? UI_UNIT_X*3: UI_UNIT_X*6;
if(openop) {
but= uiDefIconTextButO(block, BUT, openop, WM_OP_INVOKE_REGION_WIN, ICON_FILESEL, (id)? "": "Open", 0, 0, w, UI_UNIT_Y, NULL);
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
}
else {
but= uiDefIconTextBut(block, BUT, 0, ICON_FILESEL, (id)? "": "Open", 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
}
if((idfrom && idfrom->lib))
uiButSetFlag(but, UI_BUT_DISABLED);
}
/* delete button */
if(idptr.data && (flag & UI_ID_DELETE)) {
if(id && (flag & UI_ID_DELETE)) {
if(unlinkop) {
but= uiDefIconButO(block, BUT, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
}
@ -255,12 +328,15 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc
but= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_DELETE));
}
if((idfrom && idfrom->lib))
uiButSetFlag(but, UI_BUT_DISABLED);
}
uiBlockEndAlign(block);
}
void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *unlinkop)
void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop)
{
TemplateID *template;
uiBlock *block;
@ -286,6 +362,8 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname
if(newop)
flag |= UI_ID_ADD_NEW;
if(openop)
flag |= UI_ID_OPEN;
type= RNA_property_pointer_type(ptr, prop);
template->idlb= wich_libbase(CTX_data_main(C), RNA_type_to_ID_code(type));
@ -293,7 +371,7 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname
if(template->idlb) {
uiLayoutRow(layout, 1);
block= uiLayoutGetBlock(layout);
template_ID(C, block, template, type, flag, newop, unlinkop);
template_ID(C, block, template, type, flag, newop, openop, unlinkop);
}
MEM_freeN(template);

@ -2951,10 +2951,10 @@ static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt)
else if (ob->id.lib) {
uiPopupMenu *pup= uiPupMenuBegin(C, "OK?", ICON_QUESTION);
uiLayout *layout= uiPupMenuLayout(pup);
PointerRNA props_ptr = {0};
PointerRNA props_ptr;
/* create operator menu item with relevant properties filled in */
props_ptr= uiItemFullO(layout, op->type->name, 0, op->idname, props_ptr.data, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS);
props_ptr= uiItemFullO(layout, op->type->name, 0, op->idname, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS);
RNA_string_set(&props_ptr, "object", ob->id.name+2);
/* present the menu and be done... */

@ -349,8 +349,14 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
for(base= sce->base.first; base; base= base->next) {
if(base->object->id.name[2]=='p') {
if(ELEM4(base->object->type, OB_MESH, OB_CURVE, OB_SURF, OB_MBALL))
assign_material(base->object, mat, base->object->actcol);
if(ELEM4(base->object->type, OB_MESH, OB_CURVE, OB_SURF, OB_MBALL)) {
/* don't use assign_material, it changed mat->id.us, which shows in the UI */
Material ***matar= give_matarar(base->object);
int actcol= MAX2(base->object->actcol > 0, 1) - 1;
if(matar && actcol < base->object->totcol)
(*matar)[actcol]= mat;
}
}
}
}

@ -211,7 +211,7 @@ static void nla_panel_animdata (const bContext *C, Panel *pa)
/* Active Action Properties ------------------------------------- */
/* action */
row= uiLayoutRow(layout, 1);
uiTemplateID(row, (bContext *)C, &adt_ptr, "action", NULL, NULL/*"ACT_OT_new", "ACT_OT_unlink"*/); // XXX: need to make these operators
uiTemplateID(row, (bContext *)C, &adt_ptr, "action", NULL /*"ACT_OT_new"*/, NULL, NULL /*"ACT_OT_unlink"*/); // XXX: need to make these operators
/* extrapolation */
row= uiLayoutRow(layout, 1);

@ -83,8 +83,6 @@ typedef struct FlattenString {
int flatten_string(struct SpaceText *st, FlattenString *fs, char *in);
void flatten_string_free(FlattenString *fs);
void unlink_text(struct Text *text);
int wrap_width(struct SpaceText *st, struct ARegion *ar);
void wrap_offset(struct SpaceText *st, struct ARegion *ar, struct TextLine *linein, int cursin, int *offl, int *offc);

@ -273,48 +273,9 @@ void TEXT_OT_reload(wmOperatorType *ot)
/******************* delete operator *********************/
static void text_unlink(Main *bmain, Text *text)
{
bScreen *scr;
ScrArea *area;
SpaceLink *sl;
/* XXX this ifdef is in fact dangerous, if python is
* disabled it will leave invalid pointers in files! */
#ifndef DISABLE_PYTHON
// XXX BPY_free_pyconstraint_links(text);
// XXX free_text_controllers(text);
// XXX free_dome_warp_text(text);
/* equivalently for pynodes: */
if(0) // XXX nodeDynamicUnlinkText ((ID*)text))
; // XXX notifier: allqueue(REDRAWNODE, 0);
#endif
for(scr= bmain->screen.first; scr; scr= scr->id.next) {
for(area= scr->areabase.first; area; area= area->next) {
for(sl= area->spacedata.first; sl; sl= sl->next) {
if(sl->spacetype==SPACE_TEXT) {
SpaceText *st= (SpaceText*) sl;
if(st->text==text) {
st->text= NULL;
st->top= 0;
if(st==area->spacedata.first)
ED_area_tag_redraw(area);
}
}
}
}
}
free_libblock(&bmain->text, text);
}
static int unlink_exec(bContext *C, wmOperator *op)
{
Main *bmain= CTX_data_main(C);
SpaceText *st= CTX_wm_space_text(C);
Text *text= CTX_data_edit_text(C);
@ -330,7 +291,8 @@ static int unlink_exec(bContext *C, wmOperator *op)
}
}
text_unlink(CTX_data_main(C), text);
unlink_text(bmain, text);
free_libblock(&bmain->text, text);
WM_event_add_notifier(C, NC_TEXT|NA_REMOVED, text);
return OPERATOR_FINISHED;

@ -247,6 +247,7 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
api_ui_item_rna_common(func);
RNA_def_string(func, "new", "", 0, "", "Operator identifier to create a new ID block.");
RNA_def_string(func, "open", "", 0, "", "Operator identifier to open a file for creating a new ID block.");
RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block.");
func= RNA_def_function(srna, "template_modifier", "uiTemplateModifier");