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