355b61a0c49bea1dacd9e42674895aa61e97d556
[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(ptr, 0);
2347                         if(!group)
2348                                 return 0;
2349
2350                         if(rna_token_strip_quotes(token))
2351                                 prop= (PropertyRNA *)IDP_GetPropertyFromGroup(group, token+1);
2352                         else
2353                                 prop= NULL;
2354                 }
2355                 else {
2356                         prop= RNA_struct_find_property(&curptr, token);
2357                 }
2358
2359                 if(token != fixedbuf)
2360                         MEM_freeN(token);
2361
2362                 if(!prop)
2363                         return 0;
2364
2365                 /* now look up the value of this property if it is a pointer or
2366                  * collection, otherwise return the property rna so that the
2367                  * caller can read the value of the property itself */
2368                 if(RNA_property_type(prop) == PROP_POINTER) {
2369                         nextptr= RNA_property_pointer_get(&curptr, prop);
2370
2371                         if(nextptr.data)
2372                                 curptr= nextptr;
2373                         else
2374                                 return 0;
2375                 }
2376                 else if(RNA_property_type(prop) == PROP_COLLECTION && *path) {
2377                         /* resolve the lookup with [] brackets */
2378                         token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1);
2379
2380                         if(!token)
2381                                 return 0;
2382
2383                         len= strlen(token);
2384                         
2385                         /* check for "" to see if it is a string */
2386                         if(rna_token_strip_quotes(token)) {
2387                                 RNA_property_collection_lookup_string(&curptr, prop, token+1, &nextptr);
2388                         }
2389                         else {
2390                                 /* otherwise do int lookup */
2391                                 intkey= atoi(token);
2392                                 RNA_property_collection_lookup_int(&curptr, prop, intkey, &nextptr);
2393                         }
2394
2395                         if(token != fixedbuf)
2396                                 MEM_freeN(token);
2397
2398                         if(nextptr.data)
2399                                 curptr= nextptr;
2400                         else
2401                                 return 0;
2402                 }
2403         }
2404
2405         *r_ptr= curptr;
2406         *r_prop= prop;
2407
2408         return 1;
2409 }
2410
2411
2412 char *RNA_path_append(const char *path, PointerRNA *ptr, PropertyRNA *prop, int intkey, const char *strkey)
2413 {
2414         DynStr *dynstr;
2415         const char *s;
2416         char appendstr[128], *result;
2417         
2418         dynstr= BLI_dynstr_new();
2419
2420         /* add .identifier */
2421         if(path) {
2422                 BLI_dynstr_append(dynstr, (char*)path);
2423                 if(*path)
2424                         BLI_dynstr_append(dynstr, ".");
2425         }
2426
2427         BLI_dynstr_append(dynstr, (char*)RNA_property_identifier(prop));
2428
2429         if(RNA_property_type(prop) == PROP_COLLECTION) {
2430                 /* add ["strkey"] or [intkey] */
2431                 BLI_dynstr_append(dynstr, "[");
2432
2433                 if(strkey) {
2434                         BLI_dynstr_append(dynstr, "\"");
2435                         for(s=strkey; *s; s++) {
2436                                 if(*s == '[') {
2437                                         appendstr[0]= '\\';
2438                                         appendstr[1]= *s;
2439                                         appendstr[2]= 0;
2440                                 }
2441                                 else {
2442                                         appendstr[0]= *s;
2443                                         appendstr[1]= 0;
2444                                 }
2445                                 BLI_dynstr_append(dynstr, appendstr);
2446                         }
2447                         BLI_dynstr_append(dynstr, "\"");
2448                 }
2449                 else {
2450                         sprintf(appendstr, "%d", intkey);
2451                         BLI_dynstr_append(dynstr, appendstr);
2452                 }
2453
2454                 BLI_dynstr_append(dynstr, "]");
2455         }
2456
2457         result= BLI_dynstr_get_cstring(dynstr);
2458         BLI_dynstr_free(dynstr);
2459
2460         return result;
2461 }
2462
2463 char *RNA_path_back(const char *path)
2464 {
2465         char fixedbuf[256];
2466         const char *previous, *current;
2467         char *result, *token;
2468         int i;
2469
2470         if(!path)
2471                 return NULL;
2472
2473         previous= NULL;
2474         current= path;
2475
2476         /* parse token by token until the end, then we back up to the previous
2477          * position and strip of the next token to get the path one step back */
2478         while(*current) {
2479                 token= rna_path_token(&current, fixedbuf, sizeof(fixedbuf), 0);
2480
2481                 if(!token)
2482                         return NULL;
2483                 if(token != fixedbuf)
2484                         MEM_freeN(token);
2485
2486                 /* in case of collection we also need to strip off [] */
2487                 token= rna_path_token(&current, fixedbuf, sizeof(fixedbuf), 1);
2488                 if(token && token != fixedbuf)
2489                         MEM_freeN(token);
2490                 
2491                 if(!*current)
2492                         break;
2493
2494                 previous= current;
2495         }
2496
2497         if(!previous)
2498                 return NULL;
2499
2500         /* copy and strip off last token */
2501         i= previous - path;
2502         result= BLI_strdup(path);
2503
2504         if(i > 0 && result[i-1] == '.') i--;
2505         result[i]= 0;
2506
2507         return result;
2508 }
2509
2510 char *RNA_path_from_ID_to_struct(PointerRNA *ptr)
2511 {
2512         char *ptrpath=NULL;
2513
2514         if(!ptr->id.data || !ptr->data)
2515                 return NULL;
2516         
2517         if(!RNA_struct_is_ID(ptr->type)) {
2518                 if(ptr->type->path) {
2519                         /* if type has a path to some ID, use it */
2520                         ptrpath= ptr->type->path(ptr);
2521                 }
2522                 else if(ptr->type->nested && RNA_struct_is_ID(ptr->type->nested)) {
2523                         PointerRNA parentptr;
2524                         PropertyRNA *userprop;
2525                         
2526                         /* find the property in the struct we're nested in that references this struct, and 
2527                          * use its identifier as the first part of the path used...
2528                          */
2529                         RNA_id_pointer_create(ptr->id.data, &parentptr);
2530                         userprop= RNA_struct_find_nested(&parentptr, ptr->type); 
2531                         
2532                         if(userprop)
2533                                 ptrpath= BLI_strdup(RNA_property_identifier(userprop));
2534                         else
2535                                 return NULL; // can't do anything about this case yet...
2536                 }
2537                 else
2538                         return NULL;
2539         }
2540         
2541         return ptrpath;
2542 }
2543
2544 char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop)
2545 {
2546         int is_rna = (prop->magic == RNA_MAGIC);
2547         const char *propname;
2548         char *ptrpath, *path;
2549
2550         if(!ptr->id.data || !ptr->data || !prop)
2551                 return NULL;
2552         
2553         /* path from ID to the struct holding this property */
2554         ptrpath= RNA_path_from_ID_to_struct(ptr);
2555
2556         propname= RNA_property_identifier(prop);
2557
2558         if(ptrpath) {
2559                 path= BLI_sprintfN(is_rna ? "%s.%s":"%s[\"%s\"]", ptrpath, propname);
2560         }
2561         else {
2562                 if(is_rna)
2563                         path= BLI_strdup(propname);
2564                 else
2565                         path= BLI_sprintfN("[\"%s\"]", propname);
2566         }
2567
2568         return path;
2569 }
2570
2571 /* Quick name based property access */
2572
2573 int RNA_boolean_get(PointerRNA *ptr, const char *name)
2574 {
2575         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2576
2577         if(prop) {
2578                 return RNA_property_boolean_get(ptr, prop);
2579         }
2580         else {
2581                 printf("RNA_boolean_get: %s.%s not found.\n", ptr->type->identifier, name);
2582                 return 0;
2583         }
2584 }
2585
2586 void RNA_boolean_set(PointerRNA *ptr, const char *name, int value)
2587 {
2588         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2589
2590         if(prop)
2591                 RNA_property_boolean_set(ptr, prop, value);
2592         else
2593                 printf("RNA_boolean_set: %s.%s not found.\n", ptr->type->identifier, name);
2594 }
2595
2596 void RNA_boolean_get_array(PointerRNA *ptr, const char *name, int *values)
2597 {
2598         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2599
2600         if(prop)
2601                 RNA_property_boolean_get_array(ptr, prop, values);
2602         else
2603                 printf("RNA_boolean_get_array: %s.%s not found.\n", ptr->type->identifier, name);
2604 }
2605
2606 void RNA_boolean_set_array(PointerRNA *ptr, const char *name, const int *values)
2607 {
2608         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2609
2610         if(prop)
2611                 RNA_property_boolean_set_array(ptr, prop, values);
2612         else
2613                 printf("RNA_boolean_set_array: %s.%s not found.\n", ptr->type->identifier, name);
2614 }
2615
2616 int RNA_int_get(PointerRNA *ptr, const char *name)
2617 {
2618         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2619
2620         if(prop) {
2621                 return RNA_property_int_get(ptr, prop);
2622         }
2623         else {
2624                 printf("RNA_int_get: %s.%s not found.\n", ptr->type->identifier, name);
2625                 return 0;
2626         }
2627 }
2628
2629 void RNA_int_set(PointerRNA *ptr, const char *name, int value)
2630 {
2631         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2632
2633         if(prop)
2634                 RNA_property_int_set(ptr, prop, value);
2635         else
2636                 printf("RNA_int_set: %s.%s not found.\n", ptr->type->identifier, name);
2637 }
2638
2639 void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values)
2640 {
2641         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2642
2643         if(prop)
2644                 RNA_property_int_get_array(ptr, prop, values);
2645         else
2646                 printf("RNA_int_get_array: %s.%s not found.\n", ptr->type->identifier, name);
2647 }
2648
2649 void RNA_int_set_array(PointerRNA *ptr, const char *name, const int *values)
2650 {
2651         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2652
2653         if(prop)
2654                 RNA_property_int_set_array(ptr, prop, values);
2655         else
2656                 printf("RNA_int_set_array: %s.%s not found.\n", ptr->type->identifier, name);
2657 }
2658
2659 float RNA_float_get(PointerRNA *ptr, const char *name)
2660 {
2661         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2662
2663         if(prop) {
2664                 return RNA_property_float_get(ptr, prop);
2665         }
2666         else {
2667                 printf("RNA_float_get: %s.%s not found.\n", ptr->type->identifier, name);
2668                 return 0;
2669         }
2670 }
2671
2672 void RNA_float_set(PointerRNA *ptr, const char *name, float value)
2673 {
2674         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2675
2676         if(prop)
2677                 RNA_property_float_set(ptr, prop, value);
2678         else
2679                 printf("RNA_float_set: %s.%s not found.\n", ptr->type->identifier, name);
2680 }
2681
2682 void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
2683 {
2684         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2685
2686         if(prop)
2687                 RNA_property_float_get_array(ptr, prop, values);
2688         else
2689                 printf("RNA_float_get_array: %s.%s not found.\n", ptr->type->identifier, name);
2690 }
2691
2692 void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
2693 {
2694         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2695
2696         if(prop)
2697                 RNA_property_float_set_array(ptr, prop, values);
2698         else
2699                 printf("RNA_float_set_array: %s.%s not found.\n", ptr->type->identifier, name);
2700 }
2701
2702 int RNA_enum_get(PointerRNA *ptr, const char *name)
2703 {
2704         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2705
2706         if(prop) {
2707                 return RNA_property_enum_get(ptr, prop);
2708         }
2709         else {
2710                 printf("RNA_enum_get: %s.%s not found.\n", ptr->type->identifier, name);
2711                 return 0;
2712         }
2713 }
2714
2715 void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
2716 {
2717         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2718
2719         if(prop)
2720                 RNA_property_enum_set(ptr, prop, value);
2721         else
2722                 printf("RNA_enum_set: %s.%s not found.\n", ptr->type->identifier, name);
2723 }
2724
2725 int RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const char *enumname)
2726 {
2727         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2728         EnumPropertyItem *item;
2729         int free;
2730
2731         if(prop) {
2732                 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
2733
2734                 for(; item->identifier; item++)
2735                         if(strcmp(item->identifier, enumname) == 0)
2736                                 return (item->value == RNA_property_enum_get(ptr, prop));
2737
2738                 if(free)
2739                         MEM_freeN(item);
2740
2741                 printf("RNA_enum_is_equal: %s.%s item %s not found.\n", ptr->type->identifier, name, enumname);
2742                 return 0;
2743         }
2744         else {
2745                 printf("RNA_enum_is_equal: %s.%s not found.\n", ptr->type->identifier, name);
2746                 return 0;
2747         }
2748 }
2749
2750 int RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value)
2751 {
2752         for( ; item->identifier; item++) {
2753                 if(strcmp(item->identifier, identifier)==0) {
2754                         *value= item->value;
2755                         return 1;
2756                 }
2757         }
2758         
2759         return 0;
2760 }
2761
2762 int     RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **identifier)
2763 {
2764         for( ; item->identifier; item++) {
2765                 if(item->value==value) {
2766                         *identifier= item->identifier;
2767                         return 1;
2768                 }
2769         }
2770
2771         return 0;
2772 }
2773
2774 void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
2775 {
2776         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2777
2778         if(prop)
2779                 RNA_property_string_get(ptr, prop, value);
2780         else
2781                 printf("RNA_string_get: %s.%s not found.\n", ptr->type->identifier, name);
2782 }
2783
2784 char *RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen)
2785 {
2786         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2787
2788         if(prop) {
2789                 return RNA_property_string_get_alloc(ptr, prop, fixedbuf, fixedlen);
2790         }
2791         else {
2792                 printf("RNA_string_get_alloc: %s.%s not found.\n", ptr->type->identifier, name);
2793                 return 0;
2794         }
2795 }
2796
2797 int RNA_string_length(PointerRNA *ptr, const char *name)
2798 {
2799         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2800
2801         if(prop) {
2802                 return RNA_property_string_length(ptr, prop);
2803         }
2804         else {
2805                 printf("RNA_string_length: %s.%s not found.\n", ptr->type->identifier, name);
2806                 return 0;
2807         }
2808 }
2809
2810 void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
2811 {
2812         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2813
2814         if(prop)
2815                 RNA_property_string_set(ptr, prop, value);
2816         else
2817                 printf("RNA_string_set: %s.%s not found.\n", ptr->type->identifier, name);
2818 }
2819
2820 PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
2821 {
2822         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2823
2824         if(prop) {
2825                 return RNA_property_pointer_get(ptr, prop);
2826         }
2827         else {
2828                 PointerRNA result;
2829
2830                 printf("RNA_pointer_get: %s.%s not found.\n", ptr->type->identifier, name);
2831
2832                 memset(&result, 0, sizeof(result));
2833                 return result;
2834         }
2835 }
2836
2837 void RNA_pointer_set(PointerRNA *ptr, const char *name, PointerRNA ptr_value)
2838 {
2839         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2840
2841         if(prop) {
2842                 RNA_property_pointer_set(ptr, prop, ptr_value);
2843         }
2844         else {
2845                 printf("RNA_pointer_set: %s.%s not found.\n", ptr->type->identifier, name);
2846         }
2847 }
2848
2849 void RNA_pointer_add(PointerRNA *ptr, const char *name)
2850 {
2851         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2852
2853         if(prop)
2854                 RNA_property_pointer_add(ptr, prop);
2855         else
2856                 printf("RNA_pointer_set: %s.%s not found.\n", ptr->type->identifier, name);
2857 }
2858
2859 void RNA_collection_begin(PointerRNA *ptr, const char *name, CollectionPropertyIterator *iter)
2860 {
2861         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2862
2863         if(prop)
2864                 RNA_property_collection_begin(ptr, prop, iter);
2865         else
2866                 printf("RNA_collection_begin: %s.%s not found.\n", ptr->type->identifier, name);
2867 }
2868
2869 void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value)
2870 {
2871         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2872
2873         if(prop)
2874                 RNA_property_collection_add(ptr, prop, r_value);
2875         else
2876                 printf("RNA_collection_add: %s.%s not found.\n", ptr->type->identifier, name);
2877 }
2878
2879 void RNA_collection_clear(PointerRNA *ptr, const char *name)
2880 {
2881         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2882
2883         if(prop)
2884                 RNA_property_collection_clear(ptr, prop);
2885         else
2886                 printf("RNA_collection_clear: %s.%s not found.\n", ptr->type->identifier, name);
2887 }
2888
2889 int RNA_collection_length(PointerRNA *ptr, const char *name)
2890 {
2891         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2892
2893         if(prop) {
2894                 return RNA_property_collection_length(ptr, prop);
2895         }
2896         else {
2897                 printf("RNA_collection_length: %s.%s not found.\n", ptr->type->identifier, name);
2898                 return 0;
2899         }
2900 }
2901
2902 int RNA_property_is_set(PointerRNA *ptr, const char *name)
2903 {
2904         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2905
2906         if(prop) {
2907                 if(prop->flag & PROP_IDPROPERTY)
2908                         return (rna_idproperty_find(ptr, name) != NULL);
2909                 else
2910                         return 1;
2911         }
2912         else {
2913                 // printf("RNA_property_is_set: %s.%s not found.\n", ptr->type->identifier, name);
2914                 return 0;
2915         }
2916 }
2917
2918 /* string representation of a property, python
2919  * compatible but can be used for display too*/
2920 char *RNA_pointer_as_string(PointerRNA *ptr)
2921 {
2922         DynStr *dynstr= BLI_dynstr_new();
2923         char *cstring;
2924         
2925         const char *propname;
2926         int first_time = 1;
2927         
2928         BLI_dynstr_append(dynstr, "{");
2929         
2930         RNA_STRUCT_BEGIN(ptr, prop) {
2931                 propname = RNA_property_identifier(prop);
2932                 
2933                 if(strcmp(propname, "rna_type")==0)
2934                         continue;
2935                 
2936                 if(first_time==0)
2937                         BLI_dynstr_append(dynstr, ", ");
2938                 first_time= 0;
2939                 
2940                 cstring = RNA_property_as_string(NULL, ptr, prop);
2941                 BLI_dynstr_appendf(dynstr, "\"%s\":%s", propname, cstring);
2942                 MEM_freeN(cstring);
2943         }
2944         RNA_STRUCT_END;
2945
2946         BLI_dynstr_append(dynstr, "}"); 
2947         
2948         
2949         cstring = BLI_dynstr_get_cstring(dynstr);
2950         BLI_dynstr_free(dynstr);
2951         return cstring;
2952 }
2953
2954 char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
2955 {
2956         int type = RNA_property_type(prop);
2957         int len = RNA_property_array_length(ptr, prop);
2958         int i;
2959
2960         DynStr *dynstr= BLI_dynstr_new();
2961         char *cstring;
2962         
2963
2964         /* see if we can coorce into a python type - PropertyType */
2965         switch (type) {
2966         case PROP_BOOLEAN:
2967                 if(len==0) {
2968                         BLI_dynstr_append(dynstr, RNA_property_boolean_get(ptr, prop) ? "True" : "False");
2969                 }
2970                 else {
2971                         BLI_dynstr_append(dynstr, "(");
2972                         for(i=0; i<len; i++) {
2973                                 BLI_dynstr_appendf(dynstr, i?", %s":"%s", RNA_property_boolean_get_index(ptr, prop, i) ? "True" : "False");
2974                         }
2975                         if(len==1)
2976                                 BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
2977                         BLI_dynstr_append(dynstr, ")");
2978                 }
2979                 break;
2980         case PROP_INT:
2981                 if(len==0) {
2982                         BLI_dynstr_appendf(dynstr, "%d", RNA_property_int_get(ptr, prop));
2983                 }
2984                 else {
2985                         BLI_dynstr_append(dynstr, "(");
2986                         for(i=0; i<len; i++) {
2987                                 BLI_dynstr_appendf(dynstr, i?", %d":"%d", RNA_property_int_get_index(ptr, prop, i));
2988                         }
2989                         if(len==1)
2990                                 BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
2991                         BLI_dynstr_append(dynstr, ")");
2992                 }
2993                 break;
2994         case PROP_FLOAT:
2995                 if(len==0) {
2996                         BLI_dynstr_appendf(dynstr, "%g", RNA_property_float_get(ptr, prop));
2997                 }
2998                 else {
2999                         BLI_dynstr_append(dynstr, "(");
3000                         for(i=0; i<len; i++) {
3001                                 BLI_dynstr_appendf(dynstr, i?", %g":"%g", RNA_property_float_get_index(ptr, prop, i));
3002                         }
3003                         if(len==1)
3004                                 BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
3005                         BLI_dynstr_append(dynstr, ")");
3006                 }
3007                 break;
3008         case PROP_STRING:
3009         {
3010                 /* string arrays dont exist */
3011                 char *buf;
3012                 buf = RNA_property_string_get_alloc(ptr, prop, NULL, -1);
3013                 BLI_dynstr_appendf(dynstr, "\"%s\"", buf);
3014                 MEM_freeN(buf);
3015                 break;
3016         }
3017         case PROP_ENUM:
3018         {
3019                 /* string arrays dont exist */
3020                 const char *identifier;
3021                 int val = RNA_property_enum_get(ptr, prop);
3022
3023                 if(RNA_property_enum_identifier(C, ptr, prop, val, &identifier)) {
3024                         BLI_dynstr_appendf(dynstr, "'%s'", identifier);
3025                 }
3026                 else {
3027                         BLI_dynstr_appendf(dynstr, "'<UNKNOWN ENUM>'", identifier);
3028                 }
3029                 break;
3030         }
3031         case PROP_POINTER:
3032         {
3033                 BLI_dynstr_append(dynstr, "'<POINTER>'"); /* TODO */
3034                 break;
3035         }
3036         case PROP_COLLECTION:
3037         {
3038                 int first_time = 1;
3039                 CollectionPropertyIterator collect_iter;
3040                 BLI_dynstr_append(dynstr, "[");
3041                 
3042                 for(RNA_property_collection_begin(ptr, prop, &collect_iter); collect_iter.valid; RNA_property_collection_next(&collect_iter)) {
3043                         PointerRNA itemptr= collect_iter.ptr;
3044                         
3045                         if(first_time==0)
3046                                 BLI_dynstr_append(dynstr, ", ");
3047                         first_time= 0;
3048                         
3049                         /* now get every prop of the collection */
3050                         cstring= RNA_pointer_as_string(&itemptr);
3051                         BLI_dynstr_append(dynstr, cstring);
3052                         MEM_freeN(cstring);
3053                 }
3054                 
3055                 RNA_property_collection_end(&collect_iter);
3056                 BLI_dynstr_append(dynstr, "]");
3057                 break;
3058         }
3059         default:
3060                 BLI_dynstr_append(dynstr, "'<UNKNOWN TYPE>'"); /* TODO */
3061                 break;
3062         }
3063
3064         cstring = BLI_dynstr_get_cstring(dynstr);
3065         BLI_dynstr_free(dynstr);
3066         return cstring;
3067 }
3068
3069 /* Function */
3070
3071 const char *RNA_function_identifier(FunctionRNA *func)
3072 {
3073         return func->identifier;
3074 }
3075
3076 PropertyRNA *RNA_function_return(FunctionRNA *func)
3077 {
3078         return func->ret;
3079 }
3080
3081 const char *RNA_function_ui_description(FunctionRNA *func)
3082 {
3083         return func->description;
3084 }
3085
3086 int RNA_function_flag(FunctionRNA *func)
3087 {
3088         return func->flag;
3089 }
3090
3091 PropertyRNA *RNA_function_get_parameter(PointerRNA *ptr, FunctionRNA *func, int index)
3092 {
3093         PropertyRNA *parm;
3094         int i;
3095
3096         parm= func->cont.properties.first;
3097         for(i= 0; parm; parm= parm->next, i++)
3098                 if(i==index)
3099                         return parm;
3100
3101         return NULL;
3102 }
3103
3104 PropertyRNA *RNA_function_find_parameter(PointerRNA *ptr, FunctionRNA *func, const char *identifier)
3105 {
3106         PropertyRNA *parm;
3107
3108         parm= func->cont.properties.first;
3109         for(; parm; parm= parm->next)
3110                 if(strcmp(parm->identifier, identifier)==0)
3111                         return parm;
3112
3113         return NULL;
3114 }
3115
3116 const struct ListBase *RNA_function_defined_parameters(FunctionRNA *func)
3117 {
3118         return &func->cont.properties;
3119 }
3120
3121 /* Utility */
3122
3123 ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *ptr, FunctionRNA *func)
3124 {
3125         PropertyRNA *parm;
3126         void *data;
3127         int tot= 0, size;
3128
3129         /* allocate data */
3130         for(parm= func->cont.properties.first; parm; parm= parm->next)
3131                 tot+= rna_parameter_size(parm);
3132
3133         parms->data= MEM_callocN(tot, "RNA_parameter_list_create");
3134         parms->func= func;
3135         parms->tot= tot;
3136
3137         /* set default values */
3138         data= parms->data;
3139
3140         for(parm= func->cont.properties.first; parm; parm= parm->next) {
3141                 size= rna_parameter_size(parm);
3142
3143                 if(!(parm->flag & PROP_REQUIRED)) {
3144                         switch(parm->type) {
3145                                 case PROP_BOOLEAN:
3146                                         if(parm->arraydimension) memcpy(data, &((BooleanPropertyRNA*)parm)->defaultarray, size);
3147                                         else memcpy(data, &((BooleanPropertyRNA*)parm)->defaultvalue, size);
3148                                         break;
3149                                 case PROP_INT:
3150                                         if(parm->arraydimension) memcpy(data, &((IntPropertyRNA*)parm)->defaultarray, size);
3151                                         else memcpy(data, &((IntPropertyRNA*)parm)->defaultvalue, size);
3152                                         break;
3153                                 case PROP_FLOAT:
3154                                         if(parm->arraydimension) memcpy(data, &((FloatPropertyRNA*)parm)->defaultarray, size);
3155                                         else memcpy(data, &((FloatPropertyRNA*)parm)->defaultvalue, size);
3156                                         break;
3157                                 case PROP_ENUM:
3158                                         memcpy(data, &((EnumPropertyRNA*)parm)->defaultvalue, size);
3159                                         break;
3160                                 case PROP_STRING: {
3161                                         const char *defvalue= ((StringPropertyRNA*)parm)->defaultvalue;
3162                                         if(defvalue && defvalue[0])
3163                                                 memcpy(data, &defvalue, size);
3164                                         break;
3165                                 }
3166                                 case PROP_POINTER:
3167                                 case PROP_COLLECTION:
3168                                         break;
3169                         }
3170                 }
3171
3172                 data= ((char*)data) + size;
3173         }
3174
3175         return parms;
3176 }
3177
3178 void RNA_parameter_list_free(ParameterList *parms)
3179 {
3180         PropertyRNA *parm;
3181         int tot;
3182
3183         parm= parms->func->cont.properties.first;
3184         for(tot= 0; parm; parm= parm->next) {
3185                 if(parm->type == PROP_COLLECTION)
3186                         BLI_freelistN((ListBase*)((char*)parms->data+tot));
3187                 else if (parm->flag & PROP_DYNAMIC) {
3188                         /* for dynamic arrays and strings, data is a pointer to an array */
3189                         char *array= *(char**)((char*)parms->data+tot);
3190                         if(array)
3191                                 MEM_freeN(array);
3192                 }
3193
3194                 tot+= rna_parameter_size(parm);
3195         }
3196
3197         MEM_freeN(parms->data);
3198         parms->data= NULL;
3199
3200         parms->func= NULL;
3201 }
3202
3203 int  RNA_parameter_list_size(ParameterList *parms)
3204 {
3205         return parms->tot;
3206 }
3207
3208 void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter)
3209 {
3210         PropertyType ptype;
3211
3212         RNA_pointer_create(NULL, &RNA_Function, parms->func, &iter->funcptr);
3213
3214         iter->parms= parms;
3215         iter->parm= parms->func->cont.properties.first;
3216         iter->valid= iter->parm != NULL;
3217         iter->offset= 0;
3218
3219         if(iter->valid) {
3220                 iter->size= rna_parameter_size(iter->parm);
3221                 iter->data= (((char*)iter->parms->data)+iter->offset);
3222                 ptype= RNA_property_type(iter->parm);
3223         }
3224 }
3225
3226 void RNA_parameter_list_next(ParameterIterator *iter)
3227 {
3228         PropertyType ptype;
3229
3230         iter->offset+= iter->size;
3231         iter->parm= iter->parm->next;
3232         iter->valid= iter->parm != NULL;
3233
3234         if(iter->valid) {
3235                 iter->size= rna_parameter_size(iter->parm);
3236                 iter->data= (((char*)iter->parms->data)+iter->offset);
3237                 ptype= RNA_property_type(iter->parm);
3238         }
3239 }
3240
3241 void RNA_parameter_list_end(ParameterIterator *iter)
3242 {
3243         /* nothing to do */
3244 }
3245
3246 void RNA_parameter_get(ParameterList *parms, PropertyRNA *parm, void **value)
3247 {
3248         ParameterIterator iter;
3249
3250         RNA_parameter_list_begin(parms, &iter);
3251
3252         for(; iter.valid; RNA_parameter_list_next(&iter))
3253                 if(iter.parm==parm) 
3254                         break;
3255
3256         if(iter.valid)
3257                 *value= iter.data;
3258         else
3259                 *value= NULL;
3260
3261         RNA_parameter_list_end(&iter);
3262 }
3263
3264 void RNA_parameter_get_lookup(ParameterList *parms, const char *identifier, void **value)
3265 {
3266         PropertyRNA *parm;
3267
3268         parm= parms->func->cont.properties.first;
3269         for(; parm; parm= parm->next)
3270                 if(strcmp(RNA_property_identifier(parm), identifier)==0)
3271                         break;
3272
3273         if(parm)
3274                 RNA_parameter_get(parms, parm, value);
3275 }
3276
3277 void RNA_parameter_set(ParameterList *parms, PropertyRNA *parm, void *value)
3278 {
3279         ParameterIterator iter;
3280
3281         RNA_parameter_list_begin(parms, &iter);
3282