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