fac18ba7942692ea258dc9f464e0cf964c9a109c
[blender.git] / source / blender / makesrna / intern / rna_access.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * Contributor(s): Blender Foundation (2008).
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "MEM_guardedalloc.h"
29
30 #include "DNA_ID.h"
31 #include "DNA_windowmanager_types.h"
32
33 #include "BLI_blenlib.h"
34 #include "BLI_dynstr.h"
35 #include "BLI_ghash.h"
36
37 #include "BKE_context.h"
38 #include "BKE_idprop.h"
39 #include "BKE_report.h"
40 #include "BKE_utildefines.h"
41
42 #include "WM_api.h"
43
44 #include "RNA_access.h"
45 #include "RNA_define.h"
46 #include "RNA_types.h"
47
48 #include "rna_internal.h"
49
50 /* Init/Exit */
51
52 void RNA_init()
53 {
54         StructRNA *srna;
55         PropertyRNA *prop;
56
57         for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
58                 if(!srna->cont.prophash) {
59                         srna->cont.prophash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp);
60
61                         for(prop=srna->cont.properties.first; prop; prop=prop->next)
62                                 if(!(prop->flag & PROP_BUILTIN))
63                                         BLI_ghash_insert(srna->cont.prophash, (void*)prop->identifier, prop);
64                 }
65         }
66 }
67
68 void RNA_exit()
69 {
70         StructRNA *srna;
71
72         for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
73                 if(srna->cont.prophash) {
74                         BLI_ghash_free(srna->cont.prophash, NULL, NULL);
75                         srna->cont.prophash= NULL;
76                 }
77         }
78
79         RNA_free(&BLENDER_RNA);
80 }
81
82 /* Pointer */
83
84 PointerRNA PointerRNA_NULL = {{0}, 0, 0};
85
86 void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr)
87 {
88         r_ptr->id.data= NULL;
89         r_ptr->type= &RNA_Main;
90         r_ptr->data= main;
91 }
92
93 void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
94 {
95         PointerRNA tmp;
96         StructRNA *type, *idtype= NULL;
97
98         if(id) {
99                 memset(&tmp, 0, sizeof(tmp));
100                 tmp.data= id;
101                 idtype= rna_ID_refine(&tmp);
102                 
103                 while(idtype->refine) {
104                         type= idtype->refine(&tmp);
105
106                         if(type == idtype)
107                                 break;
108                         else
109                                 idtype= type;
110                 }
111         }
112         
113         r_ptr->id.data= id;
114         r_ptr->type= idtype;
115         r_ptr->data= id;
116 }
117
118 void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
119 {
120         PointerRNA tmp;
121         StructRNA *idtype= NULL;
122
123         if(id) {
124                 memset(&tmp, 0, sizeof(tmp));
125                 tmp.data= id;
126                 idtype= rna_ID_refine(&tmp);
127         }
128
129         r_ptr->id.data= id;
130         r_ptr->type= type;
131         r_ptr->data= data;
132
133         if(data) {
134                 while(r_ptr->type && r_ptr->type->refine) {
135                         StructRNA *rtype= r_ptr->type->refine(r_ptr);
136
137                         if(rtype == r_ptr->type)
138                                 break;
139                         else
140                                 r_ptr->type= rtype;
141                 }
142         }
143 }
144
145 static void rna_pointer_inherit_id(StructRNA *type, PointerRNA *parent, PointerRNA *ptr)
146 {
147         if(type && type->flag & STRUCT_ID) {
148                 ptr->id.data= ptr->data;
149         }
150         else {
151                 ptr->id.data= parent->id.data;
152         }
153 }
154
155 void RNA_blender_rna_pointer_create(PointerRNA *r_ptr)
156 {
157         r_ptr->id.data= NULL;
158         r_ptr->type= &RNA_BlenderRNA;
159         r_ptr->data= &BLENDER_RNA;
160 }
161
162 PointerRNA rna_pointer_inherit_refine(PointerRNA *ptr, StructRNA *type, void *data)
163 {
164         PointerRNA result;
165
166         if(data) {
167                 result.data= data;
168                 result.type= type;
169                 rna_pointer_inherit_id(type, ptr, &result);
170
171                 while(result.type->refine) {
172                         type= result.type->refine(&result);
173
174                         if(type == result.type)
175                                 break;
176                         else
177                                 result.type= type;
178                 }
179         }
180         else
181                 memset(&result, 0, sizeof(result));
182         
183         return result;
184 }
185
186 /* ID Properties */
187
188 IDProperty *RNA_struct_idproperties(PointerRNA *ptr, int create)
189 {
190         StructRNA *type= ptr->type;
191
192         if(type && type->idproperties)
193                 return type->idproperties(ptr, create);
194         
195         return NULL;
196 }
197
198 static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name)
199 {
200         IDProperty *group= RNA_struct_idproperties(ptr, 0);
201         IDProperty *idprop;
202
203         if(group) {
204                 for(idprop=group->data.group.first; idprop; idprop=idprop->next)
205                         if(strcmp(idprop->name, name) == 0)
206                                 return idprop;
207         }
208         
209         return NULL;
210 }
211
212 static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
213 {
214         if(prop->magic == RNA_MAGIC) {
215                 int arraylen[RNA_MAX_ARRAY_DIMENSION];
216                 return (prop->getlength)? prop->getlength(ptr, arraylen): prop->totarraylength;
217         }
218         else {
219                 IDProperty *idprop= (IDProperty*)prop;
220
221                 if(idprop->type == IDP_ARRAY)
222                         return idprop->len;
223                 else
224                         return 0;
225         }
226 }
227
228 static int rna_ensure_property_array_check(PointerRNA *ptr, PropertyRNA *prop)
229 {
230         if(prop->magic == RNA_MAGIC) {
231                 return (prop->getlength || prop->totarraylength) ? 1:0;
232         }
233         else {
234                 IDProperty *idprop= (IDProperty*)prop;
235
236                 return idprop->type == IDP_ARRAY ? 1:0;
237         }
238 }
239
240 static void rna_ensure_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int length[])
241 {
242         if(prop->magic == RNA_MAGIC) {
243                 if(prop->getlength)
244                         prop->getlength(ptr, length);
245                 else
246                         memcpy(length, prop->arraylength, prop->arraydimension*sizeof(int));
247         }
248         else {
249                 IDProperty *idprop= (IDProperty*)prop;
250
251                 if(idprop->type == IDP_ARRAY)
252                         length[0]= idprop->len;
253                 else
254                         length[0]= 0;
255         }
256 }
257
258 static int rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDProperty *idprop)
259 {
260         /* this verifies if the idproperty actually matches the property
261          * description and otherwise removes it. this is to ensure that
262          * rna property access is type safe, e.g. if you defined the rna
263          * to have a certain array length you can count on that staying so */
264         
265         switch(idprop->type) {
266                 case IDP_IDPARRAY:
267                         if(prop->type != PROP_COLLECTION)
268                                 return 0;
269                         break;
270                 case IDP_ARRAY:
271                         if(rna_ensure_property_array_length(ptr, prop) != idprop->len)
272                                 return 0;
273
274                         if(idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT)
275                                 return 0;
276                         if(idprop->subtype == IDP_INT && !ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
277                                 return 0;
278
279                         break;
280                 case IDP_INT:
281                         if(!ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
282                                 return 0;
283                         break;
284                 case IDP_FLOAT:
285                 case IDP_DOUBLE:
286                         if(prop->type != PROP_FLOAT)
287                                 return 0;
288                         break;
289                 case IDP_STRING:
290                         if(prop->type != PROP_STRING)
291                                 return 0;
292                         break;
293                 case IDP_GROUP:
294                         if(prop->type != PROP_POINTER)
295                                 return 0;
296                         break;
297                 default:
298                         return 0;
299         }
300
301         return 1;
302 }
303
304 static PropertyRNA *typemap[IDP_NUMTYPES] =
305         {(PropertyRNA*)&rna_IDProperty_string,
306          (PropertyRNA*)&rna_IDProperty_int,
307          (PropertyRNA*)&rna_IDProperty_float,
308          NULL, NULL, NULL,
309          (PropertyRNA*)&rna_IDProperty_group, NULL,
310          (PropertyRNA*)&rna_IDProperty_double};
311
312 static PropertyRNA *arraytypemap[IDP_NUMTYPES] =
313         {NULL, (PropertyRNA*)&rna_IDProperty_int_array,
314          (PropertyRNA*)&rna_IDProperty_float_array,
315          NULL, NULL, NULL,
316          (PropertyRNA*)&rna_IDProperty_collection, NULL,
317          (PropertyRNA*)&rna_IDProperty_double_array};
318
319 IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr)
320 {
321         /* This is quite a hack, but avoids some complexity in the API. we
322          * pass IDProperty structs as PropertyRNA pointers to the outside.
323          * We store some bytes in PropertyRNA structs that allows us to
324          * distinguish it from IDProperty structs. If it is an ID property,
325          * we look up an IDP PropertyRNA based on the type, and set the data
326          * pointer to the IDProperty. */
327
328         if((*prop)->magic == RNA_MAGIC) {
329                 if((*prop)->flag & PROP_IDPROPERTY) {
330                         IDProperty *idprop= rna_idproperty_find(ptr, (*prop)->identifier);
331
332                         if(idprop && !rna_idproperty_verify_valid(ptr, *prop, idprop)) {
333                                 IDProperty *group= RNA_struct_idproperties(ptr, 0);
334
335                                 IDP_RemFromGroup(group, idprop);
336                                 IDP_FreeProperty(idprop);
337                                 MEM_freeN(idprop);
338                                 return NULL;
339                         }
340
341                         return idprop;
342                 }
343                 else
344                         return NULL;
345         }
346
347         {
348                 IDProperty *idprop= (IDProperty*)(*prop);
349
350                 if(idprop->type == IDP_ARRAY)
351                         *prop= arraytypemap[(int)(idprop->subtype)];
352                 else 
353                         *prop= typemap[(int)(idprop->type)];
354
355                 return idprop;
356         }
357 }
358
359 static PropertyRNA *rna_ensure_property(PropertyRNA *prop)
360 {
361         /* the quick version if we don't need the idproperty */
362
363         if(prop->magic == RNA_MAGIC)
364                 return prop;
365
366         {
367                 IDProperty *idprop= (IDProperty*)prop;
368
369                 if(idprop->type == IDP_ARRAY)
370                         return arraytypemap[(int)(idprop->subtype)];
371                 else 
372                         return typemap[(int)(idprop->type)];
373         }
374 }
375
376 static const char *rna_ensure_property_identifier(PropertyRNA *prop)
377 {
378         if(prop->magic == RNA_MAGIC)
379                 return prop->identifier;
380         else
381                 return ((IDProperty*)prop)->name;
382 }
383
384 static const char *rna_ensure_property_description(PropertyRNA *prop)
385 {
386         if(prop->magic == RNA_MAGIC)
387                 return prop->description;
388         else
389                 return ((IDProperty*)prop)->name; /* XXX - not correct */
390 }
391
392 static const char *rna_ensure_property_name(PropertyRNA *prop)
393 {
394         if(prop->magic == RNA_MAGIC)
395                 return prop->name;
396         else
397                 return ((IDProperty*)prop)->name;
398 }
399
400 /* Structs */
401
402 const char *RNA_struct_identifier(StructRNA *type)
403 {
404         return type->identifier;
405 }
406
407 const char *RNA_struct_ui_name(StructRNA *type)
408 {
409         return type->name;
410 }
411
412 int RNA_struct_ui_icon(StructRNA *type)
413 {
414         if(type)
415                 return type->icon;
416         else
417                 return ICON_DOT;
418 }
419
420 const char *RNA_struct_ui_description(StructRNA *type)
421 {
422         return type->description;
423 }
424
425 PropertyRNA *RNA_struct_name_property(StructRNA *type)
426 {
427         return type->nameproperty;
428 }
429
430 PropertyRNA *RNA_struct_iterator_property(StructRNA *type)
431 {
432         return type->iteratorproperty;
433 }
434
435 StructRNA *RNA_struct_base(StructRNA *type)
436 {
437         return type->base;
438 }
439
440 int RNA_struct_is_ID(StructRNA *type)
441 {
442         return (type->flag & STRUCT_ID) != 0;
443 }
444
445 int RNA_struct_is_a(StructRNA *type, StructRNA *srna)
446 {
447         StructRNA *base;
448
449         if(!type)
450                 return 0;
451
452         /* ptr->type is always maximally refined */
453         for(base=type; base; base=base->base)
454                 if(base == srna)
455                         return 1;
456         
457         return 0;
458 }
459
460 PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
461 {
462         PropertyRNA *iterprop= RNA_struct_iterator_property(ptr->type);
463         PointerRNA propptr;
464
465         if(RNA_property_collection_lookup_string(ptr, iterprop, identifier, &propptr))
466                 return propptr.data;
467         
468         return NULL;
469 }
470
471 /* Find the property which uses the given nested struct */
472 PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
473 {
474         PropertyRNA *prop= NULL;
475
476         RNA_STRUCT_BEGIN(ptr, iprop) {
477                 /* This assumes that there can only be one user of this nested struct */
478                 if (RNA_property_pointer_type(ptr, iprop) == srna) {
479                         prop= iprop;
480                         break;
481                 }
482         }
483         RNA_PROP_END;
484
485         return prop;
486 }
487
488 const struct ListBase *RNA_struct_defined_properties(StructRNA *srna)
489 {
490         return &srna->cont.properties;
491 }
492
493 FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier)
494 {
495         PointerRNA tptr;
496         PropertyRNA *iterprop;
497         FunctionRNA *func;
498
499         RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr);
500         iterprop= RNA_struct_find_property(&tptr, "functions");
501
502         func= NULL;
503
504         RNA_PROP_BEGIN(&tptr, funcptr, iterprop) {
505                 if(strcmp(identifier, RNA_function_identifier(funcptr.data)) == 0) {
506                         func= funcptr.data;
507                         break;
508                 }
509         }
510         RNA_PROP_END;
511
512         return func;
513 }
514
515 const struct ListBase *RNA_struct_defined_functions(StructRNA *srna)
516 {
517         return &srna->functions;
518 }
519
520 StructRegisterFunc RNA_struct_register(StructRNA *type)
521 {
522         return type->reg;
523 }
524
525 StructUnregisterFunc RNA_struct_unregister(StructRNA *type)
526 {
527         do {
528                 if(type->unreg)
529                         return type->unreg;
530         } while((type=type->base));
531
532         return NULL;
533 }
534
535 void *RNA_struct_py_type_get(StructRNA *srna)
536 {
537         return srna->py_type;
538 }
539
540 void RNA_struct_py_type_set(StructRNA *srna, void *py_type)
541 {
542         srna->py_type= py_type;
543 }
544
545 void *RNA_struct_blender_type_get(StructRNA *srna)
546 {
547         return srna->blender_type;
548 }
549
550 void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
551 {
552         srna->blender_type= blender_type;
553 }
554
555 char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen)
556 {
557         PropertyRNA *nameprop;
558
559         if(ptr->data && (nameprop = RNA_struct_name_property(ptr->type)))
560                 return RNA_property_string_get_alloc(ptr, nameprop, fixedbuf, fixedlen);
561
562         return NULL;
563 }
564
565 /* Property Information */
566
567 const char *RNA_property_identifier(PropertyRNA *prop)
568 {
569         return rna_ensure_property_identifier(prop);
570 }
571
572 const char *RNA_property_description(PropertyRNA *prop)
573 {
574         return rna_ensure_property_description(prop);
575 }
576
577 PropertyType RNA_property_type(PropertyRNA *prop)
578 {
579         return rna_ensure_property(prop)->type;
580 }
581
582 PropertySubType RNA_property_subtype(PropertyRNA *prop)
583 {
584         return rna_ensure_property(prop)->subtype;
585 }
586
587 PropertyUnit RNA_property_unit(PropertyRNA *prop)
588 {
589         return RNA_SUBTYPE_UNIT(rna_ensure_property(prop)->subtype);
590 }
591
592 int RNA_property_flag(PropertyRNA *prop)
593 {
594         return rna_ensure_property(prop)->flag;
595 }
596
597 int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
598 {
599         return rna_ensure_property_array_length(ptr, prop);
600 }
601
602 int RNA_property_array_check(PointerRNA *ptr, PropertyRNA *prop)
603 {
604         return rna_ensure_property_array_check(ptr, prop);
605 }
606
607 /* used by BPY to make an array from the python object */
608 int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[])
609 {
610         PropertyRNA *rprop= rna_ensure_property(prop);
611
612         if(length && rprop->arraydimension > 1)
613                 rna_ensure_property_multi_array_length(ptr, prop, length);
614
615         return rprop->arraydimension;
616 }
617
618 /* Return the size of Nth dimension. */
619 int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dim)
620 {
621         int len[RNA_MAX_ARRAY_DIMENSION];
622
623         rna_ensure_property_multi_array_length(ptr, prop, len);
624
625         return len[dim];
626 }
627
628 char RNA_property_array_item_char(PropertyRNA *prop, int index)
629 {
630         const char *vectoritem= "XYZW";
631         const char *quatitem= "WXYZ";
632         const char *coloritem= "RGBA";
633         PropertySubType subtype= rna_ensure_property(prop)->subtype;
634
635         /* get string to use for array index */
636         if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE))
637                 return quatitem[index];
638         else if((index < 4) && ELEM6(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION))
639                 return vectoritem[index];
640         else if ((index < 4) && ELEM(subtype, PROP_COLOR, PROP_RGB))
641                 return coloritem[index];
642         else
643                 return '\0';
644 }
645
646 void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
647 {
648         IntPropertyRNA *iprop= (IntPropertyRNA*)rna_ensure_property(prop);
649
650         if(iprop->range) {
651                 iprop->range(ptr, hardmin, hardmax);
652         }
653         else {
654                 *hardmin= iprop->hardmin;
655                 *hardmax= iprop->hardmax;
656         }
657 }
658
659 void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
660 {
661         IntPropertyRNA *iprop= (IntPropertyRNA*)rna_ensure_property(prop);
662         int hardmin, hardmax;
663         
664         if(iprop->range) {
665                 iprop->range(ptr, &hardmin, &hardmax);
666                 *softmin= MAX2(iprop->softmin, hardmin);
667                 *softmax= MIN2(iprop->softmax, hardmax);
668         }
669         else {
670                 *softmin= iprop->softmin;
671                 *softmax= iprop->softmax;
672         }
673
674         *step= iprop->step;
675 }
676
677 void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
678 {
679         FloatPropertyRNA *fprop= (FloatPropertyRNA*)rna_ensure_property(prop);
680
681         if(fprop->range) {
682                 fprop->range(ptr, hardmin, hardmax);
683         }
684         else {
685                 *hardmin= fprop->hardmin;
686                 *hardmax= fprop->hardmax;
687         }
688 }
689
690 void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision)
691 {
692         FloatPropertyRNA *fprop= (FloatPropertyRNA*)rna_ensure_property(prop);
693         float hardmin, hardmax;
694
695         if(fprop->range) {
696                 fprop->range(ptr, &hardmin, &hardmax);
697                 *softmin= MAX2(fprop->softmin, hardmin);
698                 *softmax= MIN2(fprop->softmax, hardmax);
699         }
700         else {
701                 *softmin= fprop->softmin;
702                 *softmax= fprop->softmax;
703         }
704
705         *step= fprop->step;
706         *precision= (float)fprop->precision;
707 }
708
709 int RNA_property_string_maxlength(PropertyRNA *prop)
710 {
711         StringPropertyRNA *sprop= (StringPropertyRNA*)rna_ensure_property(prop);
712         return sprop->maxlength;
713 }
714
715 StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
716 {
717         prop= rna_ensure_property(prop);
718
719         if(prop->type == PROP_POINTER) {
720                 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
721
722                 if(pprop->typef)
723                         return pprop->typef(ptr);
724                 else if(pprop->type)
725                         return pprop->type;
726         }
727         else if(prop->type == PROP_COLLECTION) {
728                 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
729
730                 if(cprop->type)
731                         return cprop->type;
732         }
733
734         return &RNA_UnknownType;
735 }
736
737 void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item, int *totitem, int *free)
738 {
739         EnumPropertyRNA *eprop= (EnumPropertyRNA*)rna_ensure_property(prop);
740
741         *free= 0;
742
743         if(eprop->itemf && C) {
744                 int tot= 0;
745                 *item= eprop->itemf(C, ptr, free);
746
747                 if(totitem) {
748                         if(*item) {
749                                 for( ; (*item)[tot].identifier; tot++);
750                         }
751
752                         *totitem= tot;
753                 }
754         }
755         else {
756                 *item= eprop->item;
757                 if(totitem)
758                         *totitem= eprop->totitem;
759         }
760 }
761
762 int RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value)
763 {       
764         EnumPropertyItem *item;
765         int free;
766         
767         RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
768         
769         for(; item->identifier; item++) {
770                 if(item->identifier[0] && strcmp(item->identifier, identifier)==0) {
771                         *value = item->value;
772                         return 1;
773                 }
774         }
775
776         if(free)
777                 MEM_freeN(item);
778
779         return 0;
780 }
781
782 int RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier)
783 {
784         for (; item->identifier; item++) {
785                 if(item->identifier[0] && item->value==value) {
786                         *identifier = item->identifier;
787                         return 1;
788                 }
789         }
790         return 0;
791 }
792
793 int RNA_enum_name(EnumPropertyItem *item, const int value, const char **name)
794 {
795         for (; item->identifier; item++) {
796                 if(item->identifier[0] && item->value==value) {
797                         *name = item->name;
798                         return 1;
799                 }
800         }
801         return 0;
802 }
803
804 int RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
805 {       
806         EnumPropertyItem *item= NULL;
807         int result, free;
808         
809         RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
810         if(item) {
811                 result= RNA_enum_identifier(item, value, identifier);
812                 if(free)
813                         MEM_freeN(item);
814
815                 return result;
816         }
817         return 0;
818 }
819
820 const char *RNA_property_ui_name(PropertyRNA *prop)
821 {
822         return rna_ensure_property_name(prop);
823 }
824
825 const char *RNA_property_ui_description(PropertyRNA *prop)
826 {
827         return rna_ensure_property(prop)->description;
828 }
829
830 int RNA_property_ui_icon(PropertyRNA *prop)
831 {
832         return rna_ensure_property(prop)->icon;
833 }
834
835 int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
836 {
837         ID *id;
838         int flag;
839
840         prop= rna_ensure_property(prop);
841
842         if(prop->editable)
843                 flag= prop->editable(ptr);
844         else
845                 flag= prop->flag;
846         
847         id= ptr->id.data;
848
849         return (flag & PROP_EDITABLE) && (!id || !id->lib || (flag & PROP_LIB_EXCEPTION));
850 }
851
852 int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
853 {
854         int flag;
855
856         prop= rna_ensure_property(prop);
857
858         if(!(prop->flag & PROP_ANIMATEABLE))
859                 return 0;
860
861         if(prop->editable)
862                 flag= prop->editable(ptr);
863         else
864                 flag= prop->flag;
865
866         return (flag & PROP_EDITABLE);
867 }
868
869 int RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop)
870 {
871         /* would need to ask animation system */
872
873         return 0;
874 }
875
876 void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
877 {
878         prop= rna_ensure_property(prop);
879
880         if(prop->update)
881                 prop->update(C, ptr);
882         if(prop->noteflag)
883                 WM_event_add_notifier(C, prop->noteflag, ptr->id.data);
884 }
885
886 /* Property Data */
887
888 int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
889 {
890         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
891         IDProperty *idprop;
892
893         if((idprop=rna_idproperty_check(&prop, ptr)))
894                 return IDP_Int(idprop);
895         else if(bprop->get)
896                 return bprop->get(ptr);
897         else
898                 return bprop->defaultvalue;
899 }
900
901 void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
902 {
903         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
904         IDProperty *idprop;
905
906         /* just incase other values are passed */
907         if(value) value= 1;
908
909         if((idprop=rna_idproperty_check(&prop, ptr)))
910                 IDP_Int(idprop)= value;
911         else if(bprop->set)
912                 bprop->set(ptr, value);
913         else if(prop->flag & PROP_EDITABLE) {
914                 IDPropertyTemplate val = {0};
915                 IDProperty *group;
916
917                 val.i= value;
918
919                 group= RNA_struct_idproperties(ptr, 1);
920                 if(group)
921                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
922         }
923 }
924
925 void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
926 {
927         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
928         IDProperty *idprop;
929
930         if((idprop=rna_idproperty_check(&prop, ptr))) {
931                 if(prop->arraydimension == 0)
932                         values[0]= RNA_property_boolean_get(ptr, prop);
933                 else
934                         memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
935         }
936         else if(prop->arraydimension == 0)
937                 values[0]= RNA_property_boolean_get(ptr, prop);
938         else if(bprop->getarray)
939                 bprop->getarray(ptr, values);
940         else if(bprop->defaultarray)
941                 memcpy(values, bprop->defaultarray, sizeof(int)*prop->totarraylength);
942         else
943                 memset(values, 0, sizeof(int)*prop->totarraylength);
944 }
945
946 int RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
947 {
948         int tmp[RNA_MAX_ARRAY_LENGTH];
949         int len= rna_ensure_property_array_length(ptr, prop);
950
951         if(len <= RNA_MAX_ARRAY_LENGTH) {
952                 RNA_property_boolean_get_array(ptr, prop, tmp);
953                 return tmp[index];
954         }
955         else {
956                 int *tmparray, value;
957
958                 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_index");
959                 RNA_property_boolean_get_array(ptr, prop, tmparray);
960                 value= tmparray[index];
961                 MEM_freeN(tmparray);
962
963                 return value;
964         }
965 }
966
967 void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
968 {
969         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
970         IDProperty *idprop;
971
972         if((idprop=rna_idproperty_check(&prop, ptr))) {
973                 if(prop->arraydimension == 0)
974                         IDP_Int(idprop)= values[0];
975                 else
976                         memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
977         }
978         else if(prop->arraydimension == 0)
979                 RNA_property_boolean_set(ptr, prop, values[0]);
980         else if(bprop->setarray)
981                 bprop->setarray(ptr, values);
982         else if(prop->flag & PROP_EDITABLE) {
983                 IDPropertyTemplate val = {0};
984                 IDProperty *group;
985
986                 val.array.len= prop->totarraylength;
987                 val.array.type= IDP_INT;
988
989                 group= RNA_struct_idproperties(ptr, 1);
990                 if(group) {
991                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
992                         IDP_AddToGroup(group, idprop);
993                         memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
994                 }
995         }
996 }
997
998 void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
999 {
1000         int tmp[RNA_MAX_ARRAY_LENGTH];
1001         int len= rna_ensure_property_array_length(ptr, prop);
1002
1003         if(len <= RNA_MAX_ARRAY_LENGTH) {
1004                 RNA_property_boolean_get_array(ptr, prop, tmp);
1005                 tmp[index]= value;
1006                 RNA_property_boolean_set_array(ptr, prop, tmp);
1007         }
1008         else {
1009                 int *tmparray;
1010
1011                 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_index");
1012                 RNA_property_boolean_get_array(ptr, prop, tmparray);
1013                 tmparray[index]= value;
1014                 RNA_property_boolean_set_array(ptr, prop, tmparray);
1015                 MEM_freeN(tmparray);
1016         }
1017 }
1018
1019 int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
1020 {
1021         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1022         IDProperty *idprop;
1023
1024         if((idprop=rna_idproperty_check(&prop, ptr)))
1025                 return IDP_Int(idprop);
1026         else if(iprop->get)
1027                 return iprop->get(ptr);
1028         else
1029                 return iprop->defaultvalue;
1030 }
1031
1032 void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1033 {
1034         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1035         IDProperty *idprop;
1036
1037         if((idprop=rna_idproperty_check(&prop, ptr)))
1038                 IDP_Int(idprop)= value;
1039         else if(iprop->set)
1040                 iprop->set(ptr, value);
1041         else if(prop->flag & PROP_EDITABLE) {
1042                 IDPropertyTemplate val = {0};
1043                 IDProperty *group;
1044
1045                 val.i= value;
1046
1047                 group= RNA_struct_idproperties(ptr, 1);
1048                 if(group)
1049                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
1050         }
1051 }
1052
1053 void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
1054 {
1055         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1056         IDProperty *idprop;
1057
1058         if((idprop=rna_idproperty_check(&prop, ptr))) {
1059                 if(prop->arraydimension == 0)
1060                         values[0]= RNA_property_int_get(ptr, prop);
1061                 else
1062                         memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
1063         }
1064         else if(prop->arraydimension == 0)
1065                 values[0]= RNA_property_int_get(ptr, prop);
1066         else if(iprop->getarray)
1067                 iprop->getarray(ptr, values);
1068         else if(iprop->defaultarray)
1069                 memcpy(values, iprop->defaultarray, sizeof(int)*prop->totarraylength);
1070         else
1071                 memset(values, 0, sizeof(int)*prop->totarraylength);
1072 }
1073
1074 int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1075 {
1076         int tmp[RNA_MAX_ARRAY_LENGTH];
1077         int len= rna_ensure_property_array_length(ptr, prop);
1078
1079         if(len <= RNA_MAX_ARRAY_LENGTH) {
1080                 RNA_property_int_get_array(ptr, prop, tmp);
1081                 return tmp[index];
1082         }
1083         else {
1084                 int *tmparray, value;
1085
1086                 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_index");
1087                 RNA_property_int_get_array(ptr, prop, tmparray);
1088                 value= tmparray[index];
1089                 MEM_freeN(tmparray);
1090
1091                 return value;
1092         }
1093 }
1094
1095 void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
1096 {
1097         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1098         IDProperty *idprop;
1099
1100         if((idprop=rna_idproperty_check(&prop, ptr))) {
1101                 if(prop->arraydimension == 0)
1102                         IDP_Int(idprop)= values[0];
1103                 else
1104                         memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);\
1105         }
1106         else if(prop->arraydimension == 0)
1107                 RNA_property_int_set(ptr, prop, values[0]);
1108         else if(iprop->setarray)
1109                 iprop->setarray(ptr, values);
1110         else if(prop->flag & PROP_EDITABLE) {
1111                 IDPropertyTemplate val = {0};
1112                 IDProperty *group;
1113
1114                 val.array.len= prop->totarraylength;
1115                 val.array.type= IDP_INT;
1116
1117                 group= RNA_struct_idproperties(ptr, 1);
1118                 if(group) {
1119                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
1120                         IDP_AddToGroup(group, idprop);
1121                         memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
1122                 }
1123         }
1124 }
1125
1126 void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
1127 {
1128         int tmp[RNA_MAX_ARRAY_LENGTH];
1129         int len= rna_ensure_property_array_length(ptr, prop);
1130
1131         if(len <= RNA_MAX_ARRAY_LENGTH) {
1132                 RNA_property_int_get_array(ptr, prop, tmp);
1133                 tmp[index]= value;
1134                 RNA_property_int_set_array(ptr, prop, tmp);
1135         }
1136         else {
1137                 int *tmparray;
1138
1139                 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_index");
1140                 RNA_property_int_get_array(ptr, prop, tmparray);
1141                 tmparray[index]= value;
1142                 RNA_property_int_set_array(ptr, prop, tmparray);
1143                 MEM_freeN(tmparray);
1144         }
1145 }
1146
1147 float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
1148 {
1149         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1150         IDProperty *idprop;
1151
1152         if((idprop=rna_idproperty_check(&prop, ptr))) {
1153                 if(idprop->type == IDP_FLOAT)
1154                         return IDP_Float(idprop);
1155                 else
1156                         return (float)IDP_Double(idprop);
1157         }
1158         else if(fprop->get)
1159                 return fprop->get(ptr);
1160         else
1161                 return fprop->defaultvalue;
1162 }
1163
1164 void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
1165 {
1166         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1167         IDProperty *idprop;
1168
1169         if((idprop=rna_idproperty_check(&prop, ptr))) {
1170                 if(idprop->type == IDP_FLOAT)
1171                         IDP_Float(idprop)= value;
1172                 else
1173                         IDP_Double(idprop)= value;
1174         }
1175         else if(fprop->set) {
1176                 fprop->set(ptr, value);
1177         }
1178         else if(prop->flag & PROP_EDITABLE) {
1179                 IDPropertyTemplate val = {0};
1180                 IDProperty *group;
1181
1182                 val.f= value;
1183
1184                 group= RNA_struct_idproperties(ptr, 1);
1185                 if(group)
1186                         IDP_AddToGroup(group, IDP_New(IDP_FLOAT, val, (char*)prop->identifier));
1187         }
1188 }
1189
1190 void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
1191 {
1192         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1193         IDProperty *idprop;
1194         int i;
1195
1196         if((idprop=rna_idproperty_check(&prop, ptr))) {
1197                 if(prop->arraydimension == 0)
1198                         values[0]= RNA_property_float_get(ptr, prop);
1199                 else if(idprop->subtype == IDP_FLOAT) {
1200                         memcpy(values, IDP_Array(idprop), sizeof(float)*idprop->len);
1201                 }
1202                 else {
1203                         for(i=0; i<idprop->len; i++)
1204                                 values[i]=  (float)(((double*)IDP_Array(idprop))[i]);
1205                 }
1206         }
1207         else if(prop->arraydimension == 0)
1208                 values[0]= RNA_property_float_get(ptr, prop);
1209         else if(fprop->getarray)
1210                 fprop->getarray(ptr, values);
1211         else if(fprop->defaultarray)
1212                 memcpy(values, fprop->defaultarray, sizeof(float)*prop->totarraylength);
1213         else
1214                 memset(values, 0, sizeof(float)*prop->totarraylength);
1215 }
1216
1217 float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1218 {
1219         float tmp[RNA_MAX_ARRAY_LENGTH];
1220         int len= rna_ensure_property_array_length(ptr, prop);
1221
1222         if(len <= RNA_MAX_ARRAY_LENGTH) {
1223                 RNA_property_float_get_array(ptr, prop, tmp);
1224                 return tmp[index];
1225         }
1226         else {
1227                 float *tmparray, value;
1228
1229                 tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_index");
1230                 RNA_property_float_get_array(ptr, prop, tmparray);
1231                 value= tmparray[index];
1232                 MEM_freeN(tmparray);
1233
1234                 return value;
1235         }
1236
1237 }
1238
1239 void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
1240 {
1241         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1242         IDProperty *idprop;
1243         int i;
1244
1245         if((idprop=rna_idproperty_check(&prop, ptr))) {
1246                 if(prop->arraydimension == 0)
1247                         IDP_Double(idprop)= values[0];
1248                 else if(idprop->subtype == IDP_FLOAT) {
1249                         memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len);
1250                 }
1251                 else {
1252                         for(i=0; i<idprop->len; i++)
1253                                 ((double*)IDP_Array(idprop))[i]= values[i];
1254                 }
1255         }
1256         else if(prop->arraydimension == 0)
1257                 RNA_property_float_set(ptr, prop, values[0]);
1258         else if(fprop->setarray) {
1259                 fprop->setarray(ptr, values);
1260         }
1261         else if(prop->flag & PROP_EDITABLE) {
1262                 IDPropertyTemplate val = {0};
1263                 IDProperty *group;
1264
1265                 val.array.len= prop->totarraylength;
1266                 val.array.type= IDP_FLOAT;
1267
1268                 group= RNA_struct_idproperties(ptr, 1);
1269                 if(group) {
1270                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
1271                         IDP_AddToGroup(group, idprop);
1272                         memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len);
1273                 }
1274         }
1275 }
1276
1277 void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
1278 {
1279         float tmp[RNA_MAX_ARRAY_LENGTH];
1280         int len= rna_ensure_property_array_length(ptr, prop);
1281
1282         if(len <= RNA_MAX_ARRAY_LENGTH) {
1283                 RNA_property_float_get_array(ptr, prop, tmp);
1284                 tmp[index]= value;
1285                 RNA_property_float_set_array(ptr, prop, tmp);
1286         }
1287         else {
1288                 float *tmparray;
1289
1290                 tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_index");
1291                 RNA_property_float_get_array(ptr, prop, tmparray);
1292                 tmparray[index]= value;
1293                 RNA_property_float_set_array(ptr, prop, tmparray);
1294                 MEM_freeN(tmparray);
1295         }
1296 }
1297
1298 void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
1299 {
1300         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1301         IDProperty *idprop;
1302
1303         if((idprop=rna_idproperty_check(&prop, ptr)))
1304                 strcpy(value, IDP_String(idprop));
1305         else if(sprop->get)
1306                 sprop->get(ptr, value);
1307         else
1308                 strcpy(value, sprop->defaultvalue);
1309 }
1310
1311 char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen)
1312 {
1313         char *buf;
1314         int length;
1315
1316         length= RNA_property_string_length(ptr, prop);
1317
1318         if(length+1 < fixedlen)
1319                 buf= fixedbuf;
1320         else
1321                 buf= MEM_callocN(sizeof(char)*(length+1), "RNA_string_get_alloc");
1322
1323         RNA_property_string_get(ptr, prop, buf);
1324
1325         return buf;
1326 }
1327
1328 int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
1329 {
1330         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1331         IDProperty *idprop;
1332
1333         if((idprop=rna_idproperty_check(&prop, ptr)))
1334                 return strlen(IDP_String(idprop));
1335         else if(sprop->length)
1336                 return sprop->length(ptr);
1337         else
1338                 return strlen(sprop->defaultvalue);
1339 }
1340
1341 void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
1342 {
1343         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1344         IDProperty *idprop;
1345
1346         if((idprop=rna_idproperty_check(&prop, ptr)))
1347                 IDP_AssignString(idprop, (char*)value);
1348         else if(sprop->set)
1349                 sprop->set(ptr, value);
1350         else if(prop->flag & PROP_EDITABLE) {
1351                 IDPropertyTemplate val = {0};
1352                 IDProperty *group;
1353
1354                 val.str= (char*)value;
1355
1356                 group= RNA_struct_idproperties(ptr, 1);
1357                 if(group)
1358                         IDP_AddToGroup(group, IDP_New(IDP_STRING, val, (char*)prop->identifier));
1359         }
1360 }
1361
1362 int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
1363 {
1364         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
1365         IDProperty *idprop;
1366
1367         if((idprop=rna_idproperty_check(&prop, ptr)))
1368                 return IDP_Int(idprop);
1369         else if(eprop->get)
1370                 return eprop->get(ptr);
1371         else
1372                 return eprop->defaultvalue;
1373 }
1374
1375
1376 void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1377 {
1378         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
1379         IDProperty *idprop;
1380
1381         if((idprop=rna_idproperty_check(&prop, ptr)))
1382                 IDP_Int(idprop)= value;
1383         else if(eprop->set) {
1384                 eprop->set(ptr, value);
1385         }
1386         else if(prop->flag & PROP_EDITABLE) {
1387                 IDPropertyTemplate val = {0};
1388                 IDProperty *group;
1389
1390                 val.i= value;
1391
1392                 group= RNA_struct_idproperties(ptr, 1);
1393                 if(group)
1394                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
1395         }
1396 }
1397
1398 PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
1399 {
1400         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
1401         IDProperty *idprop;
1402
1403         if((idprop=rna_idproperty_check(&prop, ptr))) {
1404                 pprop= (PointerPropertyRNA*)prop;
1405
1406                 /* for groups, data is idprop itself */
1407                 return rna_pointer_inherit_refine(ptr, pprop->type, idprop);
1408         }
1409         else if(pprop->get) {
1410                 return pprop->get(ptr);
1411         }
1412         else if(prop->flag & PROP_IDPROPERTY) {
1413                 /* XXX temporary hack to add it automatically, reading should
1414                    never do any write ops, to ensure thread safety etc .. */
1415                 RNA_property_pointer_add(ptr, prop);
1416                 return RNA_property_pointer_get(ptr, prop);
1417         }
1418         else {
1419                 PointerRNA result;
1420
1421                 memset(&result, 0, sizeof(result));
1422                 return result;
1423         }
1424 }
1425
1426 void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value)
1427 {
1428         IDProperty *idprop;
1429
1430         if((idprop=rna_idproperty_check(&prop, ptr))) {
1431                 /* not supported */
1432         }
1433         else {
1434                 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
1435
1436                 if(pprop->set && !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL))
1437                         pprop->set(ptr, ptr_value);
1438         }
1439 }
1440
1441 void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop)
1442 {
1443         IDProperty *idprop;
1444
1445         if((idprop=rna_idproperty_check(&prop, ptr))) {
1446                 /* already exists */
1447         }
1448         else if(prop->flag & PROP_IDPROPERTY) {
1449                 IDPropertyTemplate val = {0};
1450                 IDProperty *group;
1451
1452                 val.i= 0;
1453
1454                 group= RNA_struct_idproperties(ptr, 1);
1455                 if(group)
1456                         IDP_AddToGroup(group, IDP_New(IDP_GROUP, val, (char*)prop->identifier));
1457         }
1458         else
1459                 printf("RNA_property_pointer_add %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);
1460 }
1461
1462 void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop)
1463 {
1464         IDProperty *idprop, *group;
1465
1466         if((idprop=rna_idproperty_check(&prop, ptr))) {
1467                 group= RNA_struct_idproperties(ptr, 0);
1468                 
1469                 if(group) {
1470                         IDP_RemFromGroup(group, idprop);
1471                         IDP_FreeProperty(idprop);
1472                         MEM_freeN(idprop);
1473                 }
1474         }
1475         else
1476                 printf("RNA_property_pointer_remove %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);
1477 }
1478
1479 static void rna_property_collection_get_idp(CollectionPropertyIterator *iter)
1480 {
1481         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
1482
1483         iter->ptr.data= rna_iterator_array_get(iter);
1484         iter->ptr.type= cprop->type;
1485         rna_pointer_inherit_id(cprop->type, &iter->parent, &iter->ptr);
1486 }
1487
1488 void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter)
1489 {
1490         IDProperty *idprop;
1491
1492         memset(iter, 0, sizeof(*iter));
1493
1494         if((idprop=rna_idproperty_check(&prop, ptr)) || (prop->flag & PROP_IDPROPERTY)) {
1495                 iter->parent= *ptr;
1496                 iter->prop= prop;
1497
1498                 if(idprop)
1499                         rna_iterator_array_begin(iter, IDP_IDPArray(idprop), sizeof(IDProperty), idprop->len, 0, NULL);
1500                 else
1501                         rna_iterator_array_begin(iter, NULL, sizeof(IDProperty), 0, 0, NULL);
1502
1503                 if(iter->valid)
1504                         rna_property_collection_get_idp(iter);
1505
1506                 iter->idprop= 1;
1507         }
1508         else {
1509                 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1510                 cprop->begin(iter, ptr);
1511         }
1512 }
1513
1514 void RNA_property_collection_next(CollectionPropertyIterator *iter)
1515 {
1516         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
1517
1518         if(iter->idprop) {
1519                 rna_iterator_array_next(iter);
1520
1521                 if(iter->valid)
1522                         rna_property_collection_get_idp(iter);
1523         }
1524         else
1525                 cprop->next(iter);
1526 }
1527
1528 void RNA_property_collection_end(CollectionPropertyIterator *iter)
1529 {
1530         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
1531
1532         if(iter->idprop)
1533                 rna_iterator_array_end(iter);
1534         else
1535                 cprop->end(iter);
1536 }
1537
1538 int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
1539 {
1540         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1541         IDProperty *idprop;
1542
1543         if((idprop=rna_idproperty_check(&prop, ptr))) {
1544                 return idprop->len;
1545         }
1546         else if(cprop->length) {
1547                 return cprop->length(ptr);
1548         }
1549         else {
1550                 CollectionPropertyIterator iter;
1551                 int length= 0;
1552
1553                 RNA_property_collection_begin(ptr, prop, &iter);
1554                 for(; iter.valid; RNA_property_collection_next(&iter))
1555                         length++;
1556                 RNA_property_collection_end(&iter);
1557
1558                 return length;
1559         }
1560 }
1561
1562 void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
1563 {
1564         IDProperty *idprop;
1565         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1566
1567         if((idprop=rna_idproperty_check(&prop, ptr))) {
1568                 IDPropertyTemplate val = {0};
1569                 IDProperty *item;
1570
1571                 item= IDP_New(IDP_GROUP, val, "");
1572                 IDP_AppendArray(idprop, item);
1573                 IDP_FreeProperty(item);
1574                 MEM_freeN(item);
1575         }
1576         else if(prop->flag & PROP_IDPROPERTY) {
1577                 IDProperty *group, *item;
1578                 IDPropertyTemplate val = {0};
1579
1580                 group= RNA_struct_idproperties(ptr, 1);
1581                 if(group) {
1582                         idprop= IDP_NewIDPArray(prop->identifier);
1583                         IDP_AddToGroup(group, idprop);
1584
1585                         item= IDP_New(IDP_GROUP, val, "");
1586                         IDP_AppendArray(idprop, item);
1587                         IDP_FreeProperty(item);
1588                         MEM_freeN(item);
1589                 }
1590         }
1591         else if(cprop->add){
1592                 if(!(cprop->add->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
1593                         ParameterList params;
1594                         RNA_parameter_list_create(&params, ptr, cprop->add);
1595                         RNA_function_call(NULL, NULL, ptr, cprop->add, &params);
1596                         RNA_parameter_list_free(&params);
1597                 }
1598         }
1599         /*else
1600                 printf("RNA_property_collection_add %s.%s: not implemented for this property.\n", ptr->type->identifier, prop->identifier);*/
1601
1602         if(r_ptr) {
1603                 if(idprop) {
1604                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1605
1606                         r_ptr->data= IDP_GetIndexArray(idprop, idprop->len-1);
1607                         r_ptr->type= cprop->type;
1608                         rna_pointer_inherit_id(NULL, ptr, r_ptr);
1609                 }
1610                 else
1611                         memset(r_ptr, 0, sizeof(*r_ptr));
1612         }
1613 }
1614
1615 int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
1616 {
1617         IDProperty *idprop;
1618         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1619
1620         if((idprop=rna_idproperty_check(&prop, ptr))) {
1621                 IDProperty tmp, *array;
1622                 int len;
1623
1624                 len= idprop->len;
1625                 array= IDP_IDPArray(idprop);
1626
1627                 if(key >= 0 && key < len) {
1628                         if(key+1 < len) {
1629                                 /* move element to be removed to the back */
1630                                 memcpy(&tmp, &array[key], sizeof(IDProperty));
1631                                 memmove(array+key, array+key+1, sizeof(IDProperty)*(len-key+1));
1632                                 memcpy(&array[len-1], &tmp, sizeof(IDProperty));
1633                         }
1634
1635                         IDP_ResizeIDPArray(idprop, len-1);
1636                 }
1637
1638                 return 1;
1639         }
1640         else if(prop->flag & PROP_IDPROPERTY)
1641                 return 1;
1642         else if(cprop->remove){
1643                 if(!(cprop->remove->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
1644                         ParameterList params;
1645                         RNA_parameter_list_create(&params, ptr, cprop->remove);
1646                         RNA_function_call(NULL, NULL, ptr, cprop->remove, &params);
1647                         RNA_parameter_list_free(&params);
1648                 }
1649
1650                 return 0;
1651         }
1652         /*else
1653                 printf("RNA_property_collection_remove %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);*/
1654         
1655         return 0;
1656 }
1657
1658 void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
1659 {
1660         IDProperty *idprop;
1661
1662         if((idprop=rna_idproperty_check(&prop, ptr)))
1663                 IDP_ResizeIDPArray(idprop, 0);
1664 }
1665
1666 int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *t_ptr)
1667 {
1668         CollectionPropertyIterator iter;
1669         int index= 0;
1670         
1671         RNA_property_collection_begin(ptr, prop, &iter);
1672         for(index=0; iter.valid; RNA_property_collection_next(&iter), index++) {
1673                 if (iter.ptr.data == t_ptr->data)
1674                         break;
1675         }
1676         RNA_property_collection_end(&iter);
1677         
1678         /* did we find it? */
1679         if (iter.valid)
1680                 return index;
1681         else
1682                 return -1;
1683 }
1684
1685 int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
1686 {
1687         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1688
1689         if(cprop->lookupint) {
1690                 /* we have a callback defined, use it */
1691                 *r_ptr= cprop->lookupint(ptr, key);
1692                 return (r_ptr->data != NULL);
1693         }
1694         else {
1695                 /* no callback defined, just iterate and find the nth item */
1696                 CollectionPropertyIterator iter;
1697                 int i;
1698
1699                 RNA_property_collection_begin(ptr, prop, &iter);
1700                 for(i=0; iter.valid; RNA_property_collection_next(&iter), i++) {
1701                         if(i == key) {
1702                                 *r_ptr= iter.ptr;
1703                                 break;
1704                         }
1705                 }
1706                 RNA_property_collection_end(&iter);
1707
1708                 if(!iter.valid)
1709                         memset(r_ptr, 0, sizeof(*r_ptr));
1710
1711                 return iter.valid;
1712         }
1713 }
1714
1715 int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr)
1716 {
1717         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1718
1719         if(cprop->lookupstring) {
1720                 /* we have a callback defined, use it */
1721                 *r_ptr= cprop->lookupstring(ptr, key);
1722                 return (r_ptr->data != NULL);
1723         }
1724         else {
1725                 /* no callback defined, compare with name properties if they exist */
1726                 CollectionPropertyIterator iter;
1727                 PropertyRNA *nameprop;
1728                 char name[256], *nameptr;
1729                 int found= 0;
1730
1731                 RNA_property_collection_begin(ptr, prop, &iter);
1732                 for(; iter.valid; RNA_property_collection_next(&iter)) {
1733                         if(iter.ptr.data && iter.ptr.type->nameproperty) {
1734                                 nameprop= iter.ptr.type->nameproperty;
1735
1736                                 nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
1737
1738                                 if(strcmp(nameptr, key) == 0) {
1739                                         *r_ptr= iter.ptr;
1740                                         found= 1;
1741                                 }
1742
1743                                 if((char *)&name != nameptr)
1744                                         MEM_freeN(nameptr);
1745
1746                                 if(found)
1747                                         break;
1748                         }
1749                 }
1750                 RNA_property_collection_end(&iter);
1751
1752                 if(!iter.valid)
1753                         memset(r_ptr, 0, sizeof(*r_ptr));
1754
1755                 return iter.valid;
1756         }
1757 }
1758
1759 int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array)
1760 {
1761         CollectionPropertyIterator iter;
1762         ArrayIterator *internal;
1763         char *arrayp;
1764
1765         if(!(prop->flag & PROP_RAW_ARRAY) || !(itemprop->flag & PROP_RAW_ACCESS))
1766                 return 0;
1767
1768         RNA_property_collection_begin(ptr, prop, &iter);
1769
1770         if(iter.valid) {
1771                 /* get data from array iterator and item property */
1772                 internal= iter.internal;
1773                 arrayp= (iter.valid)? iter.ptr.data: NULL;
1774
1775                 if(internal->skip || !RNA_property_editable(&iter.ptr, itemprop)) {
1776                         /* we might skip some items, so it's not a proper array */
1777                         RNA_property_collection_end(&iter);
1778                         return 0;
1779                 }
1780
1781                 array->array= arrayp + itemprop->rawoffset;
1782                 array->stride= internal->itemsize;
1783                 array->len= ((char*)internal->endptr - arrayp)/internal->itemsize;
1784                 array->type= itemprop->rawtype;
1785         }
1786         else
1787                 memset(array, 0, sizeof(RawArray));
1788
1789         RNA_property_collection_end(&iter);
1790
1791         return 1;
1792 }
1793
1794 #define RAW_GET(dtype, var, raw, a) \
1795 { \
1796         switch(raw.type) { \
1797                 case PROP_RAW_CHAR: var = (dtype)((char*)raw.array)[a]; break; \
1798                 case PROP_RAW_SHORT: var = (dtype)((short*)raw.array)[a]; break; \
1799                 case PROP_RAW_INT: var = (dtype)((int*)raw.array)[a]; break; \
1800                 case PROP_RAW_FLOAT: var = (dtype)((float*)raw.array)[a]; break; \
1801                 case PROP_RAW_DOUBLE: var = (dtype)((double*)raw.array)[a]; break; \
1802                 default: var = (dtype)0; \
1803         } \
1804 }
1805
1806 #define RAW_SET(dtype, raw, a, var) \
1807 { \
1808         switch(raw.type) { \
1809                 case PROP_RAW_CHAR: ((char*)raw.array)[a] = (char)var; break; \
1810                 case PROP_RAW_SHORT: ((short*)raw.array)[a] = (short)var; break; \
1811                 case PROP_RAW_INT: ((int*)raw.array)[a] = (int)var; break; \
1812                 case PROP_RAW_FLOAT: ((float*)raw.array)[a] = (float)var; break; \
1813                 case PROP_RAW_DOUBLE: ((double*)raw.array)[a] = (double)var; break; \
1814         } \
1815 }
1816
1817 int RNA_raw_type_sizeof(RawPropertyType type)
1818 {
1819         switch(type) {
1820                 case PROP_RAW_CHAR: return sizeof(char);
1821                 case PROP_RAW_SHORT: return sizeof(short);
1822                 case PROP_RAW_INT: return sizeof(int);
1823                 case PROP_RAW_FLOAT: return sizeof(float);
1824                 case PROP_RAW_DOUBLE: return sizeof(double);
1825                 default: return 0;
1826         }
1827 }
1828
1829 static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *inarray, RawPropertyType intype, int inlen, int set)
1830 {
1831         StructRNA *ptype;
1832         PointerRNA itemptr;
1833         PropertyRNA *itemprop, *iprop;
1834         PropertyType itemtype=0;
1835         RawArray in;
1836         int itemlen= 0;
1837
1838         /* initialize in array, stride assumed 0 in following code */
1839         in.array= inarray;
1840         in.type= intype;
1841         in.len= inlen;
1842         in.stride= 0;
1843
1844         ptype= RNA_property_pointer_type(ptr, prop);
1845
1846         /* try to get item property pointer */
1847         RNA_pointer_create(NULL, ptype, NULL, &itemptr);
1848         itemprop= RNA_struct_find_property(&itemptr, propname);
1849
1850         if(itemprop) {
1851                 /* we have item property pointer */
1852                 RawArray out;
1853
1854                 /* check type */
1855                 itemtype= RNA_property_type(itemprop);
1856
1857                 if(!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
1858                         BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported.");
1859                         return 0;
1860                 }
1861
1862                 /* check item array */
1863                 itemlen= RNA_property_array_length(&itemptr, itemprop);
1864
1865                 /* try to access as raw array */
1866                 if(RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
1867                         if(in.len != itemlen*out.len) {
1868                                 BKE_reportf(reports, RPT_ERROR, "Array length mismatch (expected %d, got %d).", out.len*itemlen, in.len);
1869                                 return 0;
1870                         }
1871                         
1872                         /* matching raw types */
1873                         if(out.type == in.type) {
1874                                 void *inp= in.array;
1875                                 void *outp= out.array;
1876                                 int a, size;
1877
1878                                 itemlen= (itemlen == 0)? 1: itemlen;
1879                                 size= RNA_raw_type_sizeof(out.type) * itemlen;
1880
1881                                 for(a=0; a<out.len; a++) {
1882                                         if(set) memcpy(outp, inp, size);
1883                                         else memcpy(inp, outp, size);
1884
1885                                         inp= (char*)inp + size;
1886                                         outp= (char*)outp + out.stride;
1887                                 }
1888
1889                                 return 1;
1890                         }
1891
1892                         /* could also be faster with non-matching types,
1893                          * for now we just do slower loop .. */
1894                 }
1895         }
1896
1897         {
1898                 void *tmparray= NULL;
1899                 int tmplen= 0;
1900                 int err= 0, j, a= 0;
1901
1902                 /* no item property pointer, can still be id property, or
1903                  * property of a type derived from the collection pointer type */
1904                 RNA_PROP_BEGIN(ptr, itemptr, prop) {
1905                         if(itemptr.data) {
1906                                 if(itemprop) {
1907                                         /* we got the property already */
1908                                         iprop= itemprop;
1909                                 }
1910                                 else {
1911                                         /* not yet, look it up and verify if it is valid */
1912                                         iprop= RNA_struct_find_property(&itemptr, propname);
1913
1914                                         if(iprop) {
1915                                                 itemlen= RNA_property_array_length(&itemptr, iprop);
1916                                                 itemtype= RNA_property_type(iprop);
1917                                         }
1918                                         else {
1919                                                 BKE_reportf(reports, RPT_ERROR, "Property named %s not found.", propname);
1920                                                 err= 1;
1921                                                 break;
1922                                         }
1923
1924                                         if(!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
1925                                                 BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported.");
1926                                                 err= 1;
1927                                                 break;
1928                                         }
1929                                 }
1930
1931                                 /* editable check */
1932                                 if(RNA_property_editable(&itemptr, iprop)) {
1933                                         if(a+itemlen > in.len) {
1934                                                 BKE_reportf(reports, RPT_ERROR, "Array length mismatch (got %d, expected more).", in.len);
1935                                                 err= 1;
1936                                                 break;
1937                                         }
1938
1939                                         if(itemlen == 0) {
1940                                                 /* handle conversions */
1941                                                 if(set) {
1942                                                         switch(itemtype) {
1943                                                                 case PROP_BOOLEAN: {
1944                                                                         int b;
1945                                                                         RAW_GET(int, b, in, a);
1946                                                                         RNA_property_boolean_set(&itemptr, iprop, b);
1947                                                                         break;
1948                                                                 }
1949                                                                 case PROP_INT: {
1950                                                                         int i;
1951                                                                         RAW_GET(int, i, in, a);
1952                                                                         RNA_property_int_set(&itemptr, iprop, i);
1953                                                                         break;
1954                                                                 }
1955                                                                 case PROP_FLOAT: {
1956                                                                         float f;
1957                                                                         RAW_GET(float, f, in, a);
1958                                                                         RNA_property_float_set(&itemptr, iprop, f);
1959                                                                         break;
1960                                                                 }
1961                                                                 default:
1962                                                                         break;
1963                                                         }
1964                                                 }
1965                                                 else {
1966                                                         switch(itemtype) {
1967                                                                 case PROP_BOOLEAN: {
1968                                                                         int b= RNA_property_boolean_get(&itemptr, iprop);
1969                                                                         RAW_SET(int, in, a, b);
1970                                                                         break;
1971                                                                 }
1972                                                                 case PROP_INT: {
1973                                                                         int i= RNA_property_int_get(&itemptr, iprop);
1974                                                                         RAW_SET(int, in, a, i);
1975                                                                         break;
1976                                                                 }
1977                                                                 case PROP_FLOAT: {
1978                                                                         float f= RNA_property_float_get(&itemptr, iprop);
1979                                                                         RAW_SET(float, in, a, f);
1980                                                                         break;
1981                                                                 }
1982                                                                 default:
1983                                                                         break;
1984                                                         }
1985                                                 }
1986                                                 a++;
1987                                         }
1988                                         else {
1989                                                 /* allocate temporary array if needed */
1990                                                 if(tmparray && tmplen != itemlen) {
1991                                                         MEM_freeN(tmparray);
1992                                                         tmparray= NULL;
1993                                                 }
1994                                                 if(!tmparray) {
1995                                                         tmparray= MEM_callocN(sizeof(float)*itemlen, "RNA tmparray\n");
1996                                                         tmplen= itemlen;
1997                                                 }
1998
1999                                                 /* handle conversions */
2000                                                 if(set) {
2001                                                         switch(itemtype) {
2002                                                                 case PROP_BOOLEAN: {
2003                                                                         for(j=0; j<itemlen; j++, a++)
2004                                                                                 RAW_GET(int, ((int*)tmparray)[j], in, a);
2005                                                                         RNA_property_boolean_set_array(&itemptr, iprop, tmparray);
2006                                                                         break;
2007                                                                 }
2008                                                                 case PROP_INT: {
2009                                                                         for(j=0; j<itemlen; j++, a++)
2010                                                                                 RAW_GET(int, ((int*)tmparray)[j], in, a);
2011                                                                         RNA_property_int_set_array(&itemptr, iprop, tmparray);
2012                                                                         break;
2013                                                                 }
2014                                                                 case PROP_FLOAT: {
2015                                                                         for(j=0; j<itemlen; j++, a++)
2016                                                                                 RAW_GET(float, ((float*)tmparray)[j], in, a);
2017                                                                         RNA_property_float_set_array(&itemptr, iprop, tmparray);
2018                                                                         break;
2019                                                                 }
2020                                                                 default:
2021                                                                         break;
2022                                                         }
2023                                                 }
2024                                                 else {
2025                                                         switch(itemtype) {
2026                                                                 case PROP_BOOLEAN: {
2027                                                                         RNA_property_boolean_get_array(&itemptr, iprop, tmparray);
2028                                                                         for(j=0; j<itemlen; j++, a++)
2029                                                                                 RAW_SET(int, in, a, ((int*)tmparray)[j]);
2030                                                                         break;
2031                                                                 }
2032                                                                 case PROP_INT: {
2033                                                                         RNA_property_int_get_array(&itemptr, iprop, tmparray);
2034                                                                         for(j=0; j<itemlen; j++, a++)
2035                                                                                 RAW_SET(int, in, a, ((int*)tmparray)[j]);
2036                                                                         break;
2037                                                                 }
2038                                                                 case PROP_FLOAT: {
2039                                                                         RNA_property_float_get_array(&itemptr, iprop, tmparray);
2040                                                                         for(j=0; j<itemlen; j++, a++)
2041                                                                                 RAW_SET(float, in, a, ((float*)tmparray)[j]);
2042                                                                         break;
2043                                                                 }
2044                                                                 default:
2045                                                                         break;
2046                                                         }
2047                                                 }
2048                                         }
2049                                 }
2050                         }
2051                 }
2052                 RNA_PROP_END;
2053
2054                 if(tmparray)
2055                         MEM_freeN(tmparray);
2056
2057                 return !err;
2058         }
2059 }
2060
2061 RawPropertyType RNA_property_raw_type(PropertyRNA *prop)
2062 {
2063         return prop->rawtype;
2064 }
2065
2066 int RNA_property_collection_raw_get(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *array, RawPropertyType type, int len)
2067 {
2068         return rna_raw_access(reports, ptr, prop, propname, array, type, len, 0);
2069 }
2070
2071 int RNA_property_collection_raw_set(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, char *propname, void *array, RawPropertyType type, int len)
2072 {
2073         return rna_raw_access(reports, ptr, prop, propname, array, type, len, 1);
2074 }
2075
2076 /* Standard iterator functions */
2077
2078 void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip)
2079 {
2080         ListBaseIterator *internal;
2081
2082         internal= MEM_callocN(sizeof(ListBaseIterator), "ListBaseIterator");
2083         internal->link= (lb)? lb->first: NULL;
2084         internal->skip= skip;
2085
2086         iter->internal= internal;
2087         iter->valid= (internal->link != NULL);
2088
2089         if(skip && iter->valid && skip(iter, internal->link))
2090                 rna_iterator_listbase_next(iter);
2091 }
2092
2093 void rna_iterator_listbase_next(CollectionPropertyIterator *iter)
2094 {
2095         ListBaseIterator *internal= iter->internal;
2096
2097         if(internal->skip) {
2098                 do {
2099                         internal->link= internal->link->next;
2100                         iter->valid= (internal->link != NULL);
2101                 } while(iter->valid && internal->skip(iter, internal->link));
2102         }
2103         else {
2104                 internal->link= internal->link->next;
2105                 iter->valid= (internal->link != NULL);
2106         }
2107 }
2108
2109 void *rna_iterator_listbase_get(CollectionPropertyIterator *iter)
2110 {
2111         ListBaseIterator *internal= iter->internal;
2112
2113         return internal->link;
2114 }
2115
2116 void rna_iterator_listbase_end(CollectionPropertyIterator *iter)
2117 {
2118         MEM_freeN(iter->internal);
2119         iter->internal= NULL;
2120 }
2121
2122 void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int itemsize, int length, int free_ptr, IteratorSkipFunc skip)
2123 {
2124         ArrayIterator *internal;
2125
2126         if(ptr == NULL)
2127                 length= 0;
2128
2129         internal= MEM_callocN(sizeof(ArrayIterator), "ArrayIterator");
2130         internal->ptr= ptr;
2131         internal->free_ptr= free_ptr ? ptr:NULL;
2132         internal->endptr= ((char*)ptr)+length*itemsize;
2133         internal->itemsize= itemsize;
2134         internal->skip= skip;
2135
2136         iter->internal= internal;
2137         iter->valid= (internal->ptr != internal->endptr);
2138
2139         if(skip && iter->valid && skip(iter, internal->ptr))
2140                 rna_iterator_array_next(iter);
2141 }
2142
2143 void rna_iterator_array_next(CollectionPropertyIterator *iter)
2144 {
2145         ArrayIterator *internal= iter->internal;
2146
2147         if(internal->skip) {
2148                 do {
2149                         internal->ptr += internal->itemsize;
2150                         iter->valid= (internal->ptr != internal->endptr);
2151                 } while(iter->valid && internal->skip(iter, internal->ptr));
2152         }
2153         else {
2154                 internal->ptr += internal->itemsize;
2155                 iter->valid= (internal->ptr != internal->endptr);
2156         }
2157 }
2158
2159 void *rna_iterator_array_get(CollectionPropertyIterator *iter)
2160 {
2161         ArrayIterator *internal= iter->internal;
2162
2163         return internal->ptr;
2164 }
2165
2166 void *rna_iterator_array_dereference_get(CollectionPropertyIterator *iter)
2167 {
2168         ArrayIterator *internal= iter->internal;
2169
2170         /* for ** arrays */
2171         return *(void**)(internal->ptr);
2172 }
2173
2174 void rna_iterator_array_end(CollectionPropertyIterator *iter)
2175 {
2176         ArrayIterator *internal= iter->internal;
2177         
2178         if(internal->free_ptr) {
2179                 MEM_freeN(internal->free_ptr);
2180                 internal->free_ptr= NULL;
2181         }
2182         MEM_freeN(iter->internal);
2183         iter->internal= NULL;
2184 }
2185
2186 /* RNA Path - Experiment */
2187
2188 static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int bracket)
2189 {
2190         const char *p;
2191         char *buf;
2192         int i, j, len, escape;
2193
2194         len= 0;
2195
2196         if(bracket) {
2197                 /* get data between [], check escaping ] with \] */
2198                 if(**path == '[') (*path)++;
2199                 else return NULL;
2200
2201                 p= *path;
2202
2203                 escape= 0;
2204                 while(*p && (*p != ']' || escape)) {
2205                         escape= (*p == '\\');
2206                         len++;
2207                         p++;
2208                 }
2209
2210                 if(*p != ']') return NULL;
2211         }
2212         else {
2213                 /* get data until . or [ */
2214                 p= *path;
2215
2216                 while(*p && *p != '.' && *p != '[') {
2217                         len++;
2218                         p++;
2219                 }
2220         }
2221         
2222         /* empty, return */
2223         if(len == 0)
2224                 return NULL;
2225         
2226         /* try to use fixed buffer if possible */
2227         if(len+1 < fixedlen)
2228                 buf= fixedbuf;
2229         else
2230                 buf= MEM_callocN(sizeof(char)*(len+1), "rna_path_token");
2231
2232         /* copy string, taking into account escaped ] */
2233         if(bracket) {
2234                 for(p=*path, i=0, j=0; i<len; i++, p++) {
2235                         if(*p == '\\' && *(p+1) == ']');
2236                         else buf[j++]= *p;
2237                 }
2238
2239                 buf[j]= 0;
2240         }
2241         else {
2242                 memcpy(buf, *path, sizeof(char)*len);
2243                 buf[len]= '\0';
2244         }
2245
2246         /* set path to start of next token */
2247         if(*p == ']') p++;
2248         if(*p == '.') p++;
2249         *path= p;
2250
2251         return buf;
2252 }
2253
2254 /* Resolve the given RNA path to find the pointer+property indicated at the end of the path */
2255 int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
2256 {
2257         PropertyRNA *prop;
2258         PointerRNA curptr, nextptr;
2259         char fixedbuf[256], *token;
2260         int len, intkey;
2261
2262         prop= NULL;
2263         curptr= *ptr;
2264
2265         if(path==NULL)
2266                 return 0;
2267
2268         while(*path) {
2269                 /* look up property name in current struct */
2270                 token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 0);
2271
2272                 if(!token)
2273                         return 0;
2274
2275                 prop= RNA_struct_find_property(&curptr, token);
2276
2277                 if(token != fixedbuf)
2278                         MEM_freeN(token);
2279
2280                 if(!prop)
2281                         return 0;
2282
2283                 /* now look up the value of this property if it is a pointer or
2284                  * collection, otherwise return the property rna so that the
2285                  * caller can read the value of the property itself */
2286                 if(RNA_property_type(prop) == PROP_POINTER) {
2287                         nextptr= RNA_property_pointer_get(&curptr, prop);
2288
2289                         if(nextptr.data)
2290                                 curptr= nextptr;
2291                         else
2292                                 return 0;
2293                 }
2294                 else if(RNA_property_type(prop) == PROP_COLLECTION && *path) {
2295                         /* resolve the lookup with [] brackets */
2296                         token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1);
2297
2298                         if(!token)
2299                                 return 0;
2300
2301                         len= strlen(token);
2302                         
2303                         /* check for "" to see if it is a string */
2304                         if(len >= 2 && token[0] == '"' && token[len-1] == '"') {
2305                                 /* strip away "" */
2306                                 token[len-1]= 0;
2307                                 RNA_property_collection_lookup_string(&curptr, prop, token+1, &nextptr);
2308                         }
2309                         else {
2310                                 /* otherwise do int lookup */
2311                                 intkey= atoi(token);
2312                                 RNA_property_collection_lookup_int(&curptr, prop, intkey, &nextptr);
2313                         }
2314
2315                         if(token != fixedbuf)
2316                                 MEM_freeN(token);
2317
2318                         if(nextptr.data)
2319                                 curptr= nextptr;
2320                         else
2321                                 return 0;
2322                 }
2323         }
2324
2325         *r_ptr= curptr;
2326         *r_prop= prop;
2327
2328         return 1;
2329 }
2330
2331 char *RNA_path_append(const char *path, PointerRNA *ptr, PropertyRNA *prop, int intkey, const char *strkey)
2332 {
2333         DynStr *dynstr;
2334         const char *s;
2335         char appendstr[128], *result;
2336         
2337         dynstr= BLI_dynstr_new();
2338
2339         /* add .identifier */
2340         if(path) {
2341                 BLI_dynstr_append(dynstr, (char*)path);
2342                 if(*path)
2343                         BLI_dynstr_append(dynstr, ".");
2344         }
2345
2346         BLI_dynstr_append(dynstr, (char*)RNA_property_identifier(prop));
2347
2348         if(RNA_property_type(prop) == PROP_COLLECTION) {
2349                 /* add ["strkey"] or [intkey] */
2350                 BLI_dynstr_append(dynstr, "[");
2351
2352                 if(strkey) {
2353                         BLI_dynstr_append(dynstr, "\"");
2354                         for(s=strkey; *s; s++) {
2355                                 if(*s == '[') {
2356                                         appendstr[0]= '\\';
2357                                         appendstr[1]= *s;
2358                                         appendstr[2]= 0;
2359                                 }
2360                                 else {
2361                                         appendstr[0]= *s;
2362                                         appendstr[1]= 0;
2363                                 }
2364                                 BLI_dynstr_append(dynstr, appendstr);
2365                         }
2366                         BLI_dynstr_append(dynstr, "\"");
2367                 }
2368                 else {
2369                         sprintf(appendstr, "%d", intkey);
2370                         BLI_dynstr_append(dynstr, appendstr);
2371                 }
2372
2373                 BLI_dynstr_append(dynstr, "]");
2374         }
2375
2376         result= BLI_dynstr_get_cstring(dynstr);
2377         BLI_dynstr_free(dynstr);
2378
2379         return result;
2380 }
2381
2382 char *RNA_path_back(const char *path)
2383 {
2384         char fixedbuf[256];
2385         const char *previous, *current;
2386         char *result, *token;
2387         int i;
2388
2389         if(!path)
2390                 return NULL;
2391
2392         previous= NULL;
2393         current= path;
2394
2395         /* parse token by token until the end, then we back up to the previous
2396          * position and strip of the next token to get the path one step back */
2397         while(*current) {
2398                 token= rna_path_token(&current, fixedbuf, sizeof(fixedbuf), 0);
2399
2400                 if(!token)
2401                         return NULL;
2402                 if(token != fixedbuf)
2403                         MEM_freeN(token);
2404
2405                 /* in case of collection we also need to strip off [] */
2406                 token= rna_path_token(&current, fixedbuf, sizeof(fixedbuf), 1);
2407                 if(token && token != fixedbuf)
2408                         MEM_freeN(token);
2409                 
2410                 if(!*current)
2411                         break;
2412
2413                 previous= current;
2414         }
2415
2416         if(!previous)
2417                 return NULL;
2418
2419         /* copy and strip off last token */
2420         i= previous - path;
2421         result= BLI_strdup(path);
2422
2423         if(i > 0 && result[i-1] == '.') i--;
2424         result[i]= 0;
2425
2426         return result;
2427 }
2428
2429 char *RNA_path_from_ID_to_struct(PointerRNA *ptr)
2430 {
2431         char *ptrpath=NULL;
2432
2433         if(!ptr->id.data || !ptr->data)
2434                 return NULL;
2435         
2436         if(!RNA_struct_is_ID(ptr->type)) {
2437                 if(ptr->type->path) {
2438                         /* if type has a path to some ID, use it */
2439                         ptrpath= ptr->type->path(ptr);
2440                 }
2441                 else if(ptr->type->nested && RNA_struct_is_ID(ptr->type->nested)) {
2442                         PointerRNA parentptr;
2443                         PropertyRNA *userprop;
2444                         
2445                         /* find the property in the struct we're nested in that references this struct, and 
2446                          * use its identifier as the first part of the path used...
2447                          */
2448                         RNA_id_pointer_create(ptr->id.data, &parentptr);
2449                         userprop= RNA_struct_find_nested(&parentptr, ptr->type); 
2450                         
2451                         if(userprop)
2452                                 ptrpath= BLI_strdup(RNA_property_identifier(userprop));
2453                         else
2454                                 return NULL; // can't do anything about this case yet...
2455                 }
2456                 else
2457                         return NULL;
2458         }
2459         
2460         return ptrpath;
2461 }
2462
2463 char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop)
2464 {
2465         const char *propname;
2466         char *ptrpath, *path;
2467
2468         if(!ptr->id.data || !ptr->data || !prop)
2469                 return NULL;
2470         
2471         /* path from ID to the struct holding this property */
2472         ptrpath= RNA_path_from_ID_to_struct(ptr);
2473
2474         propname= RNA_property_identifier(prop);
2475
2476         if(ptrpath) {
2477                 path= BLI_sprintfN("%s.%s", ptrpath, propname);
2478                 MEM_freeN(ptrpath);
2479         }
2480         else
2481                 path= BLI_strdup(propname);
2482         
2483         return path;
2484 }
2485
2486 /* Quick name based property access */
2487
2488 int RNA_boolean_get(PointerRNA *ptr, const char *name)
2489 {
2490         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2491
2492         if(prop) {
2493                 return RNA_property_boolean_get(ptr, prop);
2494         }
2495         else {
2496                 printf("RNA_boolean_get: %s.%s not found.\n", ptr->type->identifier, name);
2497                 return 0;
2498         }
2499 }
2500
2501 void RNA_boolean_set(PointerRNA *ptr, const char *name, int value)
2502 {
2503         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2504
2505         if(prop)
2506                 RNA_property_boolean_set(ptr, prop, value);
2507         else
2508                 printf("RNA_boolean_set: %s.%s not found.\n", ptr->type->identifier, name);
2509 }
2510
2511 void RNA_boolean_get_array(PointerRNA *ptr, const char *name, int *values)
2512 {
2513         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2514
2515         if(prop)
2516                 RNA_property_boolean_get_array(ptr, prop, values);
2517         else
2518                 printf("RNA_boolean_get_array: %s.%s not found.\n", ptr->type->identifier, name);
2519 }
2520
2521 void RNA_boolean_set_array(PointerRNA *ptr, const char *name, const int *values)
2522 {
2523         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2524
2525         if(prop)
2526                 RNA_property_boolean_set_array(ptr, prop, values);
2527         else
2528                 printf("RNA_boolean_set_array: %s.%s not found.\n", ptr->type->identifier, name);
2529 }
2530
2531 int RNA_int_get(PointerRNA *ptr, const char *name)
2532 {
2533         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2534
2535         if(prop) {
2536                 return RNA_property_int_get(ptr, prop);
2537         }
2538         else {
2539                 printf("RNA_int_get: %s.%s not found.\n", ptr->type->identifier, name);
2540                 return 0;
2541         }
2542 }
2543
2544 void RNA_int_set(PointerRNA *ptr, const char *name, int value)
2545 {
2546         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2547
2548         if(prop)
2549                 RNA_property_int_set(ptr, prop, value);
2550         else
2551                 printf("RNA_int_set: %s.%s not found.\n", ptr->type->identifier, name);
2552 }
2553
2554 void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values)
2555 {
2556         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2557
2558         if(prop)
2559                 RNA_property_int_get_array(ptr, prop, values);
2560         else
2561                 printf("RNA_int_get_array: %s.%s not found.\n", ptr->type->identifier, name);
2562 }
2563
2564 void RNA_int_set_array(PointerRNA *ptr, const char *name, const int *values)
2565 {
2566         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2567
2568         if(prop)
2569                 RNA_property_int_set_array(ptr, prop, values);
2570         else
2571                 printf("RNA_int_set_array: %s.%s not found.\n", ptr->type->identifier, name);
2572 }
2573
2574 float RNA_float_get(PointerRNA *ptr, const char *name)
2575 {
2576         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2577
2578         if(prop) {
2579                 return RNA_property_float_get(ptr, prop);
2580         }
2581         else {
2582                 printf("RNA_float_get: %s.%s not found.\n", ptr->type->identifier, name);
2583                 return 0;
2584         }
2585 }
2586
2587 void RNA_float_set(PointerRNA *ptr, const char *name, float value)
2588 {
2589         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2590
2591         if(prop)
2592                 RNA_property_float_set(ptr, prop, value);
2593         else
2594                 printf("RNA_float_set: %s.%s not found.\n", ptr->type->identifier, name);
2595 }
2596
2597 void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
2598 {
2599         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2600
2601         if(prop)
2602                 RNA_property_float_get_array(ptr, prop, values);
2603         else
2604                 printf("RNA_float_get_array: %s.%s not found.\n", ptr->type->identifier, name);
2605 }
2606
2607 void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
2608 {
2609         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2610
2611         if(prop)
2612                 RNA_property_float_set_array(ptr, prop, values);
2613         else
2614                 printf("RNA_float_set_array: %s.%s not found.\n", ptr->type->identifier, name);
2615 }
2616
2617 int RNA_enum_get(PointerRNA *ptr, const char *name)
2618 {
2619         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2620
2621         if(prop) {
2622                 return RNA_property_enum_get(ptr, prop);
2623         }
2624         else {
2625                 printf("RNA_enum_get: %s.%s not found.\n", ptr->type->identifier, name);
2626                 return 0;
2627         }
2628 }
2629
2630 void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
2631 {
2632         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2633
2634         if(prop)
2635                 RNA_property_enum_set(ptr, prop, value);
2636         else
2637                 printf("RNA_enum_set: %s.%s not found.\n", ptr->type->identifier, name);
2638 }
2639
2640 int RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const char *enumname)
2641 {
2642         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2643         EnumPropertyItem *item;
2644         int free;
2645
2646         if(prop) {
2647                 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
2648
2649                 for(; item->identifier; item++)
2650                         if(strcmp(item->identifier, enumname) == 0)
2651                                 return (item->value == RNA_property_enum_get(ptr, prop));
2652
2653                 if(free)
2654                         MEM_freeN(item);
2655
2656                 printf("RNA_enum_is_equal: %s.%s item %s not found.\n", ptr->type->identifier, name, enumname);
2657                 return 0;
2658         }
2659         else {
2660                 printf("RNA_enum_is_equal: %s.%s not found.\n", ptr->type->identifier, name);
2661                 return 0;
2662         }
2663 }
2664
2665 int RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value)
2666 {
2667         for( ; item->identifier; item++) {
2668                 if(strcmp(item->identifier, identifier)==0) {
2669                         *value= item->value;
2670                         return 1;
2671                 }
2672         }
2673         
2674         return 0;
2675 }
2676
2677 int     RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **identifier)
2678 {
2679         for( ; item->identifier; item++) {
2680                 if(item->value==value) {
2681                         *identifier= item->identifier;
2682                         return 1;
2683                 }
2684         }
2685
2686         return 0;
2687 }
2688
2689
2690
2691 void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
2692 {
2693         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2694
2695         if(prop)
2696                 RNA_property_string_get(ptr, prop, value);
2697         else
2698                 printf("RNA_string_get: %s.%s not found.\n", ptr->type->identifier, name);
2699 }
2700
2701 char *RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen)
2702 {
2703         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2704
2705         if(prop) {
2706                 return RNA_property_string_get_alloc(ptr, prop, fixedbuf, fixedlen);
2707         }
2708         else {
2709                 printf("RNA_string_get_alloc: %s.%s not found.\n", ptr->type->identifier, name);
2710                 return 0;
2711         }
2712 }
2713
2714 int RNA_string_length(PointerRNA *ptr, const char *name)
2715 {
2716         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2717
2718         if(prop) {
2719                 return RNA_property_string_length(ptr, prop);
2720         }
2721         else {
2722                 printf("RNA_string_length: %s.%s not found.\n", ptr->type->identifier, name);
2723                 return 0;
2724         }
2725 }
2726
2727 void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
2728 {
2729         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2730
2731         if(prop)
2732                 RNA_property_string_set(ptr, prop, value);
2733         else
2734                 printf("RNA_string_set: %s.%s not found.\n", ptr->type->identifier, name);
2735 }
2736
2737 PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
2738 {
2739         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2740
2741         if(prop) {
2742                 return RNA_property_pointer_get(ptr, prop);
2743         }
2744         else {
2745                 PointerRNA result;
2746
2747                 printf("RNA_pointer_get: %s.%s not found.\n", ptr->type->identifier, name);
2748
2749                 memset(&result, 0, sizeof(result));
2750                 return result;
2751         }
2752 }
2753
2754 void RNA_pointer_set(PointerRNA *ptr, const char *name, PointerRNA ptr_value)
2755 {
2756         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2757
2758         if(prop) {
2759                 RNA_property_pointer_set(ptr, prop, ptr_value);
2760         }
2761         else {
2762                 printf("RNA_pointer_set: %s.%s not found.\n", ptr->type->identifier, name);
2763         }
2764 }
2765
2766 void RNA_pointer_add(PointerRNA *ptr, const char *name)
2767 {
2768         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2769
2770         if(prop)
2771                 RNA_property_pointer_add(ptr, prop);
2772         else
2773                 printf("RNA_pointer_set: %s.%s not found.\n", ptr->type->identifier, name);
2774 }
2775
2776 void RNA_collection_begin(PointerRNA *ptr, const char *name, CollectionPropertyIterator *iter)
2777 {
2778         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2779
2780         if(prop)
2781                 RNA_property_collection_begin(ptr, prop, iter);
2782         else
2783                 printf("RNA_collection_begin: %s.%s not found.\n", ptr->type->identifier, name);
2784 }
2785
2786 void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value)
2787 {
2788         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2789
2790         if(prop)
2791                 RNA_property_collection_add(ptr, prop, r_value);
2792         else
2793                 printf("RNA_collection_add: %s.%s not found.\n", ptr->type->identifier, name);
2794 }
2795
2796 void RNA_collection_clear(PointerRNA *ptr, const char *name)
2797 {
2798         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2799
2800         if(prop)
2801                 RNA_property_collection_clear(ptr, prop);
2802         else
2803                 printf("RNA_collection_clear: %s.%s not found.\n", ptr->type->identifier, name);
2804 }
2805
2806 int RNA_collection_length(PointerRNA *ptr, const char *name)
2807 {
2808         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2809
2810         if(prop) {
2811                 return RNA_property_collection_length(ptr, prop);
2812         }
2813         else {
2814                 printf("RNA_collection_length: %s.%s not found.\n", ptr->type->identifier, name);
2815                 return 0;
2816         }
2817 }
2818
2819 int RNA_property_is_set(PointerRNA *ptr, const char *name)
2820 {
2821         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2822
2823         if(prop) {
2824                 if(prop->flag & PROP_IDPROPERTY)
2825                         return (rna_idproperty_find(ptr, name) != NULL);
2826                 else
2827                         return 1;
2828         }
2829         else {
2830                 // printf("RNA_property_is_set: %s.%s not found.\n", ptr->type->identifier, name);
2831                 return 0;
2832         }
2833 }
2834
2835 /* string representation of a property, python
2836  * compatible but can be used for display too*/
2837 char *RNA_pointer_as_string(PointerRNA *ptr)
2838 {
2839         DynStr *dynstr= BLI_dynstr_new();
2840         char *cstring;
2841         
2842         const char *propname;
2843         int first_time = 1;
2844         
2845         BLI_dynstr_append(dynstr, "{");
2846         
2847         RNA_STRUCT_BEGIN(ptr, prop) {
2848                 propname = RNA_property_identifier(prop);
2849                 
2850                 if(strcmp(propname, "rna_type")==0)
2851                         continue;
2852                 
2853                 if(first_time==0)
2854                         BLI_dynstr_append(dynstr, ", ");
2855                 first_time= 0;
2856                 
2857                 cstring = RNA_property_as_string(NULL, ptr, prop);
2858                 BLI_dynstr_appendf(dynstr, "\"%s\":%s", propname, cstring);
2859                 MEM_freeN(cstring);
2860         }
2861         RNA_STRUCT_END;
2862
2863         BLI_dynstr_append(dynstr, "}"); 
2864         
2865         
2866         cstring = BLI_dynstr_get_cstring(dynstr);
2867         BLI_dynstr_free(dynstr);
2868         return cstring;
2869 }
2870
2871 char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
2872 {
2873         int type = RNA_property_type(prop);
2874         int len = RNA_property_array_length(ptr, prop);
2875         int i;
2876
2877         DynStr *dynstr= BLI_dynstr_new();
2878         char *cstring;
2879         
2880
2881         /* see if we can coorce into a python type - PropertyType */
2882         switch (type) {
2883         case PROP_BOOLEAN:
2884                 if(len==0) {
2885                         BLI_dynstr_append(dynstr, RNA_property_boolean_get(ptr, prop) ? "True" : "False");
2886                 }
2887                 else {
2888                         BLI_dynstr_append(dynstr, "(");
2889                         for(i=0; i<len; i++) {
2890                                 BLI_dynstr_appendf(dynstr, i?", %s":"%s", RNA_property_boolean_get_index(ptr, prop, i) ? "True" : "False");
2891                         }
2892                         if(len==1)
2893                                 BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
2894                         BLI_dynstr_append(dynstr, ")");
2895                 }
2896                 break;
2897         case PROP_INT:
2898                 if(len==0) {
2899                         BLI_dynstr_appendf(dynstr, "%d", RNA_property_int_get(ptr, prop));
2900                 }
2901                 else {
2902                         BLI_dynstr_append(dynstr, "(");
2903                         for(i=0; i<len; i++) {
2904                                 BLI_dynstr_appendf(dynstr, i?", %d":"%d", RNA_property_int_get_index(ptr, prop, i));
2905                         }
2906                         if(len==1)
2907                                 BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
2908                         BLI_dynstr_append(dynstr, ")");
2909                 }
2910                 break;
2911         case PROP_FLOAT:
2912                 if(len==0) {
2913                         BLI_dynstr_appendf(dynstr, "%g", RNA_property_float_get(ptr, prop));
2914                 }
2915                 else {
2916                         BLI_dynstr_append(dynstr, "(");
2917                         for(i=0; i<len; i++) {
2918                                 BLI_dynstr_appendf(dynstr, i?", %g":"%g", RNA_property_float_get_index(ptr, prop, i));
2919                         }
2920                         if(len==1)
2921                                 BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
2922                         BLI_dynstr_append(dynstr, ")");
2923                 }
2924                 break;
2925         case PROP_STRING:
2926         {
2927                 /* string arrays dont exist */
2928                 char *buf;
2929                 buf = RNA_property_string_get_alloc(ptr, prop, NULL, -1);
2930                 BLI_dynstr_appendf(dynstr, "\"%s\"", buf);
2931                 MEM_freeN(buf);
2932                 break;
2933         }
2934         case PROP_ENUM:
2935         {
2936                 /* string arrays dont exist */
2937                 const char *identifier;
2938                 int val = RNA_property_enum_get(ptr, prop);
2939
2940                 if(RNA_property_enum_identifier(C, ptr, prop, val, &identifier)) {
2941                         BLI_dynstr_appendf(dynstr, "'%s'", identifier);
2942                 }
2943                 else {
2944                         BLI_dynstr_appendf(dynstr, "'<UNKNOWN ENUM>'", identifier);
2945                 }
2946                 break;
2947         }
2948         case PROP_POINTER:
2949         {
2950                 BLI_dynstr_append(dynstr, "'<POINTER>'"); /* TODO */
2951                 break;
2952         }
2953         case PROP_COLLECTION:
2954         {
2955                 int first_time = 1;
2956                 CollectionPropertyIterator collect_iter;
2957                 BLI_dynstr_append(dynstr, "[");
2958                 
2959                 for(RNA_property_collection_begin(ptr, prop, &collect_iter); collect_iter.valid; RNA_property_collection_next(&collect_iter)) {
2960                         PointerRNA itemptr= collect_iter.ptr;
2961                         
2962                         if(first_time==0)
2963                                 BLI_dynstr_append(dynstr, ", ");
2964                         first_time= 0;
2965                         
2966                         /* now get every prop of the collection */
2967                         cstring= RNA_pointer_as_string(&itemptr);
2968                         BLI_dynstr_append(dynstr, cstring);
2969                         MEM_freeN(cstring);
2970                 }
2971                 
2972                 RNA_property_collection_end(&collect_iter);
2973                 BLI_dynstr_append(dynstr, "]");
2974                 break;
2975         }
2976         default:
2977                 BLI_dynstr_append(dynstr, "'<UNKNOWN TYPE>'"); /* TODO */
2978                 break;
2979         }
2980
2981         cstring = BLI_dynstr_get_cstring(dynstr);
2982         BLI_dynstr_free(dynstr);
2983         return cstring;
2984 }
2985
2986 /* Function */
2987
2988 const char *RNA_function_identifier(FunctionRNA *func)
2989 {
2990         return func->identifier;
2991 }
2992
2993 PropertyRNA *RNA_function_return(FunctionRNA *func)
2994 {
2995         return func->ret;
2996 }
2997
2998 const char *RNA_function_ui_description(FunctionRNA *func)
2999 {
3000         return func->description;
3001 }
3002
3003 int RNA_function_flag(FunctionRNA *func)
3004 {
3005         return func->flag;
3006 }
3007
3008 PropertyRNA *RNA_function_get_parameter(PointerRNA *ptr, FunctionRNA *func, int index)
3009 {
3010         PropertyRNA *parm;
3011         int i;
3012
3013         parm= func->cont.properties.first;
3014         for(i= 0; parm; parm= parm->next, i++)
3015                 if(i==index)
3016                         return parm;
3017
3018         return NULL;
3019 }
3020
3021 PropertyRNA *RNA_function_find_parameter(PointerRNA *ptr, FunctionRNA *func, const char *identifier)
3022 {
3023         PropertyRNA *parm;
3024
3025         parm= func->cont.properties.first;
3026         for(; parm; parm= parm->next)
3027                 if(strcmp(parm->identifier, identifier)==0)
3028                         return parm;
3029
3030         return NULL;
3031 }
3032
3033 const struct ListBase *RNA_function_defined_parameters(FunctionRNA *func)
3034 {
3035         return &func->cont.properties;
3036 }
3037
3038 /* Utility */
3039
3040 ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *ptr, FunctionRNA *func)
3041 {
3042         PropertyRNA *parm;
3043         void *data;
3044         int tot= 0, size;
3045
3046         /* allocate data */
3047         for(parm= func->cont.properties.first; parm; parm= parm->next)
3048                 tot+= rna_parameter_size(parm);
3049
3050         parms->data= MEM_callocN(tot, "RNA_parameter_list_create");
3051         parms->func= func;
3052         parms->tot= tot;
3053
3054         /* set default values */
3055         data= parms->data;
3056
3057         for(parm= func->cont.properties.first; parm; parm= parm->next) {
3058                 size= rna_parameter_size(parm);
3059
3060                 if(!(parm->flag & PROP_REQUIRED)) {
3061                         switch(parm->type) {
3062                                 case PROP_BOOLEAN:
3063                                         if(parm->arraydimension) memcpy(data, &((BooleanPropertyRNA*)parm)->defaultarray, size);
3064                                         else memcpy(data, &((BooleanPropertyRNA*)parm)->defaultvalue, size);
3065                                         break;
3066                                 case PROP_INT:
3067                                         if(parm->arraydimension) memcpy(data, &((IntPropertyRNA*)parm)->defaultarray, size);
3068                                         else memcpy(data, &((IntPropertyRNA*)parm)->defaultvalue, size);
3069                                         break;
3070                                 case PROP_FLOAT:
3071                                         if(parm->arraydimension) memcpy(data, &((FloatPropertyRNA*)parm)->defaultarray, size);
3072                                         else memcpy(data, &((FloatPropertyRNA*)parm)->defaultvalue, size);
3073                                         break;
3074                                 case PROP_ENUM:
3075                                         memcpy(data, &((EnumPropertyRNA*)parm)->defaultvalue, size);
3076                                         break;
3077                                 case PROP_STRING: {
3078                                         const char *defvalue= ((StringPropertyRNA*)parm)->defaultvalue;
3079                                         if(defvalue && defvalue[0])
3080                                                 memcpy(data, &defvalue, size);
3081                                         break;
3082                                 }
3083                                 case PROP_POINTER:
3084                                 case PROP_COLLECTION:
3085                                         break;
3086                         }
3087                 }
3088
3089                 data= ((char*)data) + size;
3090         }
3091
3092         return parms;
3093 }
3094
3095 void RNA_parameter_list_free(ParameterList *parms)
3096 {
3097         PropertyRNA *parm;
3098         int tot;
3099
3100         parm= parms->func->cont.properties.first;
3101         for(tot= 0; parm; parm= parm->next) {
3102                 if(parm->type == PROP_COLLECTION)
3103                         BLI_freelistN((ListBase*)((char*)parms->data+tot));
3104                 else if (parm->flag & PROP_DYNAMIC) {
3105                         /* for dynamic arrays and strings, data is a pointer to an array */
3106                         char *array= *(char**)((char*)parms->data+tot);
3107                         if(array)
3108                                 MEM_freeN(array);
3109                 }
3110
3111                 tot+= rna_parameter_size(parm);
3112         }
3113
3114         MEM_freeN(parms->data);
3115         parms->data= NULL;
3116
3117         parms->func= NULL;
3118 }
3119
3120 int  RNA_parameter_list_size(ParameterList *parms)
3121 {
3122         return parms->tot;
3123 }
3124
3125 void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter)
3126 {
3127         PropertyType ptype;
3128
3129         RNA_pointer_create(NULL, &RNA_Function, parms->func, &iter->funcptr);
3130
3131         iter->parms= parms;
3132         iter->parm= parms->func->cont.properties.first;
3133         iter->valid= iter->parm != NULL;
3134         iter->offset= 0;
3135
3136         if(iter->valid) {
3137                 iter->size= rna_parameter_size(iter->parm);
3138                 iter->data= (((char*)iter->parms->data)+iter->offset);
3139                 ptype= RNA_property_type(iter->parm);
3140         }
3141 }
3142
3143 void RNA_parameter_list_next(ParameterIterator *iter)
3144 {
3145         PropertyType ptype;
3146
3147         iter->offset+= iter->size;
3148         iter->parm= iter->parm->next;
3149         iter->valid= iter->parm != NULL;
3150
3151         if(iter->valid) {
3152                 iter->size= rna_parameter_size(iter->parm);
3153                 iter->data= (((char*)iter->parms->data)+iter->offset);
3154                 ptype= RNA_property_type(iter->parm);
3155         }
3156 }
3157
3158 void RNA_parameter_list_end(ParameterIterator *iter)
3159 {
3160         /* nothing to do */
3161 }
3162
3163 void RNA_parameter_get(ParameterList *parms, PropertyRNA *parm, void **value)
3164 {
3165         ParameterIterator iter;
3166
3167         RNA_parameter_list_begin(parms, &iter);
3168
3169         for(; iter.valid; RNA_parameter_list_next(&iter))
3170                 if(iter.parm==parm) 
3171                         break;
3172
3173         if(iter.valid)
3174                 *value= iter.data;
3175         else
3176                 *value= NULL;
3177
3178         RNA_parameter_list_end(&iter);
3179 }
3180
3181 void RNA_parameter_get_lookup(ParameterList *parms, const char *identifier, void **value)
3182 {
3183         PropertyRNA *parm;
3184
3185         parm= parms->func->cont.properties.first;
3186         for(; parm; parm= parm->next)
3187                 if(strcmp(RNA_property_identifier(parm), identifier)==0)
3188                         break;
3189
3190         if(parm)
3191                 RNA_parameter_get(parms, parm, value);
3192 }
3193
3194 void RNA_parameter_set(ParameterList *parms, PropertyRNA *parm, void *value)
3195 {
3196         ParameterIterator iter;
3197
3198         RNA_parameter_list_begin(parms, &iter);
3199
3200         for(; iter.valid; RNA_parameter_list_next(&iter))
3201                 if(iter.parm==parm) 
3202                         break;
3203
3204         if(iter.valid)
3205                 memcpy(iter.data, value, iter.size);
3206
3207         RNA_parameter_list_end(&iter);
3208 }
3209
3210 void RNA_parameter_set_lookup(ParameterList *parms, const char *identifier, void *value)
3211 {
3212         PropertyRNA *parm;
3213
3214         parm= parms->func->cont.properties.first;
3215         for(; parm; parm= parm->next)
3216                 if(strcmp(RNA_property_identifier(parm), identifier)==0)
3217                         break;
3218
3219         if(parm)
3220                 RNA_parameter_set(parms, parm, value);
3221 }
3222
3223 int RNA_function_call(bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
3224 {
3225         if(func->call) {
3226                 func->call(C, reports, ptr, parms);
3227
3228                 return 0;
3229         }
3230
3231         return -1;
3232 }
3233
3234 int RNA_function_call_lookup(bContext *C, ReportList *reports, PointerRNA *ptr, const char *identifier, ParameterList *parms)
3235 {
3236         FunctionRNA *func;
3237
3238         func= RNA_struct_find_function(ptr, identifier);
3239
3240         if(func)
3241                 return RNA_function_call(C, reports, ptr, func, parms);
3242
3243         return -1;
3244 }
3245
3246 int RNA_function_call_direct(bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, const char *format, ...)
3247 {
3248         va_list args;
3249         int ret;
3250
3251         va_start(args, format);
3252
3253         ret= RNA_function_call_direct_va(C, reports, ptr, func, format, args);
3254
3255         va_end(args);
3256
3257         return ret;
3258 }
3259
3260 int RNA_function_call_direct_lookup(bContext *C, ReportList *reports, PointerRNA *ptr, const char *identifier, const char *format, ...)
3261 {
3262         FunctionRNA *func;
3263
3264         func= RNA_struct_find_function(ptr, identifier);
3265
3266         if(func) {
3267                 va_list args;
3268                 int ret;
3269
3270                 va_start(args, format);
3271
3272                 ret= RNA_function_call_direct_va(C, reports, ptr, func, format, args);
3273
3274                 va_end(args);
3275
3276                 return ret;
3277         }
3278
3279         return -1;
3280 }
3281
3282 static int rna_function_format_array_length(const char *format, int ofs, int flen)
3283 {
3284         char lenbuf[16];
3285         int idx= 0;
3286
3287         if (format[ofs++]=='[')
3288                 for (; ofs<flen && format[ofs]!=']' && idx<sizeof(*lenbuf)-1; idx++, ofs++)
3289                         lenbuf[idx]= format[ofs];
3290
3291         if (ofs<flen && format[ofs++]==']') {
3292                 /* XXX put better error reporting for ofs>=flen or idx over lenbuf capacity */
3293         &nb