From aa03132bc30369dc310fdcebe0bf1d94bab1114f Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 20 Jan 2008 23:53:13 +0000 Subject: [Coder API's]: Added a "generic unique name-finding function". Basically, this is based on the behaviour of the unique_constraint_name (or equivilant) functions, which have traditionally been duplicated everytime a new datatype needed this. Currently, this is in use for the following things: * Constraints * Action/Bone Groups * Local Action Markers / PoseLib poses Usage Notes: * The file in which this is to be used should include the standard header file . This defines the offsetof() macro, which should be used to find the relative location of the "name" member of the structs * This function is only designed for names of up to 128 chars in length (Most names are at most 32. TimeMarkers are 64). If a longer string needs to be handled, the function will need to be modified accordingly. * defname is the default name that should be used in case one hasn't been specified already --- source/blender/blenkernel/intern/constraint.c | 51 +------------------ source/blender/blenlib/BLI_blenlib.h | 1 + source/blender/blenlib/intern/util.c | 73 +++++++++++++++++++++++++++ source/blender/src/buttons_editing.c | 23 ++++++++- source/blender/src/editaction.c | 9 +++- source/blender/src/poselib.c | 9 +++- 6 files changed, 112 insertions(+), 54 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 5e53f10db37..6300d882879 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -31,6 +31,7 @@ */ #include +#include #include #include @@ -226,55 +227,7 @@ void do_constraint_channels (ListBase *conbase, ListBase *chanbase, float ctime, /* Find the first available, non-duplicate name for a given constraint */ void unique_constraint_name (bConstraint *con, ListBase *list) { - bConstraint *curcon; - char tempname[64]; - int number = 1, exists = 0; - char *dot; - - /* See if we are given an empty string */ - if (con->name[0] == '\0') { - /* give it default name first */ - strcpy(con->name, "Const"); - } - - /* See if we even need to do this */ - if (list == NULL) - return; - - for (curcon = list->first; curcon; curcon=curcon->next) { - if (curcon != con) { - if (!strcmp(curcon->name, con->name)) { - exists = 1; - break; - } - } - } - - if (exists == 0) - return; - - /* Strip off the suffix */ - dot = strchr(con->name, '.'); - if (dot) - *dot=0; - - for (number = 1; number <= 999; number++) { - sprintf(tempname, "%s.%03d", con->name, number); - - exists = 0; - for (curcon=list->first; curcon; curcon=curcon->next) { - if (con != curcon) { - if (strcmp(curcon->name, tempname)==0) { - exists = 1; - break; - } - } - } - if (exists == 0) { - strcpy(con->name, tempname); - return; - } - } + BLI_uniquename(list, con, "Const", offsetof(bConstraint, name), 32); } /* ----------------- Evaluation Loop Preparation --------------- */ diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h index e149c92c72b..fed513d3279 100644 --- a/source/blender/blenlib/BLI_blenlib.h +++ b/source/blender/blenlib/BLI_blenlib.h @@ -107,6 +107,7 @@ int BLI_findindex(struct ListBase *listbase, void *vlink); void BLI_freelistN(struct ListBase *listbase); void BLI_addtail(struct ListBase *listbase, void *vlink); void BLI_remlink(struct ListBase *listbase, void *vlink); +void BLI_uniquename(struct ListBase *list, void *vlink, char defname[], short name_offs, short len); void BLI_newname(char * name, int add); int BLI_stringdec(char *string, char *kop, char *start, unsigned short *numlen); void BLI_stringenc(char *string, char *kop, char *start, unsigned short numlen, int pic); diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index d6f76fb9259..d0f58a50eb9 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -220,6 +220,79 @@ void BLI_newname(char *name, int add) BLI_stringenc(name, head, tail, digits, pic); } +/* little helper macro for BLI_uniquename */ +#ifndef GIVE_STRADDR + #define GIVE_STRADDR(data, offset) ( ((char *)data) + offset ) +#endif + +/* Generic function to set a unique name. It is only designed to be used in situations + * where the name is part of the struct, and also that the name is at most 128 chars long. + * + * For places where this is used, see constraint.c for example... + * + * name_offs: should be calculated using offsetof(structname, membername) macro from stddef.h + * len: maximum length of string (to prevent overflows, etc.) + * defname: the name that should be used by default if none is specified already + */ +void BLI_uniquename(ListBase *list, void *vlink, char defname[], short name_offs, short len) +{ + Link *link; + char tempname[128]; + int number = 1, exists = 0; + char *dot; + + /* Make sure length can be handled */ + if ((len < 0) || (len > 128)) + return; + + /* See if we are given an empty string */ + if (ELEM(NULL, vlink, defname)) + return; + + if (GIVE_STRADDR(vlink, name_offs) == '\0') { + /* give it default name first */ + BLI_strncpy(GIVE_STRADDR(vlink, name_offs), defname, len); + } + + /* See if we even need to do this */ + if (list == NULL) + return; + + for (link = list->first; link; link= link->next) { + if (link != vlink) { + if (!strcmp(GIVE_STRADDR(link, name_offs), GIVE_STRADDR(vlink, name_offs))) { + exists = 1; + break; + } + } + } + if (exists == 0) + return; + + /* Strip off the suffix */ + dot = strchr(GIVE_STRADDR(vlink, name_offs), '.'); + if (dot) + *dot=0; + + for (number = 1; number <= 999; number++) { + BLI_snprintf(tempname, 128, "%s.%03d", GIVE_STRADDR(vlink, name_offs), number); + + exists = 0; + for (link= list->first; link; link= link->next) { + if (vlink != link) { + if (!strcmp(GIVE_STRADDR(link, name_offs), tempname)) { + exists = 1; + break; + } + } + } + if (exists == 0) { + BLI_strncpy(GIVE_STRADDR(vlink, name_offs), tempname, len); + return; + } + } +} + void BLI_addhead(ListBase *listbase, void *vlink) { diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 732d690ae7d..377555597cf 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -3864,6 +3864,7 @@ void do_armbuts(unsigned short event) grp= MEM_callocN(sizeof(bActionGroup), "PoseGroup"); strcpy(grp->name, "Group"); BLI_addtail(&pose->agroups, grp); + BLI_uniquename(&pose->agroups, grp, "Group", offsetof(bActionGroup, name), 32); pose->active_group= BLI_countlist(&pose->agroups); @@ -5050,6 +5051,22 @@ char *get_vertexgroup_menustr(Object *ob) return menustr; } +static void verify_poselib_posename(void *arg1, void *arg2) +{ + bAction *act= (bAction *)arg1; + TimeMarker *marker= (TimeMarker *)arg2; + + BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64); +} + +static void verify_posegroup_groupname(void *arg1, void *arg2) +{ + bPose *pose= (bPose *)arg1; + bActionGroup *grp= (bActionGroup *)arg2; + + BLI_uniquename(&pose->agroups, grp, "Group", offsetof(bActionGroup, name), 32); +} + static void editing_panel_links(Object *ob) { uiBlock *block; @@ -5165,7 +5182,8 @@ static void editing_panel_links(Object *ob) if (act->active_marker) { TimeMarker *marker= poselib_get_active_pose(act); - uiDefBut(block, TEX, REDRAWBUTSEDIT,"", xco+18,85,160-18-20,20, marker->name, 0, 63, 0, 0, "Displays current Pose Library Pose name. Click to change."); + but= uiDefBut(block, TEX, REDRAWBUTSEDIT,"", xco+18,85,160-18-20,20, marker->name, 0, 63, 0, 0, "Displays current Pose Library Pose name. Click to change."); + uiButSetFunc(but, verify_poselib_posename, act, marker); uiDefIconBut(block, BUT, B_POSELIB_REMOVEP, VICON_X, xco+160-20, 85, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove this Pose Library Pose from Pose Library."); } } @@ -5198,7 +5216,8 @@ static void editing_panel_links(Object *ob) bActionGroup *grp= (bActionGroup *)BLI_findlink(&pose->agroups, pose->active_group-1); /* active group */ - uiDefBut(block, TEX, REDRAWBUTSEDIT,"", xco+18,85,140-18-20,20, grp->name, 0, 63, 0, 0, "Displays current Pose Group name. Click to change."); + but= uiDefBut(block, TEX, REDRAWBUTSEDIT,"", xco+18,85,140-18-20,20, grp->name, 0, 63, 0, 0, "Displays current Pose Group name. Click to change."); + uiButSetFunc(but, verify_posegroup_groupname, pose, grp); uiDefIconBut(block, BUT, B_POSEGRP_REMOVE, VICON_X, xco+140-20, 85, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove this Pose Group"); /* set custom color set */ diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index 45ae0a72ad1..cb436e8bff1 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -31,6 +31,7 @@ */ #include +#include #include #include "MEM_guardedalloc.h" @@ -947,6 +948,7 @@ void action_groups_group (short add_group) sprintf(agrp->name, "Group"); BLI_addtail(&act->groups, agrp); + BLI_uniquename(&act->groups, agrp, "Group", offsetof(bActionGroup, name), 32); set_active_actiongroup(act, agrp, 1); @@ -2140,6 +2142,7 @@ static void numbuts_action () } else if (agrp) { strcpy(agrp->name, str); + BLI_uniquename(&( ((bAction *)data)->groups ), agrp, "Group", offsetof(bActionGroup, name), 32); if (expand) agrp->flag |= AGRP_EXPANDED; else agrp->flag &= ~AGRP_EXPANDED; @@ -3724,6 +3727,9 @@ void action_add_localmarker (bAction *act, int frame) BLI_addtail(&act->markers, marker); } + /* validate the name */ + BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64); + /* sets the newly added marker as the active one */ action_set_activemarker(act, marker, 1); @@ -3758,8 +3764,9 @@ void action_rename_localmarker (bAction *act) if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0) return; - /* copy name */ + /* copy then validate name */ BLI_strncpy(marker->name, name, sizeof(marker->name)); + BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64); /* undo and update */ BIF_undo_push("Action Rename Marker"); diff --git a/source/blender/src/poselib.c b/source/blender/src/poselib.c index 441ba0eab52..44277e17804 100644 --- a/source/blender/src/poselib.c +++ b/source/blender/src/poselib.c @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -345,7 +346,7 @@ void poselib_add_current_pose (Object *ob, int val) /* get/initialise poselib */ act= poselib_validate(ob); - /* validate name and get frame */ + /* get frame */ frame= poselib_get_free_index(act); /* add pose to poselib - replaces any existing pose there */ @@ -363,6 +364,9 @@ void poselib_add_current_pose (Object *ob, int val) BLI_addtail(&act->markers, marker); } + + /* validate name */ + BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64); } /* loop through selected posechannels, keying their pose to the action */ @@ -504,8 +508,9 @@ void poselib_rename_pose (Object *ob) if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0) return; - /* copy name */ + /* copy name and validate it */ BLI_strncpy(marker->name, name, sizeof(marker->name)); + BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64); /* undo and update */ BIF_undo_push("PoseLib Rename Pose"); -- cgit v1.2.3