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