From 5dd9f7635afeda66ca4475288b1eb7ad621486f4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 4 Sep 2009 21:02:43 +0000 Subject: 2.5 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. --- source/blender/blenkernel/BKE_armature.h | 1 - source/blender/blenkernel/BKE_group.h | 1 + source/blender/blenkernel/BKE_library.h | 3 + source/blender/blenkernel/BKE_sca.h | 1 - source/blender/blenkernel/BKE_scene.h | 2 - source/blender/blenkernel/BKE_text.h | 2 + source/blender/blenkernel/intern/group.c | 10 + source/blender/blenkernel/intern/library.c | 225 ++++++++++++++++++++- source/blender/blenkernel/intern/sca.c | 24 --- source/blender/blenkernel/intern/scene.c | 11 - source/blender/blenkernel/intern/text.c | 93 ++++++++- source/blender/editors/gpencil/gpencil_buttons.c | 2 +- source/blender/editors/include/UI_interface.h | 2 +- .../editors/interface/interface_templates.c | 112 ++++++++-- source/blender/editors/object/object_edit.c | 4 +- source/blender/editors/preview/previewrender.c | 10 +- source/blender/editors/space_nla/nla_buttons.c | 2 +- source/blender/editors/space_text/text_intern.h | 2 - source/blender/editors/space_text/text_ops.c | 44 +--- source/blender/makesrna/intern/rna_ui_api.c | 1 + 20 files changed, 436 insertions(+), 116 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 0595134f5c9..1cbb2331782 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -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); diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h index 35084aabadf..b66ddf13527 100644 --- a/source/blender/blenkernel/BKE_group.h +++ b/source/blender/blenkernel/BKE_group.h @@ -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); diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 4e7db115168..54722dac910 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -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); diff --git a/source/blender/blenkernel/BKE_sca.h b/source/blender/blenkernel/BKE_sca.h index 22c4f39148a..1b8e61f136f 100644 --- a/source/blender/blenkernel/BKE_sca.h +++ b/source/blender/blenkernel/BKE_sca.h @@ -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); diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 12a13a2b50c..686fc265de0 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -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 diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h index d288c0b6516..bd14053d121 100644 --- a/source/blender/blenkernel/BKE_text.h +++ b/source/blender/blenkernel/BKE_text.h @@ -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); diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index 6fffbd794ef..6bb47bc0f0f 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -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) { diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 3c8bf9200f8..f15552ab40c 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -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) diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index e4d73208c64..de2118af202 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -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) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 10f6a8cf47c..6f9ed3e0978 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -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; - } -} diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 8e3d59bbc58..dac426de4eb 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -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 */ /*****************************/ diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index 0d7cd263245..1036b4ccd8f 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -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"); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 0cb6964b39e..e2338078a8a 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -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); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index d253948e2e8..2b7d6f383bf 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -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); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 53882ad8424..0ae987f2308 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -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... */ diff --git a/source/blender/editors/preview/previewrender.c b/source/blender/editors/preview/previewrender.c index d17391811bb..714ebcef0fb 100644 --- a/source/blender/editors/preview/previewrender.c +++ b/source/blender/editors/preview/previewrender.c @@ -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; + } } } } diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index bbf1358a37c..8532d78aa06 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -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); diff --git a/source/blender/editors/space_text/text_intern.h b/source/blender/editors/space_text/text_intern.h index cb425274fc0..4847f2f0741 100644 --- a/source/blender/editors/space_text/text_intern.h +++ b/source/blender/editors/space_text/text_intern.h @@ -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); diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index a8ef72e3273..7751355a14d 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -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; diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 7fc2d75a708..20948843f8a 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -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"); -- cgit v1.2.3