fb7e6ba8fede7ae260fcf0934fcfc5c3e78aac4d
[blender-staging.git] / source / blender / blenkernel / intern / library.c
1
2 /*  library.c 
3  * 
4  *  Contains management of ID's and libraries
5  *  allocate and free of all library data
6  * 
7  * $Id$
8  *
9  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version. The Blender
15  * Foundation also sells licenses for use in proprietary software under
16  * the Blender License.  See http://www.blender.org/BL/ for information
17  * about this.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software Foundation,
26  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  *
28  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
29  * All rights reserved.
30  *
31  * The Original Code is: all of this file.
32  *
33  * Contributor(s): none yet.
34  *
35  * ***** END GPL/BL DUAL LICENSE BLOCK *****
36  */
37 #include <stdio.h>
38 #include <ctype.h>
39 #include <string.h>
40 #include <stdlib.h>
41
42 #ifdef HAVE_CONFIG_H
43 #include <config.h>
44 #endif
45
46 #ifdef WIN32
47 #include "BLI_winstuff.h"
48 #endif
49
50 #include "MEM_guardedalloc.h"
51
52 /* all types are needed here, in order to do memory operations */
53 #include "DNA_ID.h"
54 #include "DNA_listBase.h"
55 #include "DNA_scene_types.h"
56 #include "DNA_object_types.h"
57 #include "DNA_mesh_types.h"
58 #include "DNA_lattice_types.h"
59 #include "DNA_curve_types.h"
60 #include "DNA_meta_types.h"
61 #include "DNA_material_types.h"
62 #include "DNA_texture_types.h"
63 #include "DNA_ika_types.h"
64 #include "DNA_image_types.h"
65 #include "DNA_wave_types.h"
66 #include "DNA_lamp_types.h"
67 #include "DNA_camera_types.h"
68 #include "DNA_ipo_types.h"
69 #include "DNA_key_types.h"
70 #include "DNA_world_types.h"
71 #include "DNA_screen_types.h"
72 #include "DNA_vfont_types.h"
73 #include "DNA_text_types.h"
74 #include "DNA_sound_types.h"
75 #include "DNA_group_types.h"
76 #include "DNA_armature_types.h"
77 #include "DNA_action_types.h"
78
79 #include "BLI_blenlib.h"
80 #include "BLI_dynstr.h"
81
82 #include "BKE_bad_level_calls.h"
83 #include "BKE_library.h"
84 #include "BKE_main.h"
85 #include "BKE_global.h"
86 #include "BKE_sound.h"
87 #include "BKE_object.h"
88 #include "BKE_screen.h"
89 #include "BKE_mesh.h"
90 #include "BKE_material.h"
91 #include "BKE_curve.h"
92 #include "BKE_mball.h"
93  #include "BKE_text.h"
94 #include "BKE_texture.h"
95 #include "BKE_scene.h"
96 #include "BKE_image.h"
97 #include "BKE_ika.h"
98 #include "BKE_ipo.h"
99 #include "BKE_key.h"
100 #include "BKE_world.h"
101 #include "BKE_font.h"
102 #include "BKE_group.h"
103 #include "BKE_lattice.h"
104 #include "BKE_armature.h"
105 #include "BKE_action.h"
106
107 #define MAX_IDPUP               30      /* was 24 */
108 #define MAX_LIBARRAY    100 /* was 30 */
109
110 /* ************* general ************************ */
111
112 void id_lib_extern(ID *id)
113 {
114         if(id) {
115                 if(id->flag & LIB_INDIRECT) {
116                         id->flag -= LIB_INDIRECT;
117                         id->flag |= LIB_EXTERN;
118                 }
119         }
120 }
121
122 void id_us_plus(ID *id)
123 {
124         if(id) {
125                 id->us++;
126                 if(id->flag & LIB_INDIRECT) {
127                         id->flag -= LIB_INDIRECT;
128                         id->flag |= LIB_EXTERN;
129                 }
130         }
131 }
132
133 ListBase *wich_libbase(Main *mainlib, short type)
134 {
135         switch( type ) {
136                 case ID_SCE:
137                         return &(mainlib->scene);
138                 case ID_LI:
139                         return &(mainlib->library);
140                 case ID_OB:
141                         return &(mainlib->object);
142                 case ID_ME:
143                         return &(mainlib->mesh);
144                 case ID_CU:
145                         return &(mainlib->curve);
146                 case ID_MB:
147                         return &(mainlib->mball);
148                 case ID_MA:
149                         return &(mainlib->mat);
150                 case ID_TE:
151                         return &(mainlib->tex);
152                 case ID_IM:
153                         return &(mainlib->image);
154                 case ID_IK:
155                         return &(mainlib->ika);
156                 case ID_WV:
157                         return &(mainlib->wave);
158                 case ID_LT:
159                         return &(mainlib->latt);
160                 case ID_LA:
161                         return &(mainlib->lamp);
162                 case ID_CA:
163                         return &(mainlib->camera);
164                 case ID_IP:
165                         return &(mainlib->ipo);
166                 case ID_KE:
167                         return &(mainlib->key);
168                 case ID_WO:
169                         return &(mainlib->world);
170                 case ID_SCR:
171                         return &(mainlib->screen);
172                 case ID_VF:
173                         return &(mainlib->vfont);
174                 case ID_TXT:
175                         return &(mainlib->text);
176                 case ID_SO:
177                         return &(mainlib->sound);
178                 case ID_SAMPLE:
179                         /* declared as an external in sound.h !!! */
180                         return (samples);
181                 case ID_GR:
182                         return &(mainlib->group);
183                 case ID_AR:
184                         return &(mainlib->armature);
185                 case ID_AC:
186                         return &(mainlib->action);
187         }
188         return 0;
189 }
190
191 int set_listbasepointers(Main *main, ListBase **lb)
192 {
193         /* BACKWARDS! also watch order of free-ing! (mesh<->mat) */
194
195         lb[0]= &(main->ipo);
196         lb[1]= &(main->key);
197         lb[2]= &(main->image);
198         lb[3]= &(main->tex);
199         lb[4]= &(main->mat);
200         lb[5]= &(main->vfont);
201         
202         /* Important!: When adding a new object type,
203          * the specific data should be inserted here 
204          */
205
206         lb[6]= &(main->armature);
207         lb[7]= &(main->action);
208
209         lb[8]= &(main->mesh);
210         lb[9]= &(main->curve);
211         lb[10]= &(main->mball);
212         lb[11]= &(main->ika);
213         lb[12]= &(main->wave);
214         lb[13]= &(main->latt);
215         lb[14]= &(main->lamp);
216         lb[15]= &(main->camera);
217
218         lb[16]= &(main->world);
219         lb[17]= &(main->screen);
220         lb[18]= &(main->object);
221         lb[19]= &(main->scene);
222         lb[20]= &(main->library);
223         lb[21]= &(main->text);
224         lb[22]= &(main->sound);
225         lb[23]= &(main->group);
226
227         lb[24]= samples;
228         lb[25]= 0;
229         
230         return 25;
231 }
232
233 /* *********** ALLOC AND FREE *****************
234   
235 free_libblock(ListBase *lb, ID *id )
236         provide a list-basis and datablock, but only ID is read
237
238 void *alloc_libblock(ListBase *lb, type, name)
239         inserts in list and returns a new ID
240
241  ***************************** */
242
243 static ID *alloc_libblock_notest(short type)
244 {
245         ID *id= 0;
246         
247         switch( type ) {
248                 case ID_SCE:
249                         id= MEM_callocN(sizeof(Scene), "scene");
250                         break;
251                 case ID_LI:
252                         id= MEM_callocN(sizeof(Library), "library");
253                         break;
254                 case ID_OB:
255                         id= MEM_callocN(sizeof(Object), "object");
256                         break;
257                 case ID_ME:
258                         id= MEM_callocN(sizeof(Mesh), "mesh");
259                         break;
260                 case ID_CU:
261                         id= MEM_callocN(sizeof(Curve), "curve");
262                         break;
263                 case ID_MB:
264                         id= MEM_callocN(sizeof(MetaBall), "mball");
265                         break;
266                 case ID_MA:
267                         id= MEM_callocN(sizeof(Material), "mat");
268                         break;
269                 case ID_TE:
270                         id= MEM_callocN(sizeof(Tex), "tex");
271                         break;
272                 case ID_IM:
273                         id= MEM_callocN(sizeof(Image), "image");
274                         break;
275                 case ID_IK:
276                         id= MEM_callocN(sizeof(Ika), "ika");
277                         break;
278                 case ID_WV:
279                         id= MEM_callocN(sizeof(Wave), "wave");
280                         break;
281                 case ID_LT:
282                         id= MEM_callocN(sizeof(Lattice), "latt");
283                         break;
284                 case ID_LA:
285                         id= MEM_callocN(sizeof(Lamp), "lamp");
286                         break;
287                 case ID_CA:
288                         id= MEM_callocN(sizeof(Camera), "camera");
289                         break;
290                 case ID_IP:
291                         id= MEM_callocN(sizeof(Ipo), "ipo");
292                         break;
293                 case ID_KE:
294                         id= MEM_callocN(sizeof(Key), "key");
295                         break;
296                 case ID_WO:
297                         id= MEM_callocN(sizeof(World), "world");
298                         break;
299                 case ID_SCR:
300                         id= MEM_callocN(sizeof(bScreen), "screen");
301                         break;
302                 case ID_VF:
303                         id= MEM_callocN(sizeof(VFont), "vfont");
304                         break;
305                 case ID_TXT:
306                         id= MEM_callocN(sizeof(Text), "text");
307                         break;
308                 case ID_SO:
309                         id= MEM_callocN(sizeof(bSound), "sound");
310                         break;
311                 case ID_SAMPLE:
312                         id = MEM_callocN(sizeof(bSample), "sound");
313                         break;
314                 case ID_GR:
315                         id= MEM_callocN(sizeof(Group), "sound");
316                         break;
317                 case ID_AR:
318                         id = MEM_callocN(sizeof(bArmature), "armature");
319                         break;
320                 case ID_AC:
321                         id = MEM_callocN(sizeof(bAction), "action");
322                         break;
323         }
324         return id;
325 }
326
327 // used everywhere in blenkernel and text.c
328 void *alloc_libblock(ListBase *lb, short type, char *name)
329 {
330         ID *id= 0;
331         
332         id= alloc_libblock_notest(type);
333         if(id) {
334                 BLI_addtail(lb, id);
335                 id->us= 1;
336                 *( (short *)id->name )= type;
337                 new_id(lb, id, name);
338                 /* alphabetic insterion: is in new_id */
339         }
340         return id;
341 }
342
343 /* GS reads the memory pointed at in a specific ordering. There are,
344  * however two definitions for it. I have jotted them down here, both,
345  * but I think the first one is actually used. The thing is that
346  * big-endian systems might read this the wrong way round. OTOH, we
347  * constructed the IDs that are read out with this macro explicitly as
348  * well. I expect we'll sort it out soon... */
349
350 /* from blendef: */
351 #define GS(a)   (*((short *)(a)))
352
353 /* from misc_util: flip the bytes from x  */
354 /*#define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
355
356 // used everywhere in blenkernel and text.c
357 void *copy_libblock(void *rt)
358 {
359         ID *idn, *id;
360         ListBase *lb;
361         char *cp, *cpn;
362         int idn_len;
363         
364         id= rt;
365
366         lb= wich_libbase(G.main, GS(id->name));
367         idn= alloc_libblock(lb, GS(id->name), id->name+2);
368         
369         idn_len= MEM_allocN_len(idn);
370         if(idn_len - sizeof(ID) > 0) {
371                 cp= (char *)id;
372                 cpn= (char *)idn;
373                 memcpy(cpn+sizeof(ID), cp+sizeof(ID), idn_len - sizeof(ID));
374         }
375         
376         id->newid= idn;
377         idn->flag |= LIB_NEW;
378         
379         return idn;
380 }
381
382 static void free_library(Library *lib)
383 {
384     /* no freeing needed for libraries yet */
385 }
386
387 // used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c
388 void free_libblock(ListBase *lb, void *idv)
389 {
390         ID *id= idv;
391         
392         switch( GS(id->name) ) {        /* GetShort from util.h */
393                 case ID_SCE:
394                         free_scene((Scene *)id);
395                         break;
396                 case ID_LI:
397                         free_library((Library *)id);
398                         break;
399                 case ID_OB:
400                         free_object((Object *)id);
401                         break;
402                 case ID_ME:
403                         free_mesh((Mesh *)id);
404                         break;
405                 case ID_CU:
406                         free_curve((Curve *)id);
407                         break;
408                 case ID_MB:
409                         free_mball((MetaBall *)id);
410                         break;
411                 case ID_MA:
412                         free_material((Material *)id);
413                         break;
414                 case ID_TE:
415                         free_texture((Tex *)id);
416                         break;
417                 case ID_IM:
418                         free_image((Image *)id);
419                         break;
420                 case ID_IK:
421                         free_ika((Ika *)id);
422                         break;
423                 case ID_WV:
424                         /* free_wave(id); */
425                         break;
426                 case ID_LT:
427                         free_lattice((Lattice *)id);
428                         break;
429                 case ID_LA:
430                         free_lamp((Lamp *)id);
431                         break;
432                 case ID_CA:
433                         free_camera((Camera*) id);
434                         break;
435                 case ID_IP:
436                         free_ipo((Ipo *)id);
437                         break;
438                 case ID_KE:
439                         free_key((Key *)id);
440                         break;
441                 case ID_WO:
442                         free_world((World *)id);
443                         break;
444                 case ID_SCR:
445                         free_screen((bScreen *)id);
446                         break;
447                 case ID_VF:
448                         free_vfont((VFont *)id);
449                         break;
450                 case ID_TXT:
451                         free_text((Text *)id);
452                         break;
453                 case ID_SO:
454                         sound_free_sound((bSound *)id);
455                         break;
456                 case ID_SAMPLE:
457                         sound_free_sample((bSample *)id);
458                         break;
459                 case ID_GR:
460                         free_group((Group *)id);
461                         break;
462                 case ID_AR:
463                         free_armature((bArmature *)id);
464                         break;
465                 case ID_AC:
466                         free_action((bAction *)id);
467                         break;
468         }
469
470         BLI_remlink(lb, id);
471         MEM_freeN(id);
472
473         /* should not be here!! this is an interface-thing */
474         allspace(OOPS_TEST, 0);
475 }
476
477 void free_libblock_us(ListBase *lb, void *idv)          /* test users */
478 {
479         ID *id= idv;
480         
481         id->us--;
482
483         if(id->us<0) {
484                 if(id->lib) printf("ERROR block %s %s users %d\n", id->lib->name, id->name, id->us);
485                 else printf("ERROR block %s users %d\n", id->name, id->us);
486         }
487         if(id->us==0) {
488                 if( GS(id->name)==ID_OB ) unlink_object((Object *)id);
489                 
490                 free_libblock(lb, id);
491         }
492 }
493
494
495 void free_main(Main *mainvar)
496 {
497         /* also call when reading a file, erase all, etc */
498         ListBase *lbarray[MAX_LIBARRAY];
499         int a;
500
501         a= set_listbasepointers(mainvar, lbarray);
502         while(a--) {
503                 ListBase *lb= lbarray[a];
504                 ID *id;
505                 
506                 while (id= lb->first) {
507                         free_libblock(lb, id);
508                 }
509         }
510
511         MEM_freeN(mainvar);
512 }
513
514 /* ***************** ID ************************ */
515
516 // only used in exotic.c
517 ID *find_id(char *type, char *name)             /* type: "OB" or "MA" etc */
518 {
519         ID *id;
520         ListBase *lb;
521         
522         lb= wich_libbase(G.main, GS(type));
523         
524         id= lb->first;
525         while(id) {
526                 if( strcmp(id->name+2, name)==0 ) return id;
527                 id= id->next;
528         }
529         return 0;
530 }
531
532 static void get_flags_for_id(ID *id, char *buf) {
533         int isfake= id->flag & LIB_FAKEUSER;
534
535                 /* Writeout the flags for the entry, note there
536                  * is a small hack that writes 5 spaces instead
537                  * of 4 if no flags are displayed... this makes
538                  * things usually line up ok - better would be
539                  * to have that explicit, oh well - zr
540                  */
541
542         if (id->us<0)
543                 sprintf(buf, "-1W ");
544         else if (!id->lib && !isfake && id->us)
545                 sprintf(buf, "     ");
546         else
547                 sprintf(buf, "%c%c%c ", id->lib?'L':' ', isfake?'F':' ', (id->us==0)?'O':' ');
548 }
549
550 static void IDnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, short *nr)
551 {
552         int i, nids= BLI_countlist(lb);
553                 
554         *nr= -1;
555         
556         if (nids>MAX_IDPUP) {
557                 BLI_dynstr_append(pupds, "DataBrowse %x-2");
558         } else {
559                 ID *id;
560                 
561                 for (i=0, id= lb->first; id; id= id->next, i++) {
562                         char buf[32];
563                         
564                         if (id==link)
565                                 *nr= i+1;
566                         
567                         get_flags_for_id(id, buf);
568                                 
569                         BLI_dynstr_append(pupds, buf);
570                         BLI_dynstr_append(pupds, id->name+2);
571                         sprintf(buf, "%%x%d", i+1);
572                         BLI_dynstr_append(pupds, buf);
573                         
574                         if(id->next)
575                                 BLI_dynstr_append(pupds, "|");
576                 }
577         }
578 }
579
580         /* Silly routine, the only difference between the one
581          * above is that it only adds items with a matching
582          * blocktype... this should be unified somehow... - zr
583          */
584 static void IPOnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, short *nr, int blocktype)
585 {
586         ID *id;
587         int i, nids;
588         
589         for (id= lb->first, nids= 0; id; id= id->next) {
590                 Ipo *ipo= (Ipo*) id;
591                 
592                 if (ipo->blocktype==blocktype)
593                         nids++;
594         }
595         
596         if (nids>MAX_IDPUP) {
597                 BLI_dynstr_append(pupds, "DataBrowse %x-2");
598         } else {
599                 for (i=0, id= lb->first; id; id= id->next) {
600                         Ipo *ipo= (Ipo*) id;
601                         
602                         if (ipo->blocktype==blocktype) {
603                                 char buf[32];
604                         
605                                 if (id==link)
606                                         *nr= i+1;
607                                         
608                                 get_flags_for_id(id, buf);
609                                 
610                                 BLI_dynstr_append(pupds, buf);
611                                 BLI_dynstr_append(pupds, id->name+2);
612                                 sprintf(buf, "%%x%d", i+1);
613                                 BLI_dynstr_append(pupds, buf);
614                                 
615                                 if(id->next)
616                                         BLI_dynstr_append(pupds, "|");
617                                 
618                                 i++;
619                         }
620                 }
621         }
622 }
623
624 // used by headerbuttons.c buttons.c editobject.c editseq.c
625 void IDnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb, ID *link, short *nr)
626 {
627         DynStr *pupds= BLI_dynstr_new();
628
629         if (title) {
630                 BLI_dynstr_append(pupds, title);
631                 BLI_dynstr_append(pupds, "%t|");
632         }
633         
634         if (extraops) {
635                 BLI_dynstr_append(pupds, extraops);
636                 if (BLI_dynstr_get_len(pupds))
637                         BLI_dynstr_append(pupds, "|");
638         }
639
640         IDnames_to_dyn_pupstring(pupds, lb, link, nr);
641         
642         *str= BLI_dynstr_get_cstring(pupds);
643         BLI_dynstr_free(pupds);
644 }
645
646 // only used by headerbuttons.c
647 void IPOnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb, ID *link, short *nr, int blocktype)
648 {
649         DynStr *pupds= BLI_dynstr_new();
650         
651         if (title) {
652                 BLI_dynstr_append(pupds, title);
653                 BLI_dynstr_append(pupds, "%t|");
654         }
655         
656         if (extraops) {
657                 BLI_dynstr_append(pupds, extraops);
658                 if (BLI_dynstr_get_len(pupds))
659                         BLI_dynstr_append(pupds, "|");
660         }
661
662         IPOnames_to_dyn_pupstring(pupds, lb, link, nr, blocktype);      
663         
664         *str= BLI_dynstr_get_cstring(pupds);
665         BLI_dynstr_free(pupds);
666 }
667
668 // used by buttons.c library.c mball.c
669 void splitIDname(char *name, char *left, int *nr)
670 {
671         int a;
672         
673         *nr= 0;
674         strncpy(left, name, 21);
675         
676         a= strlen(name);
677         if(a>1 && name[a-1]=='.') return;
678         
679         while(a--) {
680                 if( name[a]=='.' ) {
681                         left[a]= 0;
682                         *nr= atol(name+a+1);
683                         return;
684                 }
685                 if( isdigit(name[a])==0 ) break;
686                 
687                 left[a]= 0;
688         }
689         strcpy(left, name);     
690 }
691
692 static void sort_alpha_id(ListBase *lb, ID *id)
693 {
694         ID *idtest;
695         
696         /* insert alphabetically */
697         if(lb->first!=lb->last) {
698                 BLI_remlink(lb, id);
699                 
700                 idtest= lb->first;
701                 while(idtest) {
702                         if(strcasecmp(idtest->name, id->name)>0 || idtest->lib) {
703                                 BLI_insertlinkbefore(lb, idtest, id);
704                                 break;
705                         }
706                         idtest= idtest->next;
707                 }
708                 /* as last */
709                 if(idtest==0) {
710                         BLI_addtail(lb, id);
711                 }
712         }
713         
714 }
715
716 int new_id(ListBase *lb, ID *id, char *tname)
717 /* only for local blocks: external en indirect blocks already have a unique ID */
718 /* return 1: created a new name */
719 {
720         ID *idtest;
721         int nr= 0, nrtest, maxtest=32, a;
722         char aname[32], *name, left[24], leftest[24], in_use[32];
723         
724         /* - split name
725          * - search
726          */
727
728         if(id->lib) return 0;
729
730         if(tname==0) name= id->name+2;
731         else {
732                 /* tname can be const */
733                 strncpy(aname, tname, 21);
734                 name= aname;
735                 
736                 if( strlen(name) > 21 ) name[21]= 0;
737         }
738
739         if(lb==0) lb= wich_libbase(G.main, GS(id->name));
740
741         /* phase 1: id already exists? */
742         idtest= lb->first;
743         while(idtest) {
744         
745                 if(id!=idtest && idtest->lib==0) {
746                         
747                         /* do not test alphabetic! */
748                         /* optimized */
749                         if( idtest->name[2] == name[0] ) {
750                                 if(strcmp(name, idtest->name+2)==0) break;
751                         }
752                 }
753                 
754                 idtest= idtest->next;
755         }       
756
757         /* if there is no double return */
758         if(idtest==0) {
759                 strcpy(id->name+2, name);
760                 return 0;
761         }
762         
763         memset(in_use, 0, maxtest);
764
765         splitIDname(name, left, &nr);
766         if(nr>999 && strlen(left)>16) left[16]= 0;
767         else if(strlen(left)>17) left[17]= 0;
768
769
770         idtest= lb->first;
771         while(idtest) {
772         
773                 if(id!=idtest && idtest->lib==0) {
774                         
775                         splitIDname(idtest->name+2, leftest, &nrtest);
776                         if(strcmp(left, leftest)==0) {
777                                 
778                                 if(nrtest<maxtest) in_use[nrtest]= 1;
779                                 if(nr <= nrtest) nr= nrtest+1;
780                         }
781                 }
782                 
783                 idtest= idtest->next;
784         }
785         
786         for(a=0; a<maxtest; a++) {
787                 if(a>=nr) break;
788                 if( in_use[a]==0 ) {
789                         nr= a;
790                         break;
791                 }
792         }
793         
794         if(nr==0) sprintf(id->name+2, "%s", left);
795         else {
796                 if (nr >= 1000 && strlen(left) > 16) {
797                         // this would overflow name buffer
798                         left[16]= 0;
799                         return (new_id(lb, id, left));
800                 }
801                 /* this format specifier is from hell... */
802                 sprintf(id->name+2, "%s.%0.3d", left, nr);
803         }
804         
805         sort_alpha_id(lb, id);  
806
807         return 1;
808 }
809
810 // next to indirect usage in read/writefile also in editobject.c scene.c
811 void clear_id_newpoins()
812 {
813         ListBase *lbarray[MAX_LIBARRAY];
814         ID *id;
815         int a;
816
817         a= set_listbasepointers(G.main, lbarray);
818         while(a--) {
819                 id= lbarray[a]->first;
820                 while(id) {
821                         id->newid= 0;
822                         id->flag &= ~LIB_NEW;
823                         id= id->next;
824                 }
825         }
826 }
827
828 void all_local(void)
829 {
830         ListBase *lbarray[MAX_LIBARRAY], tempbase={0, 0};
831         ID *id, *idn;
832         int a;
833
834         a= set_listbasepointers(G.main, lbarray);
835         while(a--) {
836                 id= lbarray[a]->first;
837                 
838                 while(id) {
839                         id->newid= 0;
840                         id->flag &= ~(LIB_EXTERN|LIB_INDIRECT|LIB_NEW);
841                         
842                         idn= id->next;          /* id is possibly being inserted again */
843                         if(id->lib) {
844                                 id->lib= 0;
845                                 new_id(lbarray[a], id, 0);      /* new_id only does it with double names */
846                                 sort_alpha_id(lbarray[a], id);
847                         }
848                         else {
849                                 /* patch: check for alphabetic ordering */
850                                 /* has been removed... why!? (ton) */
851 /*
852                                 if(idn) {
853                                         if(strcasecmp(id->name, idn->name)>0) {
854                                                 remlink(lbarray[a], id);
855                                                 addtail(&tempbase, id);
856                                         }
857                                         else if(id->prev) {
858                                                 idp= id->prev;
859                                                 if(strcasecmp(idp->name, id->name)>0) {
860                                                         remlink(lbarray[a], id);
861                                                         addtail(&tempbase, id);
862                                                 }
863                                         }
864                                 }
865 */                              
866                         }
867                         
868                         id= idn;
869                 }
870                 
871                 /* patch2: make it aphabetically */
872                 while( (id=tempbase.first) ) {
873                         BLI_remlink(&tempbase, id);
874                         BLI_addtail(lbarray[a], id);
875                         new_id(lbarray[a], id, 0);
876                 }
877         }
878 }
879
880
881 void test_idbutton(char *name)
882 {
883         /* called from buttons: when name already exists: call new_id */
884         ListBase *lb;
885         ID *idtest;
886         
887
888         lb= wich_libbase(G.main, GS(name-2) );
889         if(lb==0) return;
890         
891         /* search for id */
892         idtest= lb->first;
893         while(idtest) {
894                 if( strcmp(idtest->name+2, name)==0) break;
895                 idtest= idtest->next;
896         }
897
898         if(idtest) if( new_id(lb, idtest, name)==0 ) sort_alpha_id(lb, idtest);
899 }
900
901 void rename_id(ID *id, char *name)
902 {
903         ListBase *lb;
904         
905         strncpy(id->name+2, name, 21);
906         lb= wich_libbase(G.main, GS(id->name) );
907         
908         new_id(lb, id, name);                           
909 }
910