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