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