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