Merging r41597 through r41607 from trunk into soc-2011-tomato
[blender.git] / source / blender / blenkernel / intern / library.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenkernel/intern/library.c
29  *  \ingroup bke
30  */
31
32
33 /*
34  *  Contains management of ID's and libraries
35  *  allocate and free of all library data
36  * 
37  */
38
39
40 #include <stdio.h>
41 #include <ctype.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <stddef.h>
45 #include <assert.h>
46
47 #include "MEM_guardedalloc.h"
48
49 /* all types are needed here, in order to do memory operations */
50 #include "DNA_anim_types.h"
51 #include "DNA_armature_types.h"
52 #include "DNA_brush_types.h"
53 #include "DNA_camera_types.h"
54 #include "DNA_group_types.h"
55 #include "DNA_ipo_types.h"
56 #include "DNA_key_types.h"
57 #include "DNA_lamp_types.h"
58 #include "DNA_lattice_types.h"
59 #include "DNA_material_types.h"
60 #include "DNA_mesh_types.h"
61 #include "DNA_meta_types.h"
62 #include "DNA_nla_types.h"
63 #include "DNA_node_types.h"
64 #include "DNA_scene_types.h"
65 #include "DNA_screen_types.h"
66 #include "DNA_speaker_types.h"
67 #include "DNA_sound_types.h"
68 #include "DNA_text_types.h"
69 #include "DNA_vfont_types.h"
70 #include "DNA_windowmanager_types.h"
71 #include "DNA_world_types.h"
72 #include "DNA_gpencil_types.h"
73 #include "DNA_movieclip_types.h"
74
75 #include "BLI_blenlib.h"
76 #include "BLI_dynstr.h"
77 #include "BLI_utildefines.h"
78 #include "BLI_bpath.h"
79
80 #include "BKE_animsys.h"
81 #include "BKE_camera.h"
82 #include "BKE_context.h"
83 #include "BKE_lamp.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_mesh.h"
91 #include "BKE_material.h"
92 #include "BKE_curve.h"
93 #include "BKE_mball.h"
94 #include "BKE_text.h"
95 #include "BKE_texture.h"
96 #include "BKE_scene.h"
97 #include "BKE_icons.h"
98 #include "BKE_image.h"
99 #include "BKE_ipo.h"
100 #include "BKE_key.h"
101 #include "BKE_world.h"
102 #include "BKE_font.h"
103 #include "BKE_group.h"
104 #include "BKE_lattice.h"
105 #include "BKE_armature.h"
106 #include "BKE_action.h"
107 #include "BKE_node.h"
108 #include "BKE_brush.h"
109 #include "BKE_idprop.h"
110 #include "BKE_particle.h"
111 #include "BKE_gpencil.h"
112 #include "BKE_fcurve.h"
113 #include "BKE_speaker.h"
114 #include "BKE_utildefines.h"
115 #include "BKE_movieclip.h"
116
117 #include "RNA_access.h"
118
119 #ifdef WITH_PYTHON
120 #include "BPY_extern.h"
121 #endif
122
123 #define MAX_IDPUP               60      /* was 24 */
124
125 /* GS reads the memory pointed at in a specific ordering. 
126    only use this definition, makes little and big endian systems
127    work fine, in conjunction with MAKE_ID */
128
129 /* from blendef: */
130 #define GS(a)   (*((short *)(a)))
131
132 /* ************* general ************************ */
133
134
135 /* this has to be called from each make_local_* func, we could call
136  * from id_make_local() but then the make local functions would not be self
137  * contained.
138  * also note that the id _must_ have a library - campbell */
139 void BKE_id_lib_local_paths(Main *bmain, ID *id)
140 {
141         char *bpath_user_data[2]= {bmain->name, (id)->lib->filepath};
142
143         bpath_traverse_id(bmain, id,
144                                           bpath_relocate_visitor,
145                                           BPATH_TRAVERSE_SKIP_MULTIFILE,
146                                           bpath_user_data);
147 }
148
149 void id_lib_extern(ID *id)
150 {
151         if(id) {
152                 if(id->flag & LIB_INDIRECT) {
153                         id->flag -= LIB_INDIRECT;
154                         id->flag |= LIB_EXTERN;
155                 }
156         }
157 }
158
159 void id_us_plus(ID *id)
160 {
161         if(id) {
162                 id->us++;
163                 if(id->flag & LIB_INDIRECT) {
164                         id->flag -= LIB_INDIRECT;
165                         id->flag |= LIB_EXTERN;
166                 }
167         }
168 }
169
170 void id_us_min(ID *id)
171 {
172         if(id) {
173                 if(id->us<2 && (id->flag & LIB_FAKEUSER))
174                    id->us= 1;
175                 else if(id->us<=0)
176                         printf("ID user decrement error: %s \n", id->name);
177                 else
178                         id->us--;
179         }
180 }
181
182 int id_make_local(ID *id, int test)
183 {
184         if(id->flag & LIB_INDIRECT)
185                 return 0;
186
187         switch(GS(id->name)) {
188                 case ID_SCE:
189                         return 0; /* not implemented */
190                 case ID_LI:
191                         return 0; /* can't be linked */
192                 case ID_OB:
193                         if(!test) make_local_object((Object*)id);
194                         return 1;
195                 case ID_ME:
196                         if(!test) {
197                                 make_local_mesh((Mesh*)id);
198                                 make_local_key(((Mesh*)id)->key);
199                         }
200                         return 1;
201                 case ID_CU:
202                         if(!test) {
203                                 make_local_curve((Curve*)id);
204                                 make_local_key(((Curve*)id)->key);
205                         }
206                         return 1;
207                 case ID_MB:
208                         if(!test) make_local_mball((MetaBall*)id);
209                         return 1;
210                 case ID_MA:
211                         if(!test) make_local_material((Material*)id);
212                         return 1;
213                 case ID_TE:
214                         if(!test) make_local_texture((Tex*)id);
215                         return 1;
216                 case ID_IM:
217                         if(!test) make_local_image((Image*)id);
218                         return 1;
219                 case ID_LT:
220                         if(!test) {
221                                 make_local_lattice((Lattice*)id);
222                                 make_local_key(((Lattice*)id)->key);
223                         }
224                         return 1;
225                 case ID_LA:
226                         if(!test) make_local_lamp((Lamp*)id);
227                         return 1;
228                 case ID_CA:
229                         if(!test) make_local_camera((Camera*)id);
230                         return 1;
231                 case ID_SPK:
232                         if(!test) make_local_speaker((Speaker*)id);
233                         return 1;
234                 case ID_IP:
235                         return 0; /* deprecated */
236                 case ID_KE:
237                         if(!test) make_local_key((Key*)id);
238                         return 1;
239                 case ID_WO:
240                         if(!test) make_local_world((World*)id);
241                         return 1;
242                 case ID_SCR:
243                         return 0; /* can't be linked */
244                 case ID_VF:
245                         return 0; /* not implemented */
246                 case ID_TXT:
247                         return 0; /* not implemented */
248                 case ID_SCRIPT:
249                         return 0; /* deprecated */
250                 case ID_SO:
251                         return 0; /* not implemented */
252                 case ID_GR:
253                         return 0; /* not implemented */
254                 case ID_AR:
255                         if(!test) make_local_armature((bArmature*)id);
256                         return 1;
257                 case ID_AC:
258                         if(!test) make_local_action((bAction*)id);
259                         return 1;
260                 case ID_NT:
261                         return 0; /* not implemented */
262                 case ID_BR:
263                         if(!test) make_local_brush((Brush*)id);
264                         return 1;
265                 case ID_PA:
266                         if(!test) make_local_particlesettings((ParticleSettings*)id);
267                         return 1;
268                 case ID_WM:
269                         return 0; /* can't be linked */
270                 case ID_GD:
271                         return 0; /* not implemented */
272         }
273
274         return 0;
275 }
276
277 int id_copy(ID *id, ID **newid, int test)
278 {
279         if(!test) *newid= NULL;
280
281         /* conventions:
282          * - make shallow copy, only this ID block
283          * - id.us of the new ID is set to 1 */
284         switch(GS(id->name)) {
285                 case ID_SCE:
286                         return 0; /* can't be copied from here */
287                 case ID_LI:
288                         return 0; /* can't be copied from here */
289                 case ID_OB:
290                         if(!test) *newid= (ID*)copy_object((Object*)id);
291                         return 1;
292                 case ID_ME:
293                         if(!test) *newid= (ID*)copy_mesh((Mesh*)id);
294                         return 1;
295                 case ID_CU:
296                         if(!test) *newid= (ID*)copy_curve((Curve*)id);
297                         return 1;
298                 case ID_MB:
299                         if(!test) *newid= (ID*)copy_mball((MetaBall*)id);
300                         return 1;
301                 case ID_MA:
302                         if(!test) *newid= (ID*)copy_material((Material*)id);
303                         return 1;
304                 case ID_TE:
305                         if(!test) *newid= (ID*)copy_texture((Tex*)id);
306                         return 1;
307                 case ID_IM:
308                         if(!test) *newid= (ID*)copy_image((Image*)id);
309                         return 1;
310                 case ID_LT:
311                         if(!test) *newid= (ID*)copy_lattice((Lattice*)id);
312                         return 1;
313                 case ID_LA:
314                         if(!test) *newid= (ID*)copy_lamp((Lamp*)id);
315                         return 1;
316                 case ID_SPK:
317                         if(!test) *newid= (ID*)copy_speaker((Speaker*)id);
318                         return 1;
319                 case ID_CA:
320                         if(!test) *newid= (ID*)copy_camera((Camera*)id);
321                         return 1;
322                 case ID_IP:
323                         return 0; /* deprecated */
324                 case ID_KE:
325                         if(!test) *newid= (ID*)copy_key((Key*)id);
326                         return 1;
327                 case ID_WO:
328                         if(!test) *newid= (ID*)copy_world((World*)id);
329                         return 1;
330                 case ID_SCR:
331                         return 0; /* can't be copied from here */
332                 case ID_VF:
333                         return 0; /* not implemented */
334                 case ID_TXT:
335                         if(!test) *newid= (ID*)copy_text((Text*)id);
336                         return 1;
337                 case ID_SCRIPT:
338                         return 0; /* deprecated */
339                 case ID_SO:
340                         return 0; /* not implemented */
341                 case ID_GR:
342                         if(!test) *newid= (ID*)copy_group((Group*)id);
343                         return 1;
344                 case ID_AR:
345                         if(!test) *newid= (ID*)copy_armature((bArmature*)id);
346                         return 1;
347                 case ID_AC:
348                         if(!test) *newid= (ID*)copy_action((bAction*)id);
349                         return 1;
350                 case ID_NT:
351                         if(!test) *newid= (ID*)ntreeCopyTree((bNodeTree*)id);
352                         return 1;
353                 case ID_BR:
354                         if(!test) *newid= (ID*)copy_brush((Brush*)id);
355                         return 1;
356                 case ID_PA:
357                         if(!test) *newid= (ID*)psys_copy_settings((ParticleSettings*)id);
358                         return 1;
359                 case ID_WM:
360                         return 0; /* can't be copied from here */
361                 case ID_GD:
362                         return 0; /* not implemented */
363         }
364         
365         return 0;
366 }
367
368 int id_unlink(ID *id, int test)
369 {
370         Main *mainlib= G.main;
371         ListBase *lb;
372
373         switch(GS(id->name)) {
374                 case ID_TXT:
375                         if(test) return 1;
376                         unlink_text(mainlib, (Text*)id);
377                         break;
378                 case ID_GR:
379                         if(test) return 1;
380                         unlink_group((Group*)id);
381                         break;
382                 case ID_OB:
383                         if(test) return 1;
384                         unlink_object((Object*)id);
385                         break;
386         }
387
388         if(id->us == 0) {
389                 if(test) return 1;
390
391                 lb= which_libbase(mainlib, GS(id->name));
392                 free_libblock(lb, id);
393
394                 return 1;
395         }
396
397         return 0;
398 }
399
400 int id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
401 {
402         ID *newid = NULL;
403         PointerRNA idptr;
404         
405         if (id) {
406                 /* if property isn't editable, we're going to have an extra block hanging around until we save */
407                 if (RNA_property_editable(ptr, prop)) {
408                         if (id_copy(id, &newid, 0) && newid) {
409                                 /* copy animation actions too */
410                                 BKE_copy_animdata_id_action(id);
411                                 /* us is 1 by convention, but RNA_property_pointer_set
412                                    will also incremement it, so set it to zero */
413                                 newid->us= 0;
414                                 
415                                 /* assign copy */
416                                 RNA_id_pointer_create(newid, &idptr);
417                                 RNA_property_pointer_set(ptr, prop, idptr);
418                                 RNA_property_update(C, ptr, prop);
419                                 
420                                 return 1;
421                         }
422                 }
423         }
424         
425         return 0;
426 }
427
428 ListBase *which_libbase(Main *mainlib, short type)
429 {
430         switch( type ) {
431                 case ID_SCE:
432                         return &(mainlib->scene);
433                 case ID_LI:
434                         return &(mainlib->library);
435                 case ID_OB:
436                         return &(mainlib->object);
437                 case ID_ME:
438                         return &(mainlib->mesh);
439                 case ID_CU:
440                         return &(mainlib->curve);
441                 case ID_MB:
442                         return &(mainlib->mball);
443                 case ID_MA:
444                         return &(mainlib->mat);
445                 case ID_TE:
446                         return &(mainlib->tex);
447                 case ID_IM:
448                         return &(mainlib->image);
449                 case ID_LT:
450                         return &(mainlib->latt);
451                 case ID_LA:
452                         return &(mainlib->lamp);
453                 case ID_CA:
454                         return &(mainlib->camera);
455                 case ID_IP:
456                         return &(mainlib->ipo);
457                 case ID_KE:
458                         return &(mainlib->key);
459                 case ID_WO:
460                         return &(mainlib->world);
461                 case ID_SCR:
462                         return &(mainlib->screen);
463                 case ID_VF:
464                         return &(mainlib->vfont);
465                 case ID_TXT:
466                         return &(mainlib->text);
467                 case ID_SCRIPT:
468                         return &(mainlib->script);
469                 case ID_SPK:
470                         return &(mainlib->speaker);
471                 case ID_SO:
472                         return &(mainlib->sound);
473                 case ID_GR:
474                         return &(mainlib->group);
475                 case ID_AR:
476                         return &(mainlib->armature);
477                 case ID_AC:
478                         return &(mainlib->action);
479                 case ID_NT:
480                         return &(mainlib->nodetree);
481                 case ID_BR:
482                         return &(mainlib->brush);
483                 case ID_PA:
484                         return &(mainlib->particle);
485                 case ID_WM:
486                         return &(mainlib->wm);
487                 case ID_GD:
488                         return &(mainlib->gpencil);
489                 case ID_MC:
490                         return &(mainlib->movieclip);
491         }
492         return NULL;
493 }
494
495 /* Flag all ids in listbase */
496 void flag_listbase_ids(ListBase *lb, short flag, short value)
497 {
498         ID *id;
499         if (value) {
500                 for(id= lb->first; id; id= id->next) id->flag |= flag;
501         } else {
502                 flag = ~flag;
503                 for(id= lb->first; id; id= id->next) id->flag &= flag;
504         }
505 }
506
507 /* Flag all ids in listbase */
508 void flag_all_listbases_ids(short flag, short value)
509 {
510         ListBase *lbarray[MAX_LIBARRAY];
511         int a;
512         a= set_listbasepointers(G.main, lbarray);
513         while(a--)      flag_listbase_ids(lbarray[a], flag, value);
514 }
515
516 void recalc_all_library_objects(Main *main)
517 {
518         Object *ob;
519
520         /* flag for full recalc */
521         for(ob=main->object.first; ob; ob=ob->id.next)
522                 if(ob->id.lib)
523                         ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
524 }
525
526 /* note: MAX_LIBARRAY define should match this code */
527 int set_listbasepointers(Main *main, ListBase **lb)
528 {
529         int a = 0;
530
531         /* BACKWARDS! also watch order of free-ing! (mesh<->mat), first items freed last.
532          * This is important because freeing data decreases usercounts of other datablocks,
533          * if this data is its self freed it can crash. */
534         lb[a++]= &(main->ipo);
535         lb[a++]= &(main->action); // xxx moved here to avoid problems when freeing with animato (aligorith)
536         lb[a++]= &(main->key);
537         lb[a++]= &(main->gpencil); /* referenced by nodes, objects, view, scene etc, before to free after. */
538         lb[a++]= &(main->nodetree);
539         lb[a++]= &(main->image);
540         lb[a++]= &(main->tex);
541         lb[a++]= &(main->mat);
542         lb[a++]= &(main->vfont);
543         
544         /* Important!: When adding a new object type,
545          * the specific data should be inserted here 
546          */
547
548         lb[a++]= &(main->armature);
549
550         lb[a++]= &(main->mesh);
551         lb[a++]= &(main->curve);
552         lb[a++]= &(main->mball);
553
554         lb[a++]= &(main->latt);
555         lb[a++]= &(main->lamp);
556         lb[a++]= &(main->camera);
557
558         lb[a++]= &(main->text);
559         lb[a++]= &(main->sound);
560         lb[a++]= &(main->group);
561         lb[a++]= &(main->brush);
562         lb[a++]= &(main->script);
563         lb[a++]= &(main->particle);
564         lb[a++]= &(main->speaker);
565
566         lb[a++]= &(main->world);
567         lb[a++]= &(main->screen);
568         lb[a++]= &(main->object);
569         lb[a++]= &(main->scene);
570         lb[a++]= &(main->library);
571         lb[a++]= &(main->wm);
572         lb[a++]= &(main->movieclip);
573         
574         lb[a]= NULL;
575
576         return a;
577 }
578
579 /* *********** ALLOC AND FREE *****************
580   
581 free_libblock(ListBase *lb, ID *id )
582         provide a list-basis and datablock, but only ID is read
583
584 void *alloc_libblock(ListBase *lb, type, name)
585         inserts in list and returns a new ID
586
587  ***************************** */
588
589 static ID *alloc_libblock_notest(short type)
590 {
591         ID *id= NULL;
592         
593         switch( type ) {
594                 case ID_SCE:
595                         id= MEM_callocN(sizeof(Scene), "scene");
596                         break;
597                 case ID_LI:
598                         id= MEM_callocN(sizeof(Library), "library");
599                         break;
600                 case ID_OB:
601                         id= MEM_callocN(sizeof(Object), "object");
602                         break;
603                 case ID_ME:
604                         id= MEM_callocN(sizeof(Mesh), "mesh");
605                         break;
606                 case ID_CU:
607                         id= MEM_callocN(sizeof(Curve), "curve");
608                         break;
609                 case ID_MB:
610                         id= MEM_callocN(sizeof(MetaBall), "mball");
611                         break;
612                 case ID_MA:
613                         id= MEM_callocN(sizeof(Material), "mat");
614                         break;
615                 case ID_TE:
616                         id= MEM_callocN(sizeof(Tex), "tex");
617                         break;
618                 case ID_IM:
619                         id= MEM_callocN(sizeof(Image), "image");
620                         break;
621                 case ID_LT:
622                         id= MEM_callocN(sizeof(Lattice), "latt");
623                         break;
624                 case ID_LA:
625                         id= MEM_callocN(sizeof(Lamp), "lamp");
626                         break;
627                 case ID_CA:
628                         id= MEM_callocN(sizeof(Camera), "camera");
629                         break;
630                 case ID_IP:
631                         id= MEM_callocN(sizeof(Ipo), "ipo");
632                         break;
633                 case ID_KE:
634                         id= MEM_callocN(sizeof(Key), "key");
635                         break;
636                 case ID_WO:
637                         id= MEM_callocN(sizeof(World), "world");
638                         break;
639                 case ID_SCR:
640                         id= MEM_callocN(sizeof(bScreen), "screen");
641                         break;
642                 case ID_VF:
643                         id= MEM_callocN(sizeof(VFont), "vfont");
644                         break;
645                 case ID_TXT:
646                         id= MEM_callocN(sizeof(Text), "text");
647                         break;
648                 case ID_SCRIPT:
649                         //XXX id= MEM_callocN(sizeof(Script), "script");
650                         break;
651                 case ID_SPK:
652                         id= MEM_callocN(sizeof(Speaker), "speaker");
653                         break;
654                 case ID_SO:
655                         id= MEM_callocN(sizeof(bSound), "sound");
656                         break;
657                 case ID_GR:
658                         id= MEM_callocN(sizeof(Group), "group");
659                         break;
660                 case ID_AR:
661                         id = MEM_callocN(sizeof(bArmature), "armature");
662                         break;
663                 case ID_AC:
664                         id = MEM_callocN(sizeof(bAction), "action");
665                         break;
666                 case ID_NT:
667                         id = MEM_callocN(sizeof(bNodeTree), "nodetree");
668                         break;
669                 case ID_BR:
670                         id = MEM_callocN(sizeof(Brush), "brush");
671                         break;
672                 case ID_PA:
673                         id = MEM_callocN(sizeof(ParticleSettings), "ParticleSettings");
674                           break;
675                 case ID_WM:
676                         id = MEM_callocN(sizeof(wmWindowManager), "Window manager");
677                           break;
678                 case ID_GD:
679                         id = MEM_callocN(sizeof(bGPdata), "Grease Pencil");
680                         break;
681                 case ID_MC:
682                         id = MEM_callocN(sizeof(MovieClip), "Movie Clip");
683                         break;
684         }
685         return id;
686 }
687
688 /* used everywhere in blenkernel and text.c */
689 void *alloc_libblock(ListBase *lb, short type, const char *name)
690 {
691         ID *id= NULL;
692         
693         id= alloc_libblock_notest(type);
694         if(id) {
695                 BLI_addtail(lb, id);
696                 id->us= 1;
697                 id->icon_id = 0;
698                 *( (short *)id->name )= type;
699                 new_id(lb, id, name);
700                 /* alphabetic insterion: is in new_id */
701         }
702         return id;
703 }
704
705 /* by spec, animdata is first item after ID */
706 /* and, trust that BKE_animdata_from_id() will only find AnimData for valid ID-types */
707 static void id_copy_animdata(ID *id, const short do_action)
708 {
709         AnimData *adt= BKE_animdata_from_id(id);
710         
711         if (adt) {
712                 IdAdtTemplate *iat = (IdAdtTemplate *)id;
713                 iat->adt= BKE_copy_animdata(iat->adt, do_action); /* could be set to FALSE, need to investigate */
714         }
715 }
716
717 /* material nodes use this since they are not treated as libdata */
718 void copy_libblock_data(ID *id, const ID *id_from, const short do_action)
719 {
720         if (id_from->properties)
721                 id->properties = IDP_CopyProperty(id_from->properties);
722
723         /* the duplicate should get a copy of the animdata */
724         id_copy_animdata(id, do_action);
725 }
726
727 /* used everywhere in blenkernel */
728 void *copy_libblock(ID *id)
729 {
730         ID *idn;
731         ListBase *lb;
732         size_t idn_len;
733
734         lb= which_libbase(G.main, GS(id->name));
735         idn= alloc_libblock(lb, GS(id->name), id->name+2);
736
737         assert(idn != NULL);
738
739         idn_len= MEM_allocN_len(idn);
740         if((int)idn_len - (int)sizeof(ID) > 0) { /* signed to allow neg result */
741                 const char *cp= (const char *)id;
742                 char *cpn= (char *)idn;
743
744                 memcpy(cpn+sizeof(ID), cp+sizeof(ID), idn_len - sizeof(ID));
745         }
746         
747         id->newid= idn;
748         idn->flag |= LIB_NEW;
749
750         copy_libblock_data(idn, id, FALSE);
751         
752         return idn;
753 }
754
755 static void free_library(Library *UNUSED(lib))
756 {
757         /* no freeing needed for libraries yet */
758 }
759
760 static void (*free_windowmanager_cb)(bContext *, wmWindowManager *)= NULL;
761
762 void set_free_windowmanager_cb(void (*func)(bContext *C, wmWindowManager *) )
763 {
764         free_windowmanager_cb= func;
765 }
766
767 static void animdata_dtar_clear_cb(ID *UNUSED(id), AnimData *adt, void *userdata)
768 {
769         ChannelDriver *driver;
770         FCurve *fcu;
771
772         /* find the driver this belongs to and update it */
773         for (fcu=adt->drivers.first; fcu; fcu=fcu->next) {
774                 driver= fcu->driver;
775                 
776                 if (driver) {
777                         DriverVar *dvar;
778                         for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
779                                 DRIVER_TARGETS_USED_LOOPER(dvar) 
780                                 {
781                                         if (dtar->id == userdata)
782                                                 dtar->id= NULL;
783                                 }
784                                 DRIVER_TARGETS_LOOPER_END
785                         }
786                 }
787         }
788 }
789
790
791 /* used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c */
792 void free_libblock(ListBase *lb, void *idv)
793 {
794         ID *id= idv;
795
796 #ifdef WITH_PYTHON
797         BPY_id_release(id);
798 #endif
799
800         switch( GS(id->name) ) {        /* GetShort from util.h */
801                 case ID_SCE:
802                         free_scene((Scene *)id);
803                         break;
804                 case ID_LI:
805                         free_library((Library *)id);
806                         break;
807                 case ID_OB:
808                         free_object((Object *)id);
809                         break;
810                 case ID_ME:
811                         free_mesh((Mesh *)id);
812                         break;
813                 case ID_CU:
814                         free_curve((Curve *)id);
815                         break;
816                 case ID_MB:
817                         free_mball((MetaBall *)id);
818                         break;
819                 case ID_MA:
820                         free_material((Material *)id);
821                         break;
822                 case ID_TE:
823                         free_texture((Tex *)id);
824                         break;
825                 case ID_IM:
826                         free_image((Image *)id);
827                         break;
828                 case ID_LT:
829                         free_lattice((Lattice *)id);
830                         break;
831                 case ID_LA:
832                         free_lamp((Lamp *)id);
833                         break;
834                 case ID_CA:
835                         free_camera((Camera*) id);
836                         break;
837                 case ID_IP:
838                         free_ipo((Ipo *)id);
839                         break;
840                 case ID_KE:
841                         free_key((Key *)id);
842                         break;
843                 case ID_WO:
844                         free_world((World *)id);
845                         break;
846                 case ID_SCR:
847                         free_screen((bScreen *)id);
848                         break;
849                 case ID_VF:
850                         free_vfont((VFont *)id);
851                         break;
852                 case ID_TXT:
853                         free_text((Text *)id);
854                         break;
855                 case ID_SCRIPT:
856                         //XXX free_script((Script *)id);
857                         break;
858                 case ID_SPK:
859                         free_speaker((Speaker *)id);
860                         break;
861                 case ID_SO:
862                         sound_free((bSound*)id);
863                         break;
864                 case ID_GR:
865                         free_group_objects((Group *)id);
866                         break;
867                 case ID_AR:
868                         free_armature((bArmature *)id);
869                         break;
870                 case ID_AC:
871                         free_action((bAction *)id);
872                         break;
873                 case ID_NT:
874                         ntreeFreeTree((bNodeTree *)id);
875                         break;
876                 case ID_BR:
877                         free_brush((Brush *)id);
878                         break;
879                 case ID_PA:
880                         psys_free_settings((ParticleSettings *)id);
881                         break;
882                 case ID_WM:
883                         if(free_windowmanager_cb)
884                                 free_windowmanager_cb(NULL, (wmWindowManager *)id);
885                         break;
886                 case ID_GD:
887                         free_gpencil_data((bGPdata *)id);
888                         break;
889                 case ID_MC:
890                         free_movieclip((MovieClip *)id);
891                         break;
892         }
893
894         if (id->properties) {
895                 IDP_FreeProperty(id->properties);
896                 MEM_freeN(id->properties);
897         }
898
899         BLI_remlink(lb, id);
900
901         /* this ID may be a driver target! */
902         BKE_animdata_main_cb(G.main, animdata_dtar_clear_cb, (void *)id);
903
904         MEM_freeN(id);
905 }
906
907 void free_libblock_us(ListBase *lb, void *idv)          /* test users */
908 {
909         ID *id= idv;
910         
911         id->us--;
912
913         if(id->us<0) {
914                 if(id->lib) printf("ERROR block %s %s users %d\n", id->lib->name, id->name, id->us);
915                 else printf("ERROR block %s users %d\n", id->name, id->us);
916         }
917         if(id->us==0) {
918                 if( GS(id->name)==ID_OB ) unlink_object((Object *)id);
919                 
920                 free_libblock(lb, id);
921         }
922 }
923
924
925 void free_main(Main *mainvar)
926 {
927         /* also call when reading a file, erase all, etc */
928         ListBase *lbarray[MAX_LIBARRAY];
929         int a;
930
931         a= set_listbasepointers(mainvar, lbarray);
932         while(a--) {
933                 ListBase *lb= lbarray[a];
934                 ID *id;
935                 
936                 while ( (id= lb->first) ) {
937                         free_libblock(lb, id);
938                 }
939         }
940
941         MEM_freeN(mainvar);
942 }
943
944 /* ***************** ID ************************ */
945
946
947 ID *find_id(const char *type, const char *name)         /* type: "OB" or "MA" etc */
948 {
949         ListBase *lb= which_libbase(G.main, GS(type));
950         return BLI_findstring(lb, name, offsetof(ID, name) + 2);
951 }
952
953 static void get_flags_for_id(ID *id, char *buf) 
954 {
955         int isfake= id->flag & LIB_FAKEUSER;
956         int isnode=0;
957                 /* Writeout the flags for the entry, note there
958                  * is a small hack that writes 5 spaces instead
959                  * of 4 if no flags are displayed... this makes
960                  * things usually line up ok - better would be
961                  * to have that explicit, oh well - zr
962                  */
963
964         if(GS(id->name)==ID_MA)
965                 isnode= ((Material *)id)->use_nodes;
966         if(GS(id->name)==ID_TE)
967                 isnode= ((Tex *)id)->use_nodes;
968         
969         if (id->us<0)
970                 strcpy(buf, "-1W ");
971         else if (!id->lib && !isfake && id->us && !isnode)
972                 strcpy(buf, "     ");
973         else if(isnode)
974                 sprintf(buf, "%c%cN%c ", id->lib?'L':' ', isfake?'F':' ', (id->us==0)?'O':' ');
975         else
976                 sprintf(buf, "%c%c%c ", id->lib?'L':' ', isfake?'F':' ', (id->us==0)?'O':' ');
977 }
978
979 #define IDPUP_NO_VIEWER 1
980
981 static void IDnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, short *nr, int hideflag)
982 {
983         int i, nids= BLI_countlist(lb);
984                 
985         if (nr) *nr= -1;
986         
987         if (nr && nids>MAX_IDPUP) {
988                 BLI_dynstr_append(pupds, "DataBrowse %x-2");
989                 *nr= -2;
990         } else {
991                 ID *id;
992                 
993                 for (i=0, id= lb->first; id; id= id->next, i++) {
994                         char buf[32];
995                         
996                         if (nr && id==link) *nr= i+1;
997
998                         if (U.uiflag & USER_HIDE_DOT && id->name[2]=='.')
999                                 continue;
1000                         if (hideflag & IDPUP_NO_VIEWER)
1001                                 if (GS(id->name)==ID_IM)
1002                                         if ( ((Image *)id)->source==IMA_SRC_VIEWER )
1003                                                 continue;
1004                         
1005                         get_flags_for_id(id, buf);
1006                                 
1007                         BLI_dynstr_append(pupds, buf);
1008                         BLI_dynstr_append(pupds, id->name+2);
1009                         BLI_snprintf(buf, sizeof(buf), "%%x%d", i+1);
1010                         BLI_dynstr_append(pupds, buf);
1011                         
1012                         /* icon */
1013                         switch(GS(id->name))
1014                         {
1015                         case ID_MA: /* fall through */
1016                         case ID_TE: /* fall through */
1017                         case ID_IM: /* fall through */
1018                         case ID_WO: /* fall through */
1019                         case ID_LA: /* fall through */
1020                                 BLI_snprintf(buf, sizeof(buf), "%%i%d", BKE_icon_getid(id) );
1021                                 BLI_dynstr_append(pupds, buf);
1022                                 break;
1023                         default:
1024                                 break;
1025                         }
1026                         
1027                         if(id->next)
1028                                 BLI_dynstr_append(pupds, "|");
1029                 }
1030         }
1031 }
1032
1033
1034 /* used by headerbuttons.c buttons.c editobject.c editseq.c */
1035 /* if nr==NULL no MAX_IDPUP, this for non-header browsing */
1036 void IDnames_to_pupstring(const char **str, const char *title, const char *extraops, ListBase *lb, ID *link, short *nr)
1037 {
1038         DynStr *pupds= BLI_dynstr_new();
1039
1040         if (title) {
1041                 BLI_dynstr_append(pupds, title);
1042                 BLI_dynstr_append(pupds, "%t|");
1043         }
1044         
1045         if (extraops) {
1046                 BLI_dynstr_append(pupds, extraops);
1047                 if (BLI_dynstr_get_len(pupds))
1048                         BLI_dynstr_append(pupds, "|");
1049         }
1050
1051         IDnames_to_dyn_pupstring(pupds, lb, link, nr, 0);
1052         
1053         *str= BLI_dynstr_get_cstring(pupds);
1054         BLI_dynstr_free(pupds);
1055 }
1056
1057 /* skips viewer images */
1058 void IMAnames_to_pupstring(const char **str, const char *title, const char *extraops, ListBase *lb, ID *link, short *nr)
1059 {
1060         DynStr *pupds= BLI_dynstr_new();
1061         
1062         if (title) {
1063                 BLI_dynstr_append(pupds, title);
1064                 BLI_dynstr_append(pupds, "%t|");
1065         }
1066         
1067         if (extraops) {
1068                 BLI_dynstr_append(pupds, extraops);
1069                 if (BLI_dynstr_get_len(pupds))
1070                         BLI_dynstr_append(pupds, "|");
1071         }
1072         
1073         IDnames_to_dyn_pupstring(pupds, lb, link, nr, IDPUP_NO_VIEWER);
1074         
1075         *str= BLI_dynstr_get_cstring(pupds);
1076         BLI_dynstr_free(pupds);
1077 }
1078
1079 static void sort_alpha_id(ListBase *lb, ID *id)
1080 {
1081         ID *idtest;
1082         
1083         /* insert alphabetically */
1084         if(lb->first!=lb->last) {
1085                 BLI_remlink(lb, id);
1086                 
1087                 idtest= lb->first;
1088                 while(idtest) {
1089                         if(BLI_strcasecmp(idtest->name, id->name)>0 || idtest->lib) {
1090                                 BLI_insertlinkbefore(lb, idtest, id);
1091                                 break;
1092                         }
1093                         idtest= idtest->next;
1094                 }
1095                 /* as last */
1096                 if(idtest==NULL) {
1097                         BLI_addtail(lb, id);
1098                 }
1099         }
1100         
1101 }
1102
1103 /*
1104  * Check to see if there is an ID with the same name as 'name'.
1105  * Returns the ID if so, if not, returns NULL
1106  */
1107 static ID *is_dupid(ListBase *lb, ID *id, const char *name)
1108 {
1109         ID *idtest=NULL;
1110         
1111         for( idtest = lb->first; idtest; idtest = idtest->next ) {
1112                 /* if idtest is not a lib */ 
1113                 if( id != idtest && idtest->lib == NULL ) {
1114                         /* do not test alphabetic! */
1115                         /* optimized */
1116                         if( idtest->name[2] == name[0] ) {
1117                                 if(strcmp(name, idtest->name+2)==0) break;
1118                         }
1119                 }
1120         }
1121         
1122         return idtest;
1123 }
1124
1125 /* 
1126  * Check to see if an ID name is already used, and find a new one if so.
1127  * Return 1 if created a new name (returned in name).
1128  *
1129  * Normally the ID that's being check is already in the ListBase, so ID *id
1130  * points at the new entry.  The Python Library module needs to know what
1131  * the name of a datablock will be before it is appended; in this case ID *id
1132  * id is NULL;
1133  */
1134
1135 static int check_for_dupid(ListBase *lb, ID *id, char *name)
1136 {
1137         ID *idtest;
1138         int nr= 0, nrtest, a, left_len;
1139         char left[32], leftest[32], in_use[32];
1140
1141         /* make sure input name is terminated properly */
1142         /* if( strlen(name) > 21 ) name[21]= 0; */
1143         /* removed since this is only ever called from one place - campbell */
1144
1145         while (1) {
1146
1147                 /* phase 1: id already exists? */
1148                 idtest = is_dupid(lb, id, name);
1149
1150                 /* if there is no double, done */
1151                 if( idtest == NULL ) return 0;
1152
1153                 /* we have a dup; need to make a new name */
1154                 /* quick check so we can reuse one of first 32 ids if vacant */
1155                 memset(in_use, 0, sizeof(in_use));
1156
1157                 /* get name portion, number portion ("name.number") */
1158                 left_len= BLI_split_name_num(left, &nr, name, '.');
1159
1160                 /* if new name will be too long, truncate it */
1161                 if(nr > 999 && left_len > 16) {
1162                         left[16]= 0;
1163                         left_len= 16;
1164                 }
1165                 else if(left_len > 17) {
1166                         left[17]= 0;
1167                         left_len= 17;
1168                 }
1169
1170                 for(idtest= lb->first; idtest; idtest= idtest->next) {
1171                         if(             (id != idtest) &&
1172                                         (idtest->lib == NULL) &&
1173                                         (*name == *(idtest->name+2)) &&
1174                                         (strncmp(name, idtest->name+2, left_len)==0) &&
1175                                         (BLI_split_name_num(leftest, &nrtest, idtest->name+2, '.') == left_len)
1176                         ) {
1177                                 if(nrtest < sizeof(in_use))
1178                                         in_use[nrtest]= 1;      /* mark as used */
1179                                 if(nr <= nrtest)
1180                                         nr= nrtest+1;           /* track largest unused */
1181                         }
1182                 }
1183
1184                 /* decide which value of nr to use */
1185                 for(a=0; a < sizeof(in_use); a++) {
1186                         if(a>=nr) break;        /* stop when we've check up to biggest */
1187                         if( in_use[a]==0 ) { /* found an unused value */
1188                                 nr = a;
1189                                 break;
1190                         }
1191                 }
1192
1193                 /* If the original name has no numeric suffix, 
1194                  * rather than just chopping and adding numbers, 
1195                  * shave off the end chars until we have a unique name.
1196                  * Check the null terminators match as well so we dont get Cube.000 -> Cube.00 */
1197                 if (nr==0 && name[left_len]== '\0') {
1198                         int len = left_len-1;
1199                         idtest= is_dupid(lb, id, name);
1200                         
1201                         while (idtest && len> 1) {
1202                                 name[len--] = '\0';
1203                                 idtest= is_dupid(lb, id, name);
1204                         }
1205                         if (idtest == NULL) return 1;
1206                         /* otherwise just continue and use a number suffix */
1207                 }
1208                 
1209                 if(nr > 999 && left_len > 16) {
1210                         /* this would overflow name buffer */
1211                         left[16] = 0;
1212                         /* left_len = 16; */ /* for now this isnt used again */
1213                         memcpy(name, left, sizeof(char) * 17);
1214                         continue;
1215                 }
1216                 /* this format specifier is from hell... */
1217                 BLI_snprintf(name, sizeof(id->name) - 2,"%s.%.3d", left, nr);
1218
1219                 return 1;
1220         }
1221 }
1222
1223 /*
1224  * Only for local blocks: external en indirect blocks already have a
1225  * unique ID.
1226  *
1227  * return 1: created a new name
1228  */
1229
1230 int new_id(ListBase *lb, ID *id, const char *tname)
1231 {
1232         int result;
1233         char name[MAX_ID_NAME-2];
1234
1235         /* if library, don't rename */
1236         if(id->lib) return 0;
1237
1238         /* if no libdata given, look up based on ID */
1239         if(lb==NULL) lb= which_libbase(G.main, GS(id->name));
1240
1241         /* if no name given, use name of current ID
1242          * else make a copy (tname args can be const) */
1243         if(tname==NULL)
1244                 tname= id->name+2;
1245
1246         strncpy(name, tname, sizeof(name)-1);
1247
1248         /* if result > 21, strncpy don't put the final '\0' to name.
1249          * easier to assign each time then to check if its needed */
1250         name[sizeof(name)-1]= 0;
1251
1252         if(name[0] == '\0') {
1253                 /* disallow empty names */
1254                 strcpy(name, ID_FALLBACK_NAME);
1255         }
1256         else {
1257                 /* disallow non utf8 chars,
1258                  * the interface checks for this but new ID's based on file names dont */
1259                 BLI_utf8_invalid_strip(name, strlen(name));
1260         }
1261
1262         result = check_for_dupid(lb, id, name);
1263         strcpy(id->name+2, name);
1264
1265         /* This was in 2.43 and previous releases
1266          * however all data in blender should be sorted, not just duplicate names
1267          * sorting should not hurt, but noting just incause it alters the way other
1268          * functions work, so sort every time */
1269         /* if( result )
1270                 sort_alpha_id(lb, id);*/
1271         
1272         sort_alpha_id(lb, id);
1273         
1274         return result;
1275 }
1276
1277 /* Pull an ID out of a library (make it local). Only call this for IDs that
1278    don't have other library users. */
1279 void id_clear_lib_data(Main *bmain, ID *id)
1280 {
1281         BKE_id_lib_local_paths(bmain, id);
1282
1283         id->lib= NULL;
1284         id->flag= LIB_LOCAL;
1285         new_id(which_libbase(bmain, GS(id->name)), id, NULL);
1286 }
1287
1288 /* next to indirect usage in read/writefile also in editobject.c scene.c */
1289 void clear_id_newpoins(void)
1290 {
1291         ListBase *lbarray[MAX_LIBARRAY];
1292         ID *id;
1293         int a;
1294
1295         a= set_listbasepointers(G.main, lbarray);
1296         while(a--) {
1297                 id= lbarray[a]->first;
1298                 while(id) {
1299                         id->newid= NULL;
1300                         id->flag &= ~LIB_NEW;
1301                         id= id->next;
1302                 }
1303         }
1304 }
1305
1306 #define LIBTAG(a)       if(a && a->id.lib) {a->id.flag &=~LIB_INDIRECT; a->id.flag |= LIB_EXTERN;}
1307
1308 static void lib_indirect_test_id(ID *id, Library *lib)
1309 {
1310         
1311         if(id->lib) {
1312                 /* datablocks that were indirectly related are now direct links
1313                  * without this, appending data that has a link to other data will fail to write */
1314                 if(lib && id->lib->parent == lib) {
1315                         id_lib_extern(id);
1316                 }
1317                 return;
1318         }
1319         
1320         if(GS(id->name)==ID_OB) {               
1321                 Object *ob= (Object *)id;
1322                 bActionStrip *strip;
1323                 Mesh *me;
1324
1325                 int a;
1326         
1327                 // XXX old animation system! --------------------------------------
1328                 for (strip=ob->nlastrips.first; strip; strip=strip->next){
1329                         LIBTAG(strip->object); 
1330                         LIBTAG(strip->act);
1331                         LIBTAG(strip->ipo);
1332                 }
1333                 // XXX: new animation system needs something like this?
1334         
1335                 for(a=0; a<ob->totcol; a++) {
1336                         LIBTAG(ob->mat[a]);
1337                 }
1338         
1339                 LIBTAG(ob->dup_group);
1340                 LIBTAG(ob->proxy);
1341                 
1342                 me= ob->data;
1343                 LIBTAG(me);
1344         }
1345 }
1346
1347 void tag_main_lb(ListBase *lb, const short tag)
1348 {
1349         ID *id;
1350         if(tag) {
1351                 for(id= lb->first; id; id= id->next) {
1352                         id->flag |= LIB_DOIT;
1353                 }
1354         }
1355         else {
1356                 for(id= lb->first; id; id= id->next) {
1357                         id->flag &= ~LIB_DOIT;
1358                 }
1359         }
1360 }
1361
1362 void tag_main_idcode(struct Main *mainvar, const short type, const short tag)
1363 {
1364         ListBase *lb= which_libbase(mainvar, type);
1365
1366         tag_main_lb(lb, tag);
1367 }
1368
1369 void tag_main(struct Main *mainvar, const short tag)
1370 {
1371         ListBase *lbarray[MAX_LIBARRAY];
1372         int a;
1373
1374         a= set_listbasepointers(mainvar, lbarray);
1375         while(a--) {
1376                 tag_main_lb(lbarray[a], tag);
1377         }
1378 }
1379
1380 /* if lib!=NULL, only all from lib local
1381  * bmain is almost certainly G.main */
1382 void BKE_library_make_local(Main *bmain, Library *lib, int untagged_only)
1383 {
1384         ListBase *lbarray[MAX_LIBARRAY], tempbase={NULL, NULL};
1385         ID *id, *idn;
1386         int a;
1387
1388         a= set_listbasepointers(bmain, lbarray);
1389         while(a--) {
1390                 id= lbarray[a]->first;
1391                 
1392                 while(id) {
1393                         id->newid= NULL;
1394                         idn= id->next;          /* id is possibly being inserted again */
1395                         
1396                         /* The check on the second line (LIB_PRE_EXISTING) is done so its
1397                          * possible to tag data you dont want to be made local, used for
1398                          * appending data, so any libdata already linked wont become local
1399                          * (very nasty to discover all your links are lost after appending)  
1400                          * */
1401                         if(id->flag & (LIB_EXTERN|LIB_INDIRECT|LIB_NEW) &&
1402                           (untagged_only==0 || !(id->flag & LIB_PRE_EXISTING)))
1403                         {
1404                                 if(lib==NULL || id->lib==lib) {
1405                                         if(id->lib) {
1406                                                 id_clear_lib_data(bmain, id); /* sets 'id->flag' */
1407
1408                                                 /* why sort alphabetically here but not in
1409                                                  * id_clear_lib_data() ? - campbell */
1410                                                 sort_alpha_id(lbarray[a], id);
1411                                         }
1412                                         else {
1413                                                 id->flag &= ~(LIB_EXTERN|LIB_INDIRECT|LIB_NEW);
1414                                         }
1415                                 }
1416                         }
1417                         id= idn;
1418                 }
1419                 
1420                 /* patch2: make it aphabetically */
1421                 while( (id=tempbase.first) ) {
1422                         BLI_remlink(&tempbase, id);
1423                         BLI_addtail(lbarray[a], id);
1424                         new_id(lbarray[a], id, NULL);
1425                 }
1426         }
1427
1428         /* patch 3: make sure library data isn't indirect falsely... */
1429         a= set_listbasepointers(bmain, lbarray);
1430         while(a--) {
1431                 for(id= lbarray[a]->first; id; id=id->next)
1432                         lib_indirect_test_id(id, lib);
1433         }
1434 }
1435
1436
1437 void test_idbutton(char *name)
1438 {
1439         /* called from buttons: when name already exists: call new_id */
1440         ListBase *lb;
1441         ID *idtest;
1442         
1443
1444         lb= which_libbase(G.main, GS(name-2) );
1445         if(lb==NULL) return;
1446         
1447         /* search for id */
1448         idtest= BLI_findstring(lb, name, offsetof(ID, name) + 2);
1449
1450         if(idtest) if( new_id(lb, idtest, name)==0 ) sort_alpha_id(lb, idtest);
1451 }
1452
1453 void text_idbutton(struct ID *id, char *text)
1454 {
1455         if(id) {
1456                 if(GS(id->name)==ID_SCE)
1457                         strcpy(text, "SCE: ");
1458                 else if(GS(id->name)==ID_SCR)
1459                         strcpy(text, "SCR: ");
1460                 else if(GS(id->name)==ID_MA && ((Material*)id)->use_nodes)
1461                         strcpy(text, "NT: ");
1462                 else {
1463                         text[0]= id->name[0];
1464                         text[1]= id->name[1];
1465                         text[2]= ':';
1466                         text[3]= ' ';
1467                         text[4]= 0;
1468                 }
1469         }
1470         else {
1471                 text[0]= '\0';
1472         }
1473 }
1474
1475 void rename_id(ID *id, const char *name)
1476 {
1477         ListBase *lb;
1478
1479         BLI_strncpy(id->name+2, name, sizeof(id->name)-2);
1480         lb= which_libbase(G.main, GS(id->name) );
1481         
1482         new_id(lb, id, name);                           
1483 }
1484
1485 void name_uiprefix_id(char *name, ID *id)
1486 {
1487         name[0] = id->lib ? 'L':' ';
1488         name[1] = id->flag & LIB_FAKEUSER ? 'F': (id->us==0)?'0':' ';
1489         name[2] = ' ';
1490
1491         strcpy(name+3, id->name+2);
1492 }
1493
1494 void BKE_library_filepath_set(Library *lib, const char *filepath)
1495 {
1496         /* in some cases this is used to update the absolute path from the
1497          * relative */
1498         if (lib->name != filepath) {
1499                 BLI_strncpy(lib->name, filepath, sizeof(lib->name));
1500         }
1501
1502         BLI_strncpy(lib->filepath, filepath, sizeof(lib->filepath));
1503
1504         /* not essential but set filepath is an absolute copy of value which
1505          * is more useful if its kept in sync */
1506         if (strncmp(lib->filepath, "//", 2) == 0) {
1507                 /* note that the file may be unsaved, in this case, setting the
1508                  * filepath on an indirectly linked path is not allowed from the
1509                  * outliner, and its not really supported but allow from here for now
1510                  * since making local could cause this to be directly linked - campbell
1511                  */
1512                 const char *basepath= lib->parent ? lib->parent->filepath : G.main->name;
1513                 BLI_path_abs(lib->filepath, basepath);
1514         }
1515 }