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