aa8bd3ed7666d828f61774caed99015a678a4da7
[blender-staging.git] / source / blender / makesrna / intern / rna_access.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * Contributor(s): Blender Foundation (2008).
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "MEM_guardedalloc.h"
29
30 #include "DNA_ID.h"
31 #include "DNA_windowmanager_types.h"
32
33 #include "BLI_blenlib.h"
34 #include "BLI_dynstr.h"
35
36 #include "BKE_idprop.h"
37 #include "BKE_utildefines.h"
38
39 #include "WM_api.h"
40
41 #include "RNA_access.h"
42 #include "RNA_define.h"
43 #include "RNA_types.h"
44
45 #include "rna_internal.h"
46
47 /* Exit */
48
49 void RNA_exit()
50 {
51         RNA_free(&BLENDER_RNA);
52 }
53
54 /* Pointer */
55
56 void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr)
57 {
58         r_ptr->id.type= NULL;
59         r_ptr->id.data= NULL;
60         r_ptr->type= &RNA_Main;
61         r_ptr->data= main;
62 }
63
64 void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
65 {
66         PointerRNA tmp;
67         StructRNA *idtype= NULL;
68
69         if(id) {
70                 memset(&tmp, 0, sizeof(tmp));
71                 tmp.data= id;
72                 idtype= rna_ID_refine(&tmp);
73         }
74
75         r_ptr->id.type= idtype;
76         r_ptr->id.data= id;
77         r_ptr->type= idtype;
78         r_ptr->data= id;
79 }
80
81 void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
82 {
83         PointerRNA tmp;
84         StructRNA *idtype= NULL;
85
86         if(id) {
87                 memset(&tmp, 0, sizeof(tmp));
88                 tmp.data= id;
89                 idtype= rna_ID_refine(&tmp);
90         }
91
92         r_ptr->id.type= idtype;
93         r_ptr->id.data= id;
94         r_ptr->type= type;
95         r_ptr->data= data;
96 }
97
98 static void rna_pointer_inherit_id(StructRNA *type, PointerRNA *parent, PointerRNA *ptr)
99 {
100         if(type && type->flag & STRUCT_ID) {
101                 ptr->id.data= ptr->data;
102                 ptr->id.type= type;
103         }
104         else {
105                 ptr->id.data= parent->id.data;
106                 ptr->id.type= parent->id.type;
107         }
108 }
109
110 void RNA_blender_rna_pointer_create(PointerRNA *r_ptr)
111 {
112         r_ptr->id.type= NULL;
113         r_ptr->id.data= NULL;
114         r_ptr->type= &RNA_BlenderRNA;
115         r_ptr->data= &BLENDER_RNA;
116 }
117
118 /* ID Properties */
119
120 IDProperty *rna_idproperties_get(PointerRNA *ptr, int create)
121 {
122         if(ptr->type->flag & STRUCT_ID)
123                 return IDP_GetProperties(ptr->data, create);
124         else if(ptr->type == &RNA_IDPropertyGroup || ptr->type->base == &RNA_IDPropertyGroup)
125                 return ptr->data;
126         else if(ptr->type->base == &RNA_OperatorProperties) {
127                 if(create && !ptr->data) {
128                         IDPropertyTemplate val;
129                         val.i = 0; /* silence MSVC warning about uninitialized var when debugging */
130                         ptr->data= IDP_New(IDP_GROUP, val, "RNA_OperatorProperties group");
131                 }
132
133                 return ptr->data;
134         }
135         else
136                 return NULL;
137 }
138
139 static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name)
140 {
141         IDProperty *group= rna_idproperties_get(ptr, 0);
142         IDProperty *idprop;
143
144         if(group) {
145                 for(idprop=group->data.group.first; idprop; idprop=idprop->next)
146                         if(strcmp(idprop->name, name) == 0)
147                                 return idprop;
148         }
149         
150         return NULL;
151 }
152
153 static int rna_idproperty_verify_valid(PropertyRNA *prop, IDProperty *idprop)
154 {
155         /* this verifies if the idproperty actually matches the property
156          * description and otherwise removes it. this is to ensure that
157          * rna property access is type safe, e.g. if you defined the rna
158          * to have a certain array length you can count on that staying so */
159         
160         switch(idprop->type) {
161                 case IDP_IDPARRAY:
162                         if(prop->type != PROP_COLLECTION)
163                                 return 0;
164                         break;
165                 case IDP_ARRAY:
166                         if(prop->arraylength != idprop->len)
167                                 return 0;
168
169                         if(idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT)
170                                 return 0;
171                         if(idprop->subtype == IDP_INT && !ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
172                                 return 0;
173
174                         break;
175                 case IDP_INT:
176                         if(!ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
177                                 return 0;
178                         break;
179                 case IDP_FLOAT:
180                 case IDP_DOUBLE:
181                         if(prop->type != PROP_FLOAT)
182                                 return 0;
183                         break;
184                 case IDP_STRING:
185                         if(prop->type != PROP_STRING)
186                                 return 0;
187                         break;
188                 case IDP_GROUP:
189                         if(prop->type != PROP_POINTER)
190                                 return 0;
191                         break;
192                 default:
193                         return 0;
194         }
195
196         return 1;
197 }
198
199 IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr)
200 {
201         /* This is quite a hack, but avoids some complexity in the API. we
202          * pass IDProperty structs as PropertyRNA pointers to the outside.
203          * We store some bytes in PropertyRNA structs that allows us to
204          * distinguish it from IDProperty structs. If it is an ID property,
205          * we look up an IDP PropertyRNA based on the type, and set the data
206          * pointer to the IDProperty. */
207
208         if((*prop)->magic == RNA_MAGIC) {
209                 if((*prop)->flag & PROP_IDPROPERTY) {
210                         IDProperty *idprop= rna_idproperty_find(ptr, (*prop)->identifier);
211
212                         if(idprop && !rna_idproperty_verify_valid(*prop, idprop)) {
213                                 IDProperty *group= rna_idproperties_get(ptr, 0);
214
215                                 IDP_RemFromGroup(group, idprop);
216                                 IDP_FreeProperty(idprop);
217                                 MEM_freeN(idprop);
218                                 return NULL;
219                         }
220
221                         return idprop;
222                 }
223                 else
224                         return NULL;
225         }
226
227         {
228                 static PropertyRNA *typemap[IDP_NUMTYPES] =
229                         {(PropertyRNA*)&rna_IDProperty_string,
230                          (PropertyRNA*)&rna_IDProperty_int,
231                          (PropertyRNA*)&rna_IDProperty_float,
232                          NULL, NULL, NULL,
233                          (PropertyRNA*)&rna_IDProperty_group, NULL,
234                          (PropertyRNA*)&rna_IDProperty_double};
235
236                 static PropertyRNA *arraytypemap[IDP_NUMTYPES] =
237                         {NULL, (PropertyRNA*)&rna_IDProperty_int_array,
238                          (PropertyRNA*)&rna_IDProperty_float_array,
239                          NULL, NULL, NULL,
240                          (PropertyRNA*)&rna_IDProperty_collection, NULL,
241                          (PropertyRNA*)&rna_IDProperty_double_array};
242
243                 IDProperty *idprop= (IDProperty*)(*prop);
244
245                 if(idprop->type == IDP_ARRAY)
246                         *prop= arraytypemap[(int)(idprop->subtype)];
247                 else 
248                         *prop= typemap[(int)(idprop->type)];
249
250                 return idprop;
251         }
252 }
253
254 /* Structs */
255
256 const char *RNA_struct_identifier(PointerRNA *ptr)
257 {
258         return ptr->type->identifier;
259 }
260
261 const char *RNA_struct_ui_name(PointerRNA *ptr)
262 {
263         return ptr->type->name;
264 }
265
266 const char *RNA_struct_ui_description(PointerRNA *ptr)
267 {
268         return ptr->type->description;
269 }
270
271 PropertyRNA *RNA_struct_name_property(PointerRNA *ptr)
272 {
273         return ptr->type->nameproperty;
274 }
275
276 PropertyRNA *RNA_struct_iterator_property(PointerRNA *ptr)
277 {
278         return ptr->type->iteratorproperty;
279 }
280
281 int RNA_struct_is_ID(PointerRNA *ptr)
282 {
283         return (ptr->type->flag & STRUCT_ID) != 0;
284 }
285
286 PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
287 {
288         CollectionPropertyIterator iter;
289         PropertyRNA *iterprop, *prop;
290         int i = 0;
291
292         iterprop= RNA_struct_iterator_property(ptr);
293         RNA_property_collection_begin(ptr, iterprop, &iter);
294         prop= NULL;
295
296         for(; iter.valid; RNA_property_collection_next(&iter), i++) {
297                 if(strcmp(identifier, RNA_property_identifier(&iter.ptr, iter.ptr.data)) == 0) {
298                         prop= iter.ptr.data;
299                         break;
300                 }
301         }
302
303         RNA_property_collection_end(&iter);
304
305         return prop;
306 }
307
308 const struct ListBase *RNA_struct_defined_properties(StructRNA *srna)
309 {
310         return &srna->properties;
311 }
312
313 /* Property Information */
314
315 const char *RNA_property_identifier(PointerRNA *ptr, PropertyRNA *prop)
316 {
317         IDProperty *idprop;
318
319         if((idprop=rna_idproperty_check(&prop, ptr)))
320                 return idprop->name;
321         else
322                 return prop->identifier;
323 }
324
325 PropertyType RNA_property_type(PointerRNA *ptr, PropertyRNA *prop)
326 {
327         rna_idproperty_check(&prop, ptr);
328
329         return prop->type;
330 }
331
332 PropertySubType RNA_property_subtype(PointerRNA *ptr, PropertyRNA *prop)
333 {
334         rna_idproperty_check(&prop, ptr);
335
336         return prop->subtype;
337 }
338
339 int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
340 {
341         IDProperty *idprop;
342
343         if((idprop=rna_idproperty_check(&prop, ptr)) && idprop->type==IDP_ARRAY)
344                 return idprop->len;
345         else
346                 return prop->arraylength;
347 }
348
349 void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
350 {
351         IntPropertyRNA *iprop;
352         
353         rna_idproperty_check(&prop, ptr);
354         iprop= (IntPropertyRNA*)prop;
355
356         if(iprop->range) {
357                 iprop->range(ptr, hardmin, hardmax);
358         }
359         else {
360                 *hardmin= iprop->hardmin;
361                 *hardmax= iprop->hardmax;
362         }
363 }
364
365 void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
366 {
367         IntPropertyRNA *iprop;
368         int hardmin, hardmax;
369         
370         rna_idproperty_check(&prop, ptr);
371         iprop= (IntPropertyRNA*)prop;
372
373         if(iprop->range) {
374                 iprop->range(ptr, &hardmin, &hardmax);
375                 *softmin= MAX2(iprop->softmin, hardmin);
376                 *softmax= MIN2(iprop->softmax, hardmax);
377         }
378         else {
379                 *softmin= iprop->softmin;
380                 *softmax= iprop->softmax;
381         }
382
383         *step= iprop->step;
384 }
385
386 void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
387 {
388         FloatPropertyRNA *fprop;
389
390         rna_idproperty_check(&prop, ptr);
391         fprop= (FloatPropertyRNA*)prop;
392
393         if(fprop->range) {
394                 fprop->range(ptr, hardmin, hardmax);
395         }
396         else {
397                 *hardmin= fprop->hardmin;
398                 *hardmax= fprop->hardmax;
399         }
400 }
401
402 void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision)
403 {
404         FloatPropertyRNA *fprop;
405         float hardmin, hardmax;
406
407         rna_idproperty_check(&prop, ptr);
408         fprop= (FloatPropertyRNA*)prop;
409
410         if(fprop->range) {
411                 fprop->range(ptr, &hardmin, &hardmax);
412                 *softmin= MAX2(fprop->softmin, hardmin);
413                 *softmax= MIN2(fprop->softmax, hardmax);
414         }
415         else {
416                 *softmin= fprop->softmin;
417                 *softmax= fprop->softmax;
418         }
419
420         *step= fprop->step;
421         *precision= (float)fprop->precision;
422 }
423
424 int RNA_property_string_maxlength(PointerRNA *ptr, PropertyRNA *prop)
425 {
426         StringPropertyRNA *sprop;
427         
428         rna_idproperty_check(&prop, ptr);
429         sprop= (StringPropertyRNA*)prop;
430
431         return sprop->maxlength;
432 }
433
434 void RNA_property_enum_items(PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **item, int *totitem)
435 {
436         EnumPropertyRNA *eprop;
437
438         rna_idproperty_check(&prop, ptr);
439         eprop= (EnumPropertyRNA*)prop;
440
441         *item= eprop->item;
442         *totitem= eprop->totitem;
443 }
444
445 int RNA_property_enum_value(PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value)
446 {       
447         const EnumPropertyItem *item;
448         int totitem, i;
449         
450         RNA_property_enum_items(ptr, prop, &item, &totitem);
451         
452         for (i=0; i<totitem; i++) {
453                 if (strcmp(item[i].identifier, identifier)==0) {
454                         *value = item[i].value;
455                         return 1;
456                 }
457         }
458
459         return 0;
460 }
461
462 int RNA_property_enum_identifier(PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
463 {       
464         const EnumPropertyItem *item;
465         int totitem, i;
466         
467         RNA_property_enum_items(ptr, prop, &item, &totitem);
468         
469         for (i=0; i<totitem; i++) {
470                 if (item[i].value==value) {
471                         *identifier = item[i].identifier;
472                         return 1;
473                 }
474         }
475         
476         return 0;
477 }
478
479 const char *RNA_property_ui_name(PointerRNA *ptr, PropertyRNA *prop)
480 {
481         PropertyRNA *oldprop= prop;
482         IDProperty *idprop;
483
484         if((idprop=rna_idproperty_check(&prop, ptr)) && oldprop!=prop)
485                 return idprop->name;
486         else
487                 return prop->name;
488 }
489
490 const char *RNA_property_ui_description(PointerRNA *ptr, PropertyRNA *prop)
491 {
492         PropertyRNA *oldprop= prop;
493
494         if(rna_idproperty_check(&prop, ptr) && oldprop!=prop)
495                 return "";
496         else
497                 return prop->description;
498 }
499
500 int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
501 {
502         int flag;
503
504         rna_idproperty_check(&prop, ptr);
505
506         if(prop->editable)
507                 flag= prop->editable(ptr);
508         else
509                 flag= prop->flag;
510
511         return !(flag & PROP_NOT_EDITABLE);
512 }
513
514 int RNA_property_evaluated(PointerRNA *ptr, PropertyRNA *prop)
515 {
516         int flag;
517
518         rna_idproperty_check(&prop, ptr);
519
520         if(prop->editable)
521                 flag= prop->editable(ptr);
522         else
523                 flag= prop->flag;
524
525         return (flag & PROP_EVALUATED);
526 }
527
528 void RNA_property_update(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop)
529 {
530         rna_idproperty_check(&prop, ptr);
531
532         if(prop->update)
533                 prop->update(C, ptr);
534         if(prop->noteflag)
535                 WM_event_add_notifier(C, prop->noteflag, ptr->id.data);
536 }
537
538 /* Property Data */
539
540 int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
541 {
542         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
543         IDProperty *idprop;
544
545         if((idprop=rna_idproperty_check(&prop, ptr)))
546                 return IDP_Int(idprop);
547         else if(bprop->get)
548                 return bprop->get(ptr);
549         else
550                 return bprop->defaultvalue;
551 }
552
553 void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
554 {
555         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
556         IDProperty *idprop;
557
558         if((idprop=rna_idproperty_check(&prop, ptr)))
559                 IDP_Int(idprop)= value;
560         else if(bprop->set)
561                 bprop->set(ptr, value);
562         else if(!(prop->flag & PROP_NOT_EDITABLE)) {
563                 IDPropertyTemplate val;
564                 IDProperty *group;
565
566                 val.i= value;
567
568                 group= rna_idproperties_get(ptr, 1);
569                 if(group)
570                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
571         }
572 }
573
574 int RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int index)
575 {
576         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
577         IDProperty *idprop;
578
579         if((idprop=rna_idproperty_check(&prop, ptr)))
580                 return ((int*)IDP_Array(idprop))[index];
581         else if(bprop->getarray)
582                 return bprop->getarray(ptr, index);
583         else if(bprop->defaultarray)
584                 return bprop->defaultarray[index];
585         else
586                 return 0;
587 }
588
589 void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
590 {
591         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
592         IDProperty *idprop;
593
594         if((idprop=rna_idproperty_check(&prop, ptr)))
595                 ((int*)IDP_Array(idprop))[index]= value;
596         else if(bprop->setarray)
597                 bprop->setarray(ptr, index, value);
598         else if(!(prop->flag & PROP_NOT_EDITABLE)) {
599                 IDPropertyTemplate val;
600                 IDProperty *group;
601
602                 val.array.len= prop->arraylength;
603                 val.array.type= IDP_INT;
604
605                 group= rna_idproperties_get(ptr, 1);
606                 if(group) {
607                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
608                         IDP_AddToGroup(group, idprop);
609                         if(bprop->defaultarray)
610                                 memcpy(idprop->data.pointer, bprop->defaultarray, sizeof(int)*prop->arraylength);
611                         else
612                                 memset(idprop->data.pointer, 0, sizeof(int)*prop->arraylength);
613                         ((int*)idprop->data.pointer)[index]= value;
614                 }
615         }
616 }
617
618 int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
619 {
620         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
621         IDProperty *idprop;
622
623         if((idprop=rna_idproperty_check(&prop, ptr)))
624                 return IDP_Int(idprop);
625         else if(iprop->get)
626                 return iprop->get(ptr);
627         else
628                 return iprop->defaultvalue;
629 }
630
631 void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
632 {
633         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
634         IDProperty *idprop;
635
636         if((idprop=rna_idproperty_check(&prop, ptr)))
637                 IDP_Int(idprop)= value;
638         else if(iprop->set)
639                 iprop->set(ptr, value);
640         else if(!(prop->flag & PROP_NOT_EDITABLE)) {
641                 IDPropertyTemplate val;
642                 IDProperty *group;
643
644                 val.i= value;
645
646                 group= rna_idproperties_get(ptr, 1);
647                 if(group)
648                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
649         }
650 }
651
652 int RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int index)
653 {
654         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
655         IDProperty *idprop;
656
657         if((idprop=rna_idproperty_check(&prop, ptr)))
658                 return ((int*)IDP_Array(idprop))[index];
659         else if(iprop->getarray)
660                 return iprop->getarray(ptr, index);
661         else if(iprop->defaultarray)
662                 return iprop->defaultarray[index];
663         else
664                 return 0.0f;
665 }
666
667 void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
668 {
669         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
670         IDProperty *idprop;
671
672         if((idprop=rna_idproperty_check(&prop, ptr)))
673                 ((int*)IDP_Array(idprop))[index]= value;
674         else if(iprop->setarray)
675                 iprop->setarray(ptr, index, value);
676         else if(!(prop->flag & PROP_NOT_EDITABLE)) {
677                 IDPropertyTemplate val;
678                 IDProperty *group;
679
680                 val.array.len= prop->arraylength;
681                 val.array.type= IDP_INT;
682
683                 group= rna_idproperties_get(ptr, 1);
684                 if(group) {
685                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
686                         IDP_AddToGroup(group, idprop);
687                         if(iprop->defaultarray)
688                                 memcpy(idprop->data.pointer, iprop->defaultarray, sizeof(int)*prop->arraylength);
689                         else
690                                 memset(idprop->data.pointer, 0, sizeof(int)*prop->arraylength);
691                         ((int*)idprop->data.pointer)[index]= value;
692                 }
693         }
694 }
695
696 float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
697 {
698         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
699         IDProperty *idprop;
700
701         if((idprop=rna_idproperty_check(&prop, ptr))) {
702                 if(idprop->type == IDP_FLOAT)
703                         return IDP_Float(idprop);
704                 else
705                         return (float)IDP_Double(idprop);
706         }
707         else if(fprop->get)
708                 return fprop->get(ptr);
709         else
710                 return fprop->defaultvalue;
711 }
712
713 void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
714 {
715         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
716         IDProperty *idprop;
717
718         if((idprop=rna_idproperty_check(&prop, ptr))) {
719                 if(idprop->type == IDP_FLOAT)
720                         IDP_Float(idprop)= value;
721                 else
722                         IDP_Double(idprop)= value;
723         }
724         else if(fprop->set) {
725                 fprop->set(ptr, value);
726         }
727         else if(!(prop->flag & PROP_NOT_EDITABLE)) {
728                 IDPropertyTemplate val;
729                 IDProperty *group;
730
731                 val.f= value;
732
733                 group= rna_idproperties_get(ptr, 1);
734                 if(group)
735                         IDP_AddToGroup(group, IDP_New(IDP_FLOAT, val, (char*)prop->identifier));
736         }
737 }
738
739 float RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, int index)
740 {
741         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
742         IDProperty *idprop;
743
744         if((idprop=rna_idproperty_check(&prop, ptr))) {
745                 if(idprop->subtype == IDP_FLOAT)
746                         return ((float*)IDP_Array(idprop))[index];
747                 else
748                         return (float)(((double*)IDP_Array(idprop))[index]);
749         }
750         else if(fprop->getarray)
751                 return fprop->getarray(ptr, index);
752         else if(fprop->defaultarray)
753                 return fprop->defaultarray[index];
754         else
755                 return 0.0f;
756 }
757
758 void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
759 {
760         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
761         IDProperty *idprop;
762
763         if((idprop=rna_idproperty_check(&prop, ptr))) {
764                 if(idprop->subtype == IDP_FLOAT)
765                         ((float*)IDP_Array(idprop))[index]= value;
766                 else
767                         ((double*)IDP_Array(idprop))[index]= value;
768         }
769         else if(fprop->setarray) {
770                 fprop->setarray(ptr, index, value);
771         }
772         else if(!(prop->flag & PROP_NOT_EDITABLE)) {
773                 IDPropertyTemplate val;
774                 IDProperty *group;
775
776                 val.array.len= prop->arraylength;
777                 val.array.type= IDP_FLOAT;
778
779                 group= rna_idproperties_get(ptr, 1);
780                 if(group) {
781                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
782                         IDP_AddToGroup(group, idprop);
783                         if(fprop->defaultarray)
784                                 memcpy(idprop->data.pointer, fprop->defaultarray, sizeof(float)*prop->arraylength);
785                         else
786                                 memset(idprop->data.pointer, 0, sizeof(float)*prop->arraylength);
787                         ((float*)IDP_Array(idprop))[index]= value;
788                 }
789         }
790 }
791
792 void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
793 {
794         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
795         IDProperty *idprop;
796
797         if((idprop=rna_idproperty_check(&prop, ptr)))
798                 strcpy(value, IDP_String(idprop));
799         else if(sprop->get)
800                 sprop->get(ptr, value);
801         else
802                 strcpy(value, sprop->defaultvalue);
803 }
804
805 char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen)
806 {
807         char *buf;
808         int length;
809
810         length= RNA_property_string_length(ptr, prop);
811
812         if(length+1 < fixedlen)
813                 buf= fixedbuf;
814         else
815                 buf= MEM_callocN(sizeof(char)*(length+1), "RNA_string_get_alloc");
816
817         RNA_property_string_get(ptr, prop, buf);
818
819         return buf;
820 }
821
822 int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
823 {
824         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
825         IDProperty *idprop;
826
827         if((idprop=rna_idproperty_check(&prop, ptr)))
828                 return strlen(IDP_String(idprop));
829         else if(sprop->length)
830                 return sprop->length(ptr);
831         else
832                 return strlen(sprop->defaultvalue);
833 }
834
835 void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
836 {
837         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
838         IDProperty *idprop;
839
840         if((idprop=rna_idproperty_check(&prop, ptr)))
841                 IDP_AssignString(idprop, (char*)value);
842         else if(sprop->set)
843                 sprop->set(ptr, value);
844         else if(!(prop->flag & PROP_NOT_EDITABLE)) {
845                 IDPropertyTemplate val;
846                 IDProperty *group;
847
848                 val.str= (char*)value;
849
850                 group= rna_idproperties_get(ptr, 1);
851                 if(group)
852                         IDP_AddToGroup(group, IDP_New(IDP_STRING, val, (char*)prop->identifier));
853         }
854 }
855
856 int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
857 {
858         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
859         IDProperty *idprop;
860
861         if((idprop=rna_idproperty_check(&prop, ptr)))
862                 return IDP_Int(idprop);
863         else if(eprop->get)
864                 return eprop->get(ptr);
865         else
866                 return eprop->defaultvalue;
867 }
868
869
870 void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
871 {
872         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
873         IDProperty *idprop;
874
875         if((idprop=rna_idproperty_check(&prop, ptr)))
876                 IDP_Int(idprop)= value;
877         else if(eprop->set) {
878                 eprop->set(ptr, value);
879         }
880         else if(!(prop->flag & PROP_NOT_EDITABLE)) {
881                 IDPropertyTemplate val;
882                 IDProperty *group;
883
884                 val.i= value;
885
886                 group= rna_idproperties_get(ptr, 1);
887                 if(group)
888                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
889         }
890 }
891
892 static StructRNA *rna_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
893 {
894         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
895         StructRNA *type;
896
897         if(pprop->type)
898                 type= pprop->type(ptr);
899         else
900                 type= pprop->structtype;
901         
902         if(type) {
903                 rna_pointer_inherit_id(type, ptr, r_ptr);
904
905                 if(type->refine)
906                         type= type->refine(r_ptr);
907         }
908         
909         r_ptr->type= type;
910         return type;
911 }
912
913 void RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
914 {
915         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
916         IDProperty *idprop;
917
918         if((idprop=rna_idproperty_check(&prop, ptr)))
919                 r_ptr->data= idprop; /* for groups, data is idprop itself */
920         else if(pprop->get)
921                 r_ptr->data= pprop->get(ptr);
922         else
923                 r_ptr->data= NULL;
924
925         if(!(r_ptr->data && rna_property_pointer_type(ptr, prop, r_ptr)))
926                 memset(r_ptr, 0, sizeof(*r_ptr));
927 }
928
929 void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *ptr_value)
930 {
931         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
932
933         if(pprop->set)
934                 pprop->set(ptr, ptr_value->data);
935 }
936
937 void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop)
938 {
939         IDProperty *idprop;
940
941         if((idprop=rna_idproperty_check(&prop, ptr))) {
942                 /* already exists */
943         }
944         else if(prop->flag & PROP_IDPROPERTY) {
945                 IDPropertyTemplate val;
946                 IDProperty *group;
947
948                 val.i= 0;
949
950                 group= rna_idproperties_get(ptr, 1);
951                 if(group)
952                         IDP_AddToGroup(group, IDP_New(IDP_GROUP, val, (char*)prop->identifier));
953         }
954         else
955                 printf("RNA_property_pointer_add %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);
956 }
957
958 static StructRNA *rna_property_collection_type(CollectionPropertyIterator *iter)
959 {
960         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
961         StructRNA *type;
962
963         if(cprop->type)
964                 type= cprop->type(iter);
965         else
966                 type= cprop->structtype;
967         
968         if(type) {
969                 rna_pointer_inherit_id(type, &iter->parent, &iter->ptr);
970
971                 if(type->refine)
972                         type= type->refine(&iter->ptr);
973         }
974         
975         iter->ptr.type= type;
976         return type;
977 }
978
979 static void rna_property_collection_get(CollectionPropertyIterator *iter)
980 {
981         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
982
983         iter->ptr.data= cprop->get(iter);
984
985         if(!(iter->ptr.data && rna_property_collection_type(iter)))
986                 memset(&iter->ptr, 0, sizeof(iter->ptr));
987 }
988
989 static void rna_property_collection_get_idp(CollectionPropertyIterator *iter)
990 {
991         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
992
993         iter->ptr.data= rna_iterator_array_get(iter);
994         iter->ptr.type= cprop->structtype;
995         rna_pointer_inherit_id(cprop->structtype, &iter->parent, &iter->ptr);
996 }
997
998 void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter)
999 {
1000         IDProperty *idprop;
1001
1002         if((idprop=rna_idproperty_check(&prop, ptr)) || (prop->flag & PROP_IDPROPERTY)) {
1003                 iter->parent= *ptr;
1004                 iter->prop= prop;
1005
1006                 if(idprop)
1007                         rna_iterator_array_begin(iter, IDP_IDPArray(idprop), sizeof(IDProperty), idprop->len, NULL);
1008                 else
1009                         rna_iterator_array_begin(iter, NULL, sizeof(IDProperty), 0, NULL);
1010
1011                 if(iter->valid)
1012                         rna_property_collection_get_idp(iter);
1013                 else
1014                         memset(&iter->ptr, 0, sizeof(iter->ptr));
1015
1016                 iter->idprop= 1;
1017         }
1018         else {
1019                 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1020
1021                 if(cprop->begin) {
1022                         iter->parent= *ptr;
1023                         iter->prop= prop;
1024                         iter->idprop= 0;
1025                         cprop->begin(iter, ptr);
1026
1027                         if(iter->valid)
1028                                 rna_property_collection_get(iter);
1029                         else
1030                                 memset(&iter->ptr, 0, sizeof(iter->ptr));
1031                 }
1032                 else 
1033                         memset(iter, 0, sizeof(*iter));
1034         }
1035 }
1036
1037 void RNA_property_collection_next(CollectionPropertyIterator *iter)
1038 {
1039         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
1040
1041         if(iter->idprop) {
1042                 rna_iterator_array_next(iter);
1043
1044                 if(iter->valid)
1045                         rna_property_collection_get_idp(iter);
1046                 else
1047                         memset(&iter->ptr, 0, sizeof(iter->ptr));
1048         }
1049         else {
1050                 cprop->next(iter);
1051
1052                 if(iter->valid)
1053                         rna_property_collection_get(iter);
1054                 else
1055                         memset(&iter->ptr, 0, sizeof(iter->ptr));
1056         }
1057 }
1058
1059 void RNA_property_collection_end(CollectionPropertyIterator *iter)
1060 {
1061         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
1062
1063         if(iter->idprop)
1064                 rna_iterator_array_end(iter);
1065         else if(cprop->end)
1066                 cprop->end(iter);
1067 }
1068
1069 int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
1070 {
1071         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1072         IDProperty *idprop;
1073
1074         if((idprop=rna_idproperty_check(&prop, ptr))) {
1075                 return idprop->len;
1076         }
1077         else if(cprop->length) {
1078                 return cprop->length(ptr);
1079         }
1080         else {
1081                 CollectionPropertyIterator iter;
1082                 int length= 0;
1083
1084                 RNA_property_collection_begin(ptr, prop, &iter);
1085                 for(; iter.valid; RNA_property_collection_next(&iter))
1086                         length++;
1087                 RNA_property_collection_end(&iter);
1088
1089                 return length;
1090         }
1091 }
1092
1093 void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
1094 {
1095         IDProperty *idprop;
1096
1097         if((idprop=rna_idproperty_check(&prop, ptr))) {
1098                 IDPropertyTemplate val;
1099                 IDProperty *item;
1100                 val.i= 0;
1101
1102                 item= IDP_New(IDP_GROUP, val, "");
1103                 IDP_AppendArray(idprop, item);
1104                 IDP_FreeProperty(item);
1105                 MEM_freeN(item);
1106         }
1107         else if(prop->flag & PROP_IDPROPERTY) {
1108                 IDProperty *group, *item;
1109                 IDPropertyTemplate val;
1110                 val.i= 0;
1111
1112                 group= rna_idproperties_get(ptr, 1);
1113                 if(group) {
1114                         idprop= IDP_NewIDPArray(prop->identifier);
1115                         IDP_AddToGroup(group, idprop);
1116
1117                         item= IDP_New(IDP_GROUP, val, "");
1118                         IDP_AppendArray(idprop, item);
1119                         IDP_FreeProperty(item);
1120                         MEM_freeN(item);
1121                 }
1122         }
1123         else
1124                 printf("RNA_property_collection_add %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);
1125
1126         if(r_ptr) {
1127                 if(idprop) {
1128                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1129
1130                         r_ptr->data= IDP_GetIndexArray(idprop, idprop->len-1);
1131                         r_ptr->type= cprop->structtype;
1132                         rna_pointer_inherit_id(NULL, ptr, r_ptr);
1133                 }
1134                 else
1135                         memset(r_ptr, 0, sizeof(*r_ptr));
1136         }
1137 }
1138
1139 void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
1140 {
1141         IDProperty *idprop;
1142
1143         if((idprop=rna_idproperty_check(&prop, ptr)))
1144                 IDP_ResizeIDPArray(idprop, 0);
1145 }
1146
1147 int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
1148 {
1149         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1150
1151         if(cprop->lookupint) {
1152                 /* we have a callback defined, use it */
1153                 r_ptr->data= cprop->lookupint(ptr, key, &r_ptr->type);
1154
1155                 if(r_ptr->data) {
1156                         if(!r_ptr->type)
1157                                 r_ptr->type= cprop->structtype;
1158                         rna_pointer_inherit_id(r_ptr->type, ptr, r_ptr);
1159
1160                         return 1;
1161                 }
1162                 else {
1163                         memset(r_ptr, 0, sizeof(*r_ptr));
1164                         return 0;
1165                 }
1166         }
1167         else {
1168                 /* no callback defined, just iterate and find the nth item */
1169                 CollectionPropertyIterator iter;
1170                 int i;
1171
1172                 RNA_property_collection_begin(ptr, prop, &iter);
1173                 for(i=0; iter.valid; RNA_property_collection_next(&iter), i++) {
1174                         if(i == key) {
1175                                 *r_ptr= iter.ptr;
1176                                 break;
1177                         }
1178                 }
1179                 RNA_property_collection_end(&iter);
1180
1181                 if(!iter.valid)
1182                         memset(r_ptr, 0, sizeof(*r_ptr));
1183
1184                 return iter.valid;
1185         }
1186 }
1187
1188 int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr)
1189 {
1190         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1191
1192         if(cprop->lookupstring) {
1193                 /* we have a callback defined, use it */
1194                 r_ptr->data= cprop->lookupstring(ptr, key, &r_ptr->type);
1195
1196                 if(r_ptr->data) {
1197                         if(!r_ptr->type)
1198                                 r_ptr->type= cprop->structtype;
1199                         rna_pointer_inherit_id(r_ptr->type, ptr, r_ptr);
1200
1201                         return 1;
1202                 }
1203                 else {
1204                         memset(r_ptr, 0, sizeof(*r_ptr));
1205                         return 0;
1206                 }
1207         }
1208         else {
1209                 /* no callback defined, compare with name properties if they exist */
1210                 CollectionPropertyIterator iter;
1211                 PropertyRNA *nameprop;
1212                 char name[256], *nameptr;
1213                 int found= 0;
1214
1215                 RNA_property_collection_begin(ptr, prop, &iter);
1216                 for(; iter.valid; RNA_property_collection_next(&iter)) {
1217                         if(iter.ptr.data && iter.ptr.type->nameproperty) {
1218                                 nameprop= iter.ptr.type->nameproperty;
1219
1220                                 nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
1221
1222                                 if(strcmp(nameptr, key) == 0) {
1223                                         *r_ptr= iter.ptr;
1224                                         found= 1;
1225                                 }
1226
1227                                 if ((char *)&name != nameptr)
1228                                         MEM_freeN(nameptr);
1229
1230                                 if(found)
1231                                         break;
1232                         }
1233                 }
1234                 RNA_property_collection_end(&iter);
1235
1236                 if(!iter.valid)
1237                         memset(r_ptr, 0, sizeof(*r_ptr));
1238
1239                 return iter.valid;
1240         }
1241 }
1242
1243 /* Standard iterator functions */
1244
1245 void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip)
1246 {
1247         ListBaseIterator *internal;
1248
1249         internal= MEM_callocN(sizeof(ListBaseIterator), "ListBaseIterator");
1250         internal->link= lb->first;
1251         internal->skip= skip;
1252
1253         iter->internal= internal;
1254         iter->valid= (internal->link != NULL);
1255
1256         if(skip && iter->valid && skip(iter, internal->link))
1257                 rna_iterator_listbase_next(iter);
1258 }
1259
1260 void rna_iterator_listbase_next(CollectionPropertyIterator *iter)
1261 {
1262         ListBaseIterator *internal= iter->internal;
1263
1264         if(internal->skip) {
1265                 do {
1266                         internal->link= internal->link->next;
1267                         iter->valid= (internal->link != NULL);
1268                 } while(iter->valid && internal->skip(iter, internal->link));
1269         }
1270         else {
1271                 internal->link= internal->link->next;
1272                 iter->valid= (internal->link != NULL);
1273         }
1274 }
1275
1276 void *rna_iterator_listbase_get(CollectionPropertyIterator *iter)
1277 {
1278         ListBaseIterator *internal= iter->internal;
1279
1280         return internal->link;
1281 }
1282
1283 void rna_iterator_listbase_end(CollectionPropertyIterator *iter)
1284 {
1285         MEM_freeN(iter->internal);
1286 }
1287
1288 void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int itemsize, int length, IteratorSkipFunc skip)
1289 {
1290         ArrayIterator *internal;
1291
1292         if(ptr == NULL)
1293                 length= 0;
1294
1295         internal= MEM_callocN(sizeof(ArrayIterator), "ArrayIterator");
1296         internal->ptr= ptr;
1297         internal->endptr= ((char*)ptr)+length*itemsize;
1298         internal->itemsize= itemsize;
1299         internal->skip= skip;
1300
1301         iter->internal= internal;
1302         iter->valid= (internal->ptr != internal->endptr);
1303
1304         if(skip && iter->valid && skip(iter, internal->ptr))
1305                 rna_iterator_array_next(iter);
1306 }
1307
1308 void rna_iterator_array_next(CollectionPropertyIterator *iter)
1309 {
1310         ArrayIterator *internal= iter->internal;
1311
1312         if(internal->skip) {
1313                 do {
1314                         internal->ptr += internal->itemsize;
1315                         iter->valid= (internal->ptr != internal->endptr);
1316                 } while(iter->valid && internal->skip(iter, internal->ptr));
1317         }
1318         else {
1319                 internal->ptr += internal->itemsize;
1320                 iter->valid= (internal->ptr != internal->endptr);
1321         }
1322 }
1323
1324 void *rna_iterator_array_get(CollectionPropertyIterator *iter)
1325 {
1326         ArrayIterator *internal= iter->internal;
1327
1328         return internal->ptr;
1329 }
1330
1331 void *rna_iterator_array_dereference_get(CollectionPropertyIterator *iter)
1332 {
1333         ArrayIterator *internal= iter->internal;
1334
1335         /* for ** arrays */
1336         return *(void**)(internal->ptr);
1337 }
1338
1339 void rna_iterator_array_end(CollectionPropertyIterator *iter)
1340 {
1341         MEM_freeN(iter->internal);
1342 }
1343
1344 /* RNA Path - Experiment */
1345
1346 static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int bracket)
1347 {
1348         const char *p;
1349         char *buf;
1350         int i, j, len, escape;
1351
1352         len= 0;
1353
1354         if(bracket) {
1355                 /* get data between [], check escaping ] with \] */
1356                 if(**path == '[') (*path)++;
1357                 else return NULL;
1358
1359                 p= *path;
1360
1361                 escape= 0;
1362                 while(*p && (*p != ']' || escape)) {
1363                         escape= (*p == '\\');
1364                         len++;
1365                         p++;
1366                 }
1367
1368                 if(*p != ']') return NULL;
1369         }
1370         else {
1371                 /* get data until . or [ */
1372                 p= *path;
1373
1374                 while(*p && *p != '.' && *p != '[') {
1375                         len++;
1376                         p++;
1377                 }
1378         }
1379         
1380         /* empty, return */
1381         if(len == 0)
1382                 return NULL;
1383         
1384         /* try to use fixed buffer if possible */
1385         if(len+1 < fixedlen)
1386                 buf= fixedbuf;
1387         else
1388                 buf= MEM_callocN(sizeof(char)*(len+1), "rna_path_token");
1389
1390         /* copy string, taking into account escaped ] */
1391         for(p=*path, i=0, j=0; i<len; i++, p++) {
1392                 if(*p == '\\' && *(p+1) == ']');
1393                 else buf[j++]= *p;
1394         }
1395
1396         buf[j]= 0;
1397
1398         /* set path to start of next token */
1399         if(*p == ']') p++;
1400         if(*p == '.') p++;
1401         *path= p;
1402
1403         return buf;
1404 }
1405
1406 int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
1407 {
1408         CollectionPropertyIterator iter;
1409         PropertyRNA *prop, *iterprop;
1410         PointerRNA curptr, nextptr;
1411         char fixedbuf[256], *token;
1412         int len, intkey;
1413
1414         prop= NULL;
1415         curptr= *ptr;
1416
1417         while(*path) {
1418                 /* look up property name in current struct */
1419                 token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 0);
1420
1421                 if(!token)
1422                         return 0;
1423
1424                 iterprop= RNA_struct_iterator_property(&curptr);
1425                 RNA_property_collection_begin(&curptr, iterprop, &iter);
1426                 prop= NULL;
1427
1428                 for(; iter.valid; RNA_property_collection_next(&iter)) {
1429                         if(strcmp(token, RNA_property_identifier(&iter.ptr, iter.ptr.data)) == 0) {
1430                                 prop= iter.ptr.data;
1431                                 break;
1432                         }
1433                 }
1434
1435                 RNA_property_collection_end(&iter);
1436
1437                 if(token != fixedbuf)
1438                         MEM_freeN(token);
1439
1440                 if(!prop)
1441                         return 0;
1442
1443                 /* now look up the value of this property if it is a pointer or
1444                  * collection, otherwise return the property rna so that the
1445                  * caller can read the value of the property itself */
1446                 if(RNA_property_type(&curptr, prop) == PROP_POINTER) {
1447                         RNA_property_pointer_get(&curptr, prop, &nextptr);
1448
1449                         if(nextptr.data)
1450                                 curptr= nextptr;
1451                         else
1452                                 return 0;
1453                 }
1454                 else if(RNA_property_type(&curptr, prop) == PROP_COLLECTION && *path) {
1455                         /* resolve the lookup with [] brackets */
1456                         token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1);
1457
1458                         if(!token)
1459                                 return 0;
1460
1461                         len= strlen(token);
1462
1463                         /* check for "" to see if it is a string */
1464                         if(len >= 2 && *token == '"' && token[len-2] == '"') {
1465                                 /* strip away "" */
1466                                 token[len-2]= 0;
1467                                 RNA_property_collection_lookup_string(&curptr, prop, token+1, &nextptr);
1468                         }
1469                         else {
1470                                 /* otherwise do int lookup */
1471                                 intkey= atoi(token);
1472                                 RNA_property_collection_lookup_int(&curptr, prop, intkey, &nextptr);
1473                         }
1474
1475                         if(token != fixedbuf)
1476                                 MEM_freeN(token);
1477
1478                         if(nextptr.data)
1479                                 curptr= nextptr;
1480                         else
1481                                 return 0;
1482                 }
1483         }
1484
1485         *r_ptr= curptr;
1486         *r_prop= prop;
1487
1488         return 1;
1489 }
1490
1491 char *RNA_path_append(const char *path, PointerRNA *ptr, PropertyRNA *prop, int intkey, const char *strkey)
1492 {
1493         DynStr *dynstr;
1494         const char *s;
1495         char appendstr[128], *result;
1496         
1497         dynstr= BLI_dynstr_new();
1498
1499         /* add .identifier */
1500         if(path) {
1501                 BLI_dynstr_append(dynstr, (char*)path);
1502                 if(*path)
1503                         BLI_dynstr_append(dynstr, ".");
1504         }
1505
1506         BLI_dynstr_append(dynstr, (char*)RNA_property_identifier(ptr, prop));
1507
1508         if(RNA_property_type(ptr, prop) == PROP_COLLECTION) {
1509                 /* add ["strkey"] or [intkey] */
1510                 BLI_dynstr_append(dynstr, "[");
1511
1512                 if(strkey) {
1513                         BLI_dynstr_append(dynstr, "\"");
1514                         for(s=strkey; *s; s++) {
1515                                 if(*s == '[') {
1516                                         appendstr[0]= '\\';
1517                                         appendstr[1]= *s;
1518                                         appendstr[2]= 0;
1519                                 }
1520                                 else {
1521                                         appendstr[0]= *s;
1522                                         appendstr[1]= 0;
1523                                 }
1524                                 BLI_dynstr_append(dynstr, appendstr);
1525                         }
1526                         BLI_dynstr_append(dynstr, "\"");
1527                 }
1528                 else {
1529                         sprintf(appendstr, "%d", intkey);
1530                         BLI_dynstr_append(dynstr, appendstr);
1531                 }
1532
1533                 BLI_dynstr_append(dynstr, "]");
1534         }
1535
1536         result= BLI_dynstr_get_cstring(dynstr);
1537         BLI_dynstr_free(dynstr);
1538
1539         return result;
1540 }
1541
1542 char *RNA_path_back(const char *path)
1543 {
1544         char fixedbuf[256];
1545         const char *previous, *current;
1546         char *result, *token;
1547         int i;
1548
1549         if(!path)
1550                 return NULL;
1551
1552         previous= NULL;
1553         current= path;
1554
1555         /* parse token by token until the end, then we back up to the previous
1556          * position and strip of the next token to get the path one step back */
1557         while(*current) {
1558                 token= rna_path_token(&current, fixedbuf, sizeof(fixedbuf), 0);
1559
1560                 if(!token)
1561                         return NULL;
1562                 if(token != fixedbuf)
1563                         MEM_freeN(token);
1564
1565                 /* in case of collection we also need to strip off [] */
1566                 token= rna_path_token(&current, fixedbuf, sizeof(fixedbuf), 1);
1567                 if(token && token != fixedbuf)
1568                         MEM_freeN(token);
1569                 
1570                 if(!*current)
1571                         break;
1572
1573                 previous= current;
1574         }
1575
1576         if(!previous)
1577                 return NULL;
1578
1579         /* copy and strip off last token */
1580         i= previous - path;
1581         result= BLI_strdup(path);
1582
1583         if(i > 0 && result[i-1] == '.') i--;
1584         result[i]= 0;
1585
1586         return result;
1587 }
1588
1589 /* Quick name based property access */
1590
1591 int RNA_boolean_get(PointerRNA *ptr, const char *name)
1592 {
1593         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1594
1595         if(prop) {
1596                 return RNA_property_boolean_get(ptr, prop);
1597         }
1598         else {
1599                 printf("RNA_boolean_get: %s.%s not found.\n", ptr->type->identifier, name);
1600                 return 0;
1601         }
1602 }
1603
1604 void RNA_boolean_set(PointerRNA *ptr, const char *name, int value)
1605 {
1606         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1607
1608         if(prop)
1609                 RNA_property_boolean_set(ptr, prop, value);
1610         else
1611                 printf("RNA_boolean_set: %s.%s not found.\n", ptr->type->identifier, name);
1612 }
1613
1614 void RNA_boolean_get_array(PointerRNA *ptr, const char *name, int *values)
1615 {
1616         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1617         int i, length;
1618
1619         if(prop) {
1620                 length= RNA_property_array_length(ptr, prop);
1621                 for(i=0; i<length; i++)
1622                         values[i]= RNA_property_boolean_get_array(ptr, prop, i);
1623         }
1624         else
1625                 printf("RNA_boolean_get_array: %s.%s not found.\n", ptr->type->identifier, name);
1626 }
1627
1628 void RNA_boolean_set_array(PointerRNA *ptr, const char *name, const int *values)
1629 {
1630         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1631         int i, length;
1632
1633         if(prop) {
1634                 length= RNA_property_array_length(ptr, prop);
1635                 for(i=0; i<length; i++)
1636                         RNA_property_boolean_set_array(ptr, prop, i, values[i]);
1637         }
1638         else
1639                 printf("RNA_boolean_set_array: %s.%s not found.\n", ptr->type->identifier, name);
1640 }
1641
1642 int RNA_int_get(PointerRNA *ptr, const char *name)
1643 {
1644         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1645
1646         if(prop) {
1647                 return RNA_property_int_get(ptr, prop);
1648         }
1649         else {
1650                 printf("RNA_int_get: %s.%s not found.\n", ptr->type->identifier, name);
1651                 return 0;
1652         }
1653 }
1654
1655 void RNA_int_set(PointerRNA *ptr, const char *name, int value)
1656 {
1657         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1658
1659         if(prop)
1660                 RNA_property_int_set(ptr, prop, value);
1661         else
1662                 printf("RNA_int_set: %s.%s not found.\n", ptr->type->identifier, name);
1663 }
1664
1665 void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values)
1666 {
1667         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1668         int i, length;
1669
1670         if(prop) {
1671                 length= RNA_property_array_length(ptr, prop);
1672                 for(i=0; i<length; i++)
1673                         values[i]= RNA_property_int_get_array(ptr, prop, i);
1674         }
1675         else
1676                 printf("RNA_int_get_array: %s.%s not found.\n", ptr->type->identifier, name);
1677 }
1678
1679 void RNA_int_set_array(PointerRNA *ptr, const char *name, const int *values)
1680 {
1681         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1682         int i, length;
1683
1684         if(prop) {
1685                 length= RNA_property_array_length(ptr, prop);
1686                 for(i=0; i<length; i++)
1687                         RNA_property_int_set_array(ptr, prop, i, values[i]);
1688         }
1689         else
1690                 printf("RNA_int_set_array: %s.%s not found.\n", ptr->type->identifier, name);
1691 }
1692
1693 float RNA_float_get(PointerRNA *ptr, const char *name)
1694 {
1695         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1696
1697         if(prop) {
1698                 return RNA_property_float_get(ptr, prop);
1699         }
1700         else {
1701                 printf("RNA_float_get: %s.%s not found.\n", ptr->type->identifier, name);
1702                 return 0;
1703         }
1704 }
1705
1706 void RNA_float_set(PointerRNA *ptr, const char *name, float value)
1707 {
1708         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1709
1710         if(prop)
1711                 RNA_property_float_set(ptr, prop, value);
1712         else
1713                 printf("RNA_float_set: %s.%s not found.\n", ptr->type->identifier, name);
1714 }
1715
1716 void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
1717 {
1718         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1719         int i, length;
1720
1721         if(prop) {
1722                 length= RNA_property_array_length(ptr, prop);
1723                 for(i=0; i<length; i++)
1724                         values[i]= RNA_property_float_get_array(ptr, prop, i);
1725         }
1726         else
1727                 printf("RNA_float_get_array: %s.%s not found.\n", ptr->type->identifier, name);
1728 }
1729
1730 void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
1731 {
1732         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1733         int i, length;
1734
1735         if(prop) {
1736                 length= RNA_property_array_length(ptr, prop);
1737                 for(i=0; i<length; i++)
1738                         RNA_property_float_set_array(ptr, prop, i, values[i]);
1739         }
1740         else
1741                 printf("RNA_float_set_array: %s.%s not found.\n", ptr->type->identifier, name);
1742 }
1743
1744 int RNA_enum_get(PointerRNA *ptr, const char *name)
1745 {
1746         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1747
1748         if(prop) {
1749                 return RNA_property_enum_get(ptr, prop);
1750         }
1751         else {
1752                 printf("RNA_enum_get: %s.%s not found.\n", ptr->type->identifier, name);
1753                 return 0;
1754         }
1755 }
1756
1757 void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
1758 {
1759         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1760
1761         if(prop)
1762                 RNA_property_enum_set(ptr, prop, value);
1763         else
1764                 printf("RNA_enum_set: %s.%s not found.\n", ptr->type->identifier, name);
1765 }
1766
1767 int RNA_enum_is_equal(PointerRNA *ptr, const char *name, const char *enumname)
1768 {
1769         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1770         const EnumPropertyItem *item;
1771         int a, totitem;
1772
1773         if(prop) {
1774                 RNA_property_enum_items(ptr, prop, &item, &totitem);
1775
1776                 for(a=0; a<totitem; a++)
1777                         if(strcmp(item[a].identifier, enumname) == 0)
1778                                 return (item[a].value == RNA_property_enum_get(ptr, prop));
1779
1780                 printf("RNA_enum_is_equal: %s.%s item %s not found.\n", ptr->type->identifier, name, enumname);
1781                 return 0;
1782         }
1783         else {
1784                 printf("RNA_enum_is_equal: %s.%s not found.\n", ptr->type->identifier, name);
1785                 return 0;
1786         }
1787 }
1788
1789 void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
1790 {
1791         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1792
1793         if(prop)
1794                 RNA_property_string_get(ptr, prop, value);
1795         else
1796                 printf("RNA_string_get: %s.%s not found.\n", ptr->type->identifier, name);
1797 }
1798
1799 char *RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen)
1800 {
1801         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1802
1803         if(prop) {
1804                 return RNA_property_string_get_alloc(ptr, prop, fixedbuf, fixedlen);
1805         }
1806         else {
1807                 printf("RNA_string_get_alloc: %s.%s not found.\n", ptr->type->identifier, name);
1808                 return 0;
1809         }
1810 }
1811
1812 int RNA_string_length(PointerRNA *ptr, const char *name)
1813 {
1814         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1815
1816         if(prop) {
1817                 return RNA_property_string_length(ptr, prop);
1818         }
1819         else {
1820                 printf("RNA_string_length: %s.%s not found.\n", ptr->type->identifier, name);
1821                 return 0;
1822         }
1823 }
1824
1825 void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
1826 {
1827         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1828
1829         if(prop)
1830                 RNA_property_string_set(ptr, prop, value);
1831         else
1832                 printf("RNA_string_set: %s.%s not found.\n", ptr->type->identifier, name);
1833 }
1834
1835 void RNA_pointer_get(PointerRNA *ptr, const char *name, PointerRNA *r_value)
1836 {
1837         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1838
1839         if(prop)
1840                 RNA_property_pointer_get(ptr, prop, r_value);
1841         else
1842                 printf("RNA_pointer_get: %s.%s not found.\n", ptr->type->identifier, name);
1843 }
1844
1845 void RNA_pointer_add(PointerRNA *ptr, const char *name)
1846 {
1847         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1848
1849         if(prop)
1850                 RNA_property_pointer_add(ptr, prop);
1851         else
1852                 printf("RNA_pointer_set: %s.%s not found.\n", ptr->type->identifier, name);
1853 }
1854
1855 void RNA_collection_begin(PointerRNA *ptr, const char *name, CollectionPropertyIterator *iter)
1856 {
1857         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1858
1859         if(prop)
1860                 RNA_property_collection_begin(ptr, prop, iter);
1861         else
1862                 printf("RNA_collection_begin: %s.%s not found.\n", ptr->type->identifier, name);
1863 }
1864
1865 void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value)
1866 {
1867         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1868
1869         if(prop)
1870                 RNA_property_collection_add(ptr, prop, r_value);
1871         else
1872                 printf("RNA_collection_add: %s.%s not found.\n", ptr->type->identifier, name);
1873 }
1874
1875 void RNA_collection_clear(PointerRNA *ptr, const char *name)
1876 {
1877         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1878
1879         if(prop)
1880                 RNA_property_collection_clear(ptr, prop);
1881         else
1882                 printf("RNA_collection_clear: %s.%s not found.\n", ptr->type->identifier, name);
1883 }
1884
1885 int RNA_collection_length(PointerRNA *ptr, const char *name)
1886 {
1887         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1888
1889         if(prop) {
1890                 return RNA_property_collection_length(ptr, prop);
1891         }
1892         else {
1893                 printf("RNA_collection_length: %s.%s not found.\n", ptr->type->identifier, name);
1894                 return 0;
1895         }
1896 }
1897
1898 int RNA_property_is_set(PointerRNA *ptr, const char *name)
1899 {
1900         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1901
1902         if(prop) {
1903                 return (rna_idproperty_find(ptr, name) != NULL);
1904         }
1905         else {
1906                 printf("RNA_property_is_set: %s.%s not found.\n", ptr->type->identifier, name);
1907                 return 0;
1908         }
1909 }
1910
1911 /* string representation of a property, python
1912  * compatible but can be used for display too*/
1913 char *RNA_property_as_string(PointerRNA *ptr, PropertyRNA *prop)
1914 {
1915         int type = RNA_property_type(ptr, prop);
1916         int len = RNA_property_array_length(ptr, prop);
1917         int i;
1918
1919         DynStr *dynstr= BLI_dynstr_new();
1920         char *cstring;
1921         
1922
1923         /* see if we can coorce into a python type - PropertyType */
1924         switch (type) {
1925         case PROP_BOOLEAN:
1926                 if (len==0) {
1927                         BLI_dynstr_append(dynstr, RNA_property_boolean_get(ptr, prop) ? "True" : "False");
1928                 }
1929                 else {
1930                         BLI_dynstr_append(dynstr, "(");
1931                         for(i=0; i<len; i++) {
1932                                 BLI_dynstr_appendf(dynstr, i?"%s, ":"%s", RNA_property_boolean_get_array(ptr, prop, i) ? "True" : "False");
1933                         }
1934                         BLI_dynstr_append(dynstr, ")");
1935                 }
1936                 break;
1937         case PROP_INT:
1938                 if (len==0) {
1939                         BLI_dynstr_appendf(dynstr, "%d", RNA_property_int_get(ptr, prop));
1940                 }
1941                 else {
1942                         BLI_dynstr_append(dynstr, "(");
1943                         for(i=0; i<len; i++) {
1944                                 BLI_dynstr_appendf(dynstr, i?"%d, ":"%d", RNA_property_int_get_array(ptr, prop, i));
1945                         }
1946                         BLI_dynstr_append(dynstr, ")");
1947                 }
1948                 break;
1949         case PROP_FLOAT:
1950                 if (len==0) {
1951                         BLI_dynstr_appendf(dynstr, "%f", RNA_property_float_get(ptr, prop));
1952                 }
1953                 else {
1954                         BLI_dynstr_append(dynstr, "(");
1955                         for(i=0; i<len; i++) {
1956                                 BLI_dynstr_appendf(dynstr, i?"%f, ":"%f", RNA_property_float_get_array(ptr, prop, i));
1957                         }
1958                         BLI_dynstr_append(dynstr, ")");
1959                 }
1960                 break;
1961         case PROP_STRING:
1962         {
1963                 /* string arrays dont exist */
1964                 char *buf;
1965                 buf = RNA_property_string_get_alloc(ptr, prop, NULL, -1);
1966                 BLI_dynstr_appendf(dynstr, "\"%s\"", buf);
1967                 MEM_freeN(buf);
1968                 break;
1969         }
1970         case PROP_ENUM:
1971         {
1972                 /* string arrays dont exist */
1973                 const char *identifier;
1974                 int val = RNA_property_enum_get(ptr, prop);
1975
1976                 if (RNA_property_enum_identifier(ptr, prop, val, &identifier)) {
1977                         BLI_dynstr_appendf(dynstr, "'%s'", identifier);
1978                 }
1979                 else {
1980                         BLI_dynstr_appendf(dynstr, "'<UNKNOWN ENUM>'", identifier);
1981                 }
1982                 break;
1983         }
1984         case PROP_POINTER:
1985         {
1986                 BLI_dynstr_append(dynstr, "'<POINTER>'"); /* TODO */
1987                 break;
1988         }
1989         case PROP_COLLECTION:
1990                 BLI_dynstr_append(dynstr, "'<COLLECTION>'"); /* TODO */
1991                 break;
1992         default:
1993                 BLI_dynstr_append(dynstr, "'<UNKNOWN TYPE>'"); /* TODO */
1994                 break;
1995         }
1996
1997         cstring = BLI_dynstr_get_cstring(dynstr);
1998         BLI_dynstr_free(dynstr);
1999         return cstring;
2000 }
2001