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