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