Initial revision
[blender.git] / source / blender / blenkernel / intern / library.c
1
2 /*  library.c   aug 94     MIXED MODEL
3  * 
4  *  jan 95
5  * 
6  *  afhandeling ID's en libraries
7  *  allocceren en vrijgeven alle library data
8  * 
9  * $Id$
10  *
11  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version. The Blender
17  * Foundation also sells licenses for use in proprietary software under
18  * the Blender License.  See http://www.blender.org/BL/ for information
19  * about this.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software Foundation,
28  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
29  *
30  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
31  * All rights reserved.
32  *
33  * The Original Code is: all of this file.
34  *
35  * Contributor(s): none yet.
36  *
37  * ***** END GPL/BL DUAL LICENSE BLOCK *****
38  */
39 #include <stdio.h>
40 #include <ctype.h>
41 #include <string.h>
42 #include <stdlib.h>
43
44 #ifdef WIN32
45 #include "BLI_winstuff.h"
46 #endif
47
48 #include "MEM_guardedalloc.h"
49
50 /* all types are needed here, in order to do memory operations */
51 #include "DNA_ID.h"
52 #include "DNA_listBase.h"
53 #include "DNA_scene_types.h"
54 #include "DNA_object_types.h"
55 #include "DNA_mesh_types.h"
56 #include "DNA_lattice_types.h"
57 #include "DNA_curve_types.h"
58 #include "DNA_meta_types.h"
59 #include "DNA_material_types.h"
60 #include "DNA_texture_types.h"
61 #include "DNA_ika_types.h"
62 #include "DNA_image_types.h"
63 #include "DNA_wave_types.h"
64 #include "DNA_lamp_types.h"
65 #include "DNA_camera_types.h"
66 #include "DNA_ipo_types.h"
67 #include "DNA_key_types.h"
68 #include "DNA_world_types.h"
69 #include "DNA_screen_types.h"
70 #include "DNA_vfont_types.h"
71 #include "DNA_text_types.h"
72 #include "DNA_sound_types.h"
73 #include "DNA_group_types.h"
74 #include "DNA_armature_types.h"
75 #include "DNA_action_types.h"
76
77 #include "BLI_blenlib.h"
78 #include "BLI_dynstr.h"
79
80 #include "BKE_bad_level_calls.h"
81 #include "BKE_library.h"
82 #include "BKE_main.h"
83 #include "BKE_global.h"
84 #include "BKE_sound.h"
85 #include "BKE_object.h"
86 #include "BKE_screen.h"
87 #include "BKE_mesh.h"
88 #include "BKE_material.h"
89 #include "BKE_curve.h"
90 #include "BKE_mball.h"
91  #include "BKE_text.h"
92 #include "BKE_texture.h"
93 #include "BKE_scene.h"
94 #include "BKE_image.h"
95 #include "BKE_ika.h"
96 #include "BKE_ipo.h"
97 #include "BKE_key.h"
98 #include "BKE_world.h"
99 #include "BKE_font.h"
100 #include "BKE_group.h"
101 #include "BKE_lattice.h"
102 #include "BKE_armature.h"
103 #include "BKE_action.h"
104
105 #define MAX_IDPUP               30      /* was 24 */
106 #define MAX_LIBARRAY    100 /* was 30 */
107
108 /* ************* ALGEMEEN ************************ */
109
110 void id_lib_extern(ID *id)
111 {
112         if(id) {
113                 if(id->flag & LIB_INDIRECT) {
114                         id->flag -= LIB_INDIRECT;
115                         id->flag |= LIB_EXTERN;
116                 }
117         }
118 }
119
120 void id_us_plus(ID *id)
121 {
122         if(id) {
123                 id->us++;
124                 if(id->flag & LIB_INDIRECT) {
125                         id->flag -= LIB_INDIRECT;
126                         id->flag |= LIB_EXTERN;
127                 }
128         }
129 }
130
131 ListBase *wich_libbase(Main *mainlib, short type)
132 {
133         switch( type ) {
134                 case ID_SCE:
135                         return &(mainlib->scene);
136                 case ID_LI:
137                         return &(mainlib->library);
138                 case ID_OB:
139                         return &(mainlib->object);
140                 case ID_ME:
141                         return &(mainlib->mesh);
142                 case ID_CU:
143                         return &(mainlib->curve);
144                 case ID_MB:
145                         return &(mainlib->mball);
146                 case ID_MA:
147                         return &(mainlib->mat);
148                 case ID_TE:
149                         return &(mainlib->tex);
150                 case ID_IM:
151                         return &(mainlib->image);
152                 case ID_IK:
153                         return &(mainlib->ika);
154                 case ID_WV:
155                         return &(mainlib->wave);
156                 case ID_LT:
157                         return &(mainlib->latt);
158                 case ID_LA:
159                         return &(mainlib->lamp);
160                 case ID_CA:
161                         return &(mainlib->camera);
162                 case ID_IP:
163                         return &(mainlib->ipo);
164                 case ID_KE:
165                         return &(mainlib->key);
166                 case ID_WO:
167                         return &(mainlib->world);
168                 case ID_SCR:
169                         return &(mainlib->screen);
170                 case ID_VF:
171                         return &(mainlib->vfont);
172                 case ID_TXT:
173                         return &(mainlib->text);
174                 case ID_SO:
175                         return &(mainlib->sound);
176                 case ID_SAMPLE:
177                         /* declared as an external in sound.h !!! */
178                         return (samples);
179                 case ID_GR:
180                         return &(mainlib->group);
181                 case ID_AR:
182                         return &(mainlib->armature);
183                 case ID_AC:
184                         return &(mainlib->action);
185         }
186         return 0;
187 }
188
189 int set_listbasepointers(Main *main, ListBase **lb)
190 {
191         /* BACKWARDS! let op volgorde van vrijgeven! (mesh<->mat) */
192
193         lb[0]= &(main->ipo);
194         lb[1]= &(main->key);
195         lb[2]= &(main->image);
196         lb[3]= &(main->tex);
197         lb[4]= &(main->mat);
198         lb[5]= &(main->vfont);
199         
200         /* Important!: When adding a new object type,
201          * the specific data should be inserted here 
202          */
203
204         lb[6]= &(main->armature);
205         lb[7]= &(main->action);
206
207         lb[8]= &(main->mesh);
208         lb[9]= &(main->curve);
209         lb[10]= &(main->mball);
210         lb[11]= &(main->ika);
211         lb[12]= &(main->wave);
212         lb[13]= &(main->latt);
213         lb[14]= &(main->lamp);
214         lb[15]= &(main->camera);
215
216         lb[16]= &(main->world);
217         lb[17]= &(main->screen);
218         lb[18]= &(main->object);
219         lb[19]= &(main->scene);
220         lb[20]= &(main->library);
221         lb[21]= &(main->text);
222         lb[22]= &(main->sound);
223         lb[23]= &(main->group);
224
225         lb[24]= samples;
226         lb[25]= 0;
227         
228         return 25;
229 }
230
231 /* *********** ALLOC EN FREE *****************
232   
233 free_libblock(ListBase *lb, ID *id )
234         lijstbasis en datablok geven, alleen ID wordt uitgelezen
235
236 void *alloc_libblock(ListBase *lb, type, name)
237         hangt in lijst en geeft nieuw ID
238
239  ***************************** */
240
241 static ID *alloc_libblock_notest(short type)
242 {
243         ID *id= 0;
244         
245         switch( type ) {
246                 case ID_SCE:
247                         id= MEM_callocN(sizeof(Scene), "scene");
248                         break;
249                 case ID_LI:
250                         id= MEM_callocN(sizeof(Library), "library");
251                         break;
252                 case ID_OB:
253                         id= MEM_callocN(sizeof(Object), "object");
254                         break;
255                 case ID_ME:
256                         id= MEM_callocN(sizeof(Mesh), "mesh");
257                         break;
258                 case ID_CU:
259                         id= MEM_callocN(sizeof(Curve), "curve");
260                         break;
261                 case ID_MB:
262                         id= MEM_callocN(sizeof(MetaBall), "mball");
263                         break;
264                 case ID_MA:
265                         id= MEM_callocN(sizeof(Material), "mat");
266                         break;
267                 case ID_TE:
268                         id= MEM_callocN(sizeof(Tex), "tex");
269                         break;
270                 case ID_IM:
271                         id= MEM_callocN(sizeof(Image), "image");
272                         break;
273                 case ID_IK:
274                         id= MEM_callocN(sizeof(Ika), "ika");
275                         break;
276                 case ID_WV:
277                         id= MEM_callocN(sizeof(Wave), "wave");
278                         break;
279                 case ID_LT:
280                         id= MEM_callocN(sizeof(Lattice), "latt");
281                         break;
282                 case ID_LA:
283                         id= MEM_callocN(sizeof(Lamp), "lamp");
284                         break;
285                 case ID_CA:
286                         id= MEM_callocN(sizeof(Camera), "camera");
287                         break;
288                 case ID_IP:
289                         id= MEM_callocN(sizeof(Ipo), "ipo");
290                         break;
291                 case ID_KE:
292                         id= MEM_callocN(sizeof(Key), "key");
293                         break;
294                 case ID_WO:
295                         id= MEM_callocN(sizeof(World), "world");
296                         break;
297                 case ID_SCR:
298                         id= MEM_callocN(sizeof(bScreen), "screen");
299                         break;
300                 case ID_VF:
301                         id= MEM_callocN(sizeof(VFont), "vfont");
302                         break;
303                 case ID_TXT:
304                         id= MEM_callocN(sizeof(Text), "text");
305                         break;
306                 case ID_SO:
307                         id= MEM_callocN(sizeof(bSound), "sound");
308                         break;
309                 case ID_SAMPLE:
310                         id = MEM_callocN(sizeof(bSample), "sound");
311                         break;
312                 case ID_GR:
313                         id= MEM_callocN(sizeof(Group), "sound");
314                         break;
315                 case ID_AR:
316                         id = MEM_callocN(sizeof(bArmature), "armature");
317                         break;
318                 case ID_AC:
319                         id = MEM_callocN(sizeof(bAction), "action");
320                         break;
321         }
322         return id;
323 }
324
325 // used everywhere in blenkernel and text.c
326 void *alloc_libblock(ListBase *lb, short type, char *name)
327 {
328         ID *id= 0;
329         
330         id= alloc_libblock_notest(type);
331         if(id) {
332                 BLI_addtail(lb, id);
333                 id->us= 1;
334                 *( (short *)id->name )= type;
335                 new_id(lb, id, name);
336                 /* alfabetisch opnieuw invoegen: zit in new_id */
337         }
338         return id;
339 }
340
341 /* GS reads the memory pointed at in a specific ordering. There are,
342  * however two definitions for it. I have jotted them down here, both,
343  * but I think the first one is actually used. The thing is that
344  * big-endian systems might read this the wrong way round. OTOH, we
345  * constructed the IDs that are read out with this macro explicitly as
346  * well. I expect we'll sort it out soon... */
347
348 /* from blendef: */
349 #define GS(a)   (*((short *)(a)))
350
351 /* from misc_util: flip the bytes from x  */
352 /*#define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
353
354 // used everywhere in blenkernel and text.c
355 void *copy_libblock(void *rt)
356 {
357         ID *idn, *id;
358         ListBase *lb;
359         char *cp, *cpn;
360         int idn_len;
361         
362         id= rt;
363
364         lb= wich_libbase(G.main, GS(id->name));
365         idn= alloc_libblock(lb, GS(id->name), id->name+2);
366         
367         idn_len= MEM_allocN_len(idn);
368         if(idn_len - sizeof(ID) > 0) {
369                 cp= (char *)id;
370                 cpn= (char *)idn;
371                 memcpy(cpn+sizeof(ID), cp+sizeof(ID), idn_len - sizeof(ID));
372         }
373         
374         id->newid= idn;
375         idn->flag |= LIB_NEW;
376         
377         return idn;
378 }
379
380 static void free_library(Library *lib)
381 {
382     /* no freeing needed for libraries yet */
383 }
384
385 // used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c
386 void free_libblock(ListBase *lb, void *idv)
387 {
388         ID *id= idv;
389         
390         switch( GS(id->name) ) {        /* GetShort uit util.h */
391                 case ID_SCE:
392                         free_scene((Scene *)id);
393                         break;
394                 case ID_LI:
395                         free_library((Library *)id);
396                         break;
397                 case ID_OB:
398                         free_object((Object *)id);
399                         break;
400                 case ID_ME:
401                         free_mesh((Mesh *)id);
402                         break;
403                 case ID_CU:
404                         free_curve((Curve *)id);
405                         break;
406                 case ID_MB:
407                         free_mball((MetaBall *)id);
408                         break;
409                 case ID_MA:
410                         free_material((Material *)id);
411                         break;
412                 case ID_TE:
413                         free_texture((Tex *)id);
414                         break;
415                 case ID_IM:
416                         free_image((Image *)id);
417                         break;
418                 case ID_IK:
419                         free_ika((Ika *)id);
420                         break;
421                 case ID_WV:
422                         /* free_wave(id); */
423                         break;
424                 case ID_LT:
425                         free_lattice((Lattice *)id);
426                         break;
427                 case ID_LA:
428                         free_lamp((Lamp *)id);
429                         break;
430                 case ID_CA:
431 /*                      free_camera(id); */
432                         /* cast wasn't here before... spooky... */
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         /* ook aanroepen bij file inlezen, 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" of "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                                 
572                         if(id->next)
573                                 BLI_dynstr_append(pupds, "|");
574                 }
575         }
576 }
577
578         /* Silly routine, the only difference between the one
579          * above is that it only adds items with a matching
580          * blocktype... this should be unified somehow... - zr
581          */
582 static void IPOnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, short *nr, int blocktype)
583 {
584         ID *id;
585         int i, nids;
586         
587         for (id= lb->first, nids= 0; id; id= id->next) {
588                 Ipo *ipo= (Ipo*) id;
589                 
590                 if (ipo->blocktype==blocktype)
591                         nids++;
592         }
593         
594         if (nids>MAX_IDPUP) {
595                 BLI_dynstr_append(pupds, "DataBrowse %x-2");
596         } else {
597                 for (i=0, id= lb->first; id; id= id->next) {
598                         Ipo *ipo= (Ipo*) id;
599                         
600                         if (ipo->blocktype==blocktype) {
601                                 char buf[32];
602                         
603                                 if (id==link)
604                                         *nr= i+1;
605                                         
606                                 get_flags_for_id(id, buf);
607                                 
608                                 BLI_dynstr_append(pupds, buf);
609                                 BLI_dynstr_append(pupds, id->name+2);
610                                 
611                                 if(id->next)
612                                         BLI_dynstr_append(pupds, "|");
613                                 
614                                 i++;
615                         }
616                 }
617         }
618 }
619
620 // used by headerbuttons.c buttons.c editobject.c editseq.c
621 void IDnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb, ID *link, short *nr)
622 {
623         DynStr *pupds= BLI_dynstr_new();
624
625         if (title) {
626                 BLI_dynstr_append(pupds, title);
627                 BLI_dynstr_append(pupds, "%t|");
628         }
629         
630         IDnames_to_dyn_pupstring(pupds, lb, link, nr);
631         
632         if (extraops) {
633                 if (BLI_dynstr_get_len(pupds))
634                         BLI_dynstr_append(pupds, "|");
635                 BLI_dynstr_append(pupds, extraops);
636         }
637         
638         *str= BLI_dynstr_get_cstring(pupds);
639         BLI_dynstr_free(pupds);
640 }
641
642 // only used by headerbuttons.c
643 void IPOnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb, ID *link, short *nr, int blocktype)
644 {
645         DynStr *pupds= BLI_dynstr_new();
646         
647         if (title) {
648                 BLI_dynstr_append(pupds, title);
649                 BLI_dynstr_append(pupds, "%t|");
650         }
651         
652         IPOnames_to_dyn_pupstring(pupds, lb, link, nr, blocktype);
653         
654         if (extraops) {
655                 if (BLI_dynstr_get_len(pupds))
656                         BLI_dynstr_append(pupds, "|");
657                 BLI_dynstr_append(pupds, extraops);
658         }
659         
660         *str= BLI_dynstr_get_cstring(pupds);
661         BLI_dynstr_free(pupds);
662 }
663
664 // used by buttons.c library.c mball.c
665 void splitIDname(char *name, char *left, int *nr)
666 {
667         int a;
668         
669         *nr= 0;
670         strncpy(left, name, 21);
671         
672         a= strlen(name);
673         if(a>1 && name[a-1]=='.') return;
674         
675         while(a--) {
676                 if( name[a]=='.' ) {
677                         left[a]= 0;
678                         *nr= atol(name+a+1);
679                         return;
680                 }
681                 if( isdigit(name[a])==0 ) break;
682                 
683                 left[a]= 0;
684         }
685         strcpy(left, name);     
686 }
687
688 static void sort_alpha_id(ListBase *lb, ID *id)
689 {
690         ID *idtest;
691         
692         /* alfabetisch opnieuw invoegen */
693         if(lb->first!=lb->last) {
694                 BLI_remlink(lb, id);
695                 
696                 idtest= lb->first;
697                 while(idtest) {
698                         if(strcasecmp(idtest->name, id->name)>0 || idtest->lib) {
699                                 BLI_insertlinkbefore(lb, idtest, id);
700                                 break;
701                         }
702                         idtest= idtest->next;
703                 }
704                 /* als laatste */
705                 if(idtest==0) {
706                         BLI_addtail(lb, id);
707                 }
708         }
709         
710 }
711
712 int new_id(ListBase *lb, ID *id, char *tname)
713 /* alleen locale blokken: externe en indirekte hebben al een unieke ID */
714 /* return 1: nieuwe naam gemaakt */
715 {
716         ID *idtest;
717         int nr= 0, nrtest, maxtest=32, a;
718         char aname[32], *name, left[24], leftest[24], in_use[32];
719         
720         /* - naam splitsen
721          * - zoeken
722          */
723
724         if(id->lib) return 0;
725
726         if(tname==0) name= id->name+2;
727         else {
728                 /* tname can be const */
729                 strncpy(aname, tname, 21);
730                 name= aname;
731                 
732                 if( strlen(name) > 21 ) name[21]= 0;
733         }
734
735         if(lb==0) lb= wich_libbase(G.main, GS(id->name));
736
737         /* eerste fase: bestaat de id al? */
738         idtest= lb->first;
739         while(idtest) {
740         
741                 if(id!=idtest && idtest->lib==0) {
742                         
743                         /* niet alphabetic testen! */
744                         /* optim */
745                         if( idtest->name[2] == name[0] ) {
746                                 if(strcmp(name, idtest->name+2)==0) break;
747                         }
748                 }
749                 
750                 idtest= idtest->next;
751         }       
752
753         /* if there is no double return */
754         if(idtest==0) {
755                 strcpy(id->name+2, name);
756                 return 0;
757         }
758         
759         memset(in_use, 0, maxtest);
760
761         splitIDname(name, left, &nr);
762         if(nr>999 && strlen(left)>16) left[16]= 0;
763         else if(strlen(left)>17) left[17]= 0;
764
765
766         idtest= lb->first;
767         while(idtest) {
768         
769                 if(id!=idtest && idtest->lib==0) {
770                         
771                         splitIDname(idtest->name+2, leftest, &nrtest);
772                         if(strcmp(left, leftest)==0) {
773                                 
774                                 if(nrtest<maxtest) in_use[nrtest]= 1;
775                                 if(nr <= nrtest) nr= nrtest+1;
776                         }
777                 }
778                 
779                 idtest= idtest->next;
780         }
781         
782         for(a=0; a<maxtest; a++) {
783                 if(a>=nr) break;
784                 if( in_use[a]==0 ) {
785                         nr= a;
786                         break;
787                 }
788         }
789         
790         if(nr==0) sprintf(id->name+2, "%s", left);
791         else {
792                 if (nr >= 1000 && strlen(left) > 16) {
793                         // this would overflow name buffer
794                         left[16]= 0;
795                         return (new_id(lb, id, left));
796                 }
797                 /* this format specifier is fucked... */
798                 sprintf(id->name+2, "%s.%0.3d", left, nr);
799         }
800         
801         sort_alpha_id(lb, id);  
802
803         return 1;
804 }
805
806 // next to indirect usage in read/writefile also in editobject.c scene.c
807 void clear_id_newpoins()
808 {
809         ListBase *lbarray[MAX_LIBARRAY];
810         ID *id;
811         int a;
812
813         a= set_listbasepointers(G.main, lbarray);
814         while(a--) {
815                 id= lbarray[a]->first;
816                 while(id) {
817                         id->newid= 0;
818                         id->flag &= ~LIB_NEW;
819                         id= id->next;
820                 }
821         }
822 }
823
824 void all_local(void)
825 {
826         ListBase *lbarray[MAX_LIBARRAY], tempbase={0, 0};
827         ID *id, *idn;
828         int a;
829
830         a= set_listbasepointers(G.main, lbarray);
831         while(a--) {
832                 id= lbarray[a]->first;
833                 
834                 while(id) {
835                         id->newid= 0;
836                         id->flag &= ~(LIB_EXTERN|LIB_INDIRECT|LIB_NEW);
837                         
838                         idn= id->next;          /* id wordt mogelijk opnieuw ingevoegd */
839                         if(id->lib) {
840                                 id->lib= 0;
841                                 new_id(lbarray[a], id, 0);      /* new_id doet dit alleen bij dubbele namen */
842                                 sort_alpha_id(lbarray[a], id);
843                         }
844                         else {
845                                 /* patch: testen of de zaak wel alphabetisch is */
846 /*
847                                 if(idn) {
848                                         if(strcasecmp(id->name, idn->name)>0) {
849                                                 remlink(lbarray[a], id);
850                                                 addtail(&tempbase, id);
851                                         }
852                                         else if(id->prev) {
853                                                 idp= id->prev;
854                                                 if(strcasecmp(idp->name, id->name)>0) {
855                                                         remlink(lbarray[a], id);
856                                                         addtail(&tempbase, id);
857                                                 }
858                                         }
859                                 }
860 */                              
861                         }
862                         
863                         id= idn;
864                 }
865                 
866                 /* patch2: zorgen dat de zaak wel alphabetisch is */
867                 while( (id=tempbase.first) ) {
868                         BLI_remlink(&tempbase, id);
869                         BLI_addtail(lbarray[a], id);
870                         new_id(lbarray[a], id, 0);
871                 }
872         }
873 }
874
875
876 void test_idbutton(char *name)
877 {
878         /* vanuit buttons: als naam al bestaat: new_id aanroepen */
879         ListBase *lb;
880         ID *idtest;
881         
882
883         lb= wich_libbase(G.main, GS(name-2) );
884         if(lb==0) return;
885         
886         /* zoek welke id */
887         idtest= lb->first;
888         while(idtest) {
889                 if( strcmp(idtest->name+2, name)==0) break;
890                 idtest= idtest->next;
891         }
892
893         if(idtest) if( new_id(lb, idtest, name)==0 ) sort_alpha_id(lb, idtest);
894 }
895
896 void rename_id(ID *id, char *name)
897 {
898         ListBase *lb;
899         
900         strncpy(id->name+2, name, 21);
901         lb= wich_libbase(G.main, GS(id->name) );
902         
903         new_id(lb, id, name);                           
904 }
905