Fix for [#20032] outliner cuts off long names after pasing them
authorMatt Ebb <matt@mke3.net>
Mon, 28 Dec 2009 01:31:47 +0000 (01:31 +0000)
committerMatt Ebb <matt@mke3.net>
Mon, 28 Dec 2009 01:31:47 +0000 (01:31 +0000)
The system that ensures unique ID names chopped off the end
of the name to add a number suffix (.001 or so) regardless of
whether it already had a number or not. In this particular case,
(no suffix number) it now just shaves off the last letter of the
name until it's unique.

I've been testing this patch here for a while, and seems to work
properly, if anyone would like to have a quick look over this
commit and doublecheck, that would be great too.

source/blender/blenkernel/intern/library.c

index a79c347242663ae12a415f0553226041e0f04ff0..a32746e3093c21bf3bb44cc48362d2ee9bf42e9e 100644 (file)
@@ -1033,6 +1033,28 @@ static void sort_alpha_id(ListBase *lb, ID *id)
        
 }
 
+/*
+ * Check to see if there is an ID with the same name as 'name'.
+ * Returns the ID if so, if not, returns NULL
+ */
+static ID *is_dupid(ListBase *lb, ID *id, char *name)
+{
+       ID *idtest=NULL;
+       
+       for( idtest = lb->first; idtest; idtest = idtest->next ) {
+               /* if idtest is not a lib */ 
+               if( id != idtest && idtest->lib == NULL ) {
+                       /* do not test alphabetic! */
+                       /* optimized */
+                       if( idtest->name[2] == name[0] ) {
+                               if(strcmp(name, idtest->name+2)==0) break;
+                       }
+               }
+       }
+       
+       return idtest;
+}
+
 /* 
  * Check to see if an ID name is already used, and find a new one if so.
  * Return 1 if created a new name (returned in name).
@@ -1056,16 +1078,7 @@ int check_for_dupid(ListBase *lb, ID *id, char *name)
        while (1) {
 
                /* phase 1: id already exists? */
-               for( idtest = lb->first; idtest; idtest = idtest->next ) {
-                               /* if idtest is not a lib */ 
-                       if( id != idtest && idtest->lib == NULL ) {
-                               /* do not test alphabetic! */
-                               /* optimized */
-                               if( idtest->name[2] == name[0] ) {
-                                       if(strcmp(name, idtest->name+2)==0) break;
-                               }
-                       }
-               }
+               idtest = is_dupid(lb, id, name);
 
                /* if there is no double, done */
                if( idtest == NULL ) return 0;
@@ -1104,18 +1117,30 @@ int check_for_dupid(ListBase *lb, ID *id, char *name)
                        }
                }
 
-               /* if non-numbered name was not in use, reuse it */
-               if(nr==0) strcpy( name, left );
-               else {
-                       if(nr > 999 && strlen(left) > 16) {
-                               /* this would overflow name buffer */
-                               left[16] = 0;
-                               strcpy( name, left );
-                               continue;
+               /* If the original name has no numeric suffix, 
+                * rather than just chopping and adding numbers, 
+                * shave off the end chars until we have a unique name */
+               if (nr==0) {
+                       int len = strlen(name)-1;
+                       idtest= is_dupid(lb, id, name);
+                       
+                       while (idtest && len> 1) {
+                               name[len--] = '\0';
+                               idtest= is_dupid(lb, id, name);
                        }
-                       /* this format specifier is from hell... */
-                       sprintf(name, "%s.%.3d", left, nr);
+                       if (idtest == NULL) return 1;
+                       /* otherwise just continue and use a number suffix */
                }
+               
+               if(nr > 999 && strlen(left) > 16) {
+                       /* this would overflow name buffer */
+                       left[16] = 0;
+                       strcpy( name, left );
+                       continue;
+               }
+               /* this format specifier is from hell... */
+               sprintf(name, "%s.%.3d", left, nr);
+
                return 1;
        }
 }