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