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