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