Eevee: TAA: Remove 32 sample limit.
[blender.git] / source / blender / makesrna / intern / rna_ui.c
index 635dfb48b275a0c79e9d291e76f2d338765ddcb1..08038b0b1ffd71feb3e0dd4010fb178dcf5708ff 100644 (file)
 
 #include "DNA_screen_types.h"
 
+#include "BLT_translation.h"
+
+#include "BKE_idprop.h"
+
 #include "RNA_define.h"
 
 #include "rna_internal.h"
@@ -39,7 +43,7 @@
 #include "WM_types.h"
 
 /* see WM_types.h */
-EnumPropertyItem operator_context_items[] = {
+EnumPropertyItem rna_enum_operator_context_items[] = {
        {WM_OP_INVOKE_DEFAULT, "INVOKE_DEFAULT", 0, "Invoke Default", ""},
        {WM_OP_INVOKE_REGION_WIN, "INVOKE_REGION_WIN", 0, "Invoke Region Window", ""},
        {WM_OP_INVOKE_REGION_CHANNELS, "INVOKE_REGION_CHANNELS", 0, "Invoke Region Channels", ""},
@@ -52,7 +56,15 @@ EnumPropertyItem operator_context_items[] = {
        {WM_OP_EXEC_REGION_PREVIEW, "EXEC_REGION_PREVIEW", 0, "Exec Region Preview", ""},
        {WM_OP_EXEC_AREA, "EXEC_AREA", 0, "Exec Area", ""},
        {WM_OP_EXEC_SCREEN, "EXEC_SCREEN", 0, "Exec Screen", ""},
-       {0, NULL, 0, NULL, NULL}};
+       {0, NULL, 0, NULL, NULL}
+};
+
+EnumPropertyItem rna_enum_uilist_layout_type_items[] = {
+       {UILST_LAYOUT_DEFAULT, "DEFAULT", 0, "Default Layout", "Use the default, multi-rows layout"},
+       {UILST_LAYOUT_COMPACT, "COMPACT", 0, "Compact Layout", "Use the compact, single-row layout"},
+       {UILST_LAYOUT_GRID, "GRID", 0, "Grid Layout", "Use the grid-based layout"},
+       {0, NULL, 0, NULL, NULL}
+};
 
 #ifdef RNA_RUNTIME
 
@@ -77,14 +89,14 @@ static ARegionType *region_type_find(ReportList *reports, int space_type, int re
 
        st = BKE_spacetype_from_id(space_type);
 
-       for (art = (st)? st->regiontypes.first: NULL; art; art = art->next) {
+       for (art = (st) ? st->regiontypes.first : NULL; art; art = art->next) {
                if (art->regionid == region_type)
                        break;
        }
        
        /* region type not found? abort */
        if (art == NULL) {
-               BKE_report(reports, RPT_ERROR, "Region not found in spacetype");
+               BKE_report(reports, RPT_ERROR, "Region not found in space type");
                return NULL;
        }
 
@@ -111,7 +123,7 @@ static int panel_poll(const bContext *C, PanelType *pt)
        pt->ext.call((bContext *)C, &ptr, func, &list);
 
        RNA_parameter_get_lookup(&list, "visible", &ret);
-       visible = *(int*)ret;
+       visible = *(int *)ret;
 
        RNA_parameter_list_free(&list);
 
@@ -127,7 +139,7 @@ static void panel_draw(const bContext *C, Panel *pnl)
        FunctionRNA *func;
 
        RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->ext.srna, pnl, &ptr);
-       func = &rna_Panel_draw_func;/* RNA_struct_find_function(&ptr, "draw"); */
+       func = &rna_Panel_draw_func; /* RNA_struct_find_function(&ptr, "draw"); */
 
        RNA_parameter_list_create(&list, &ptr, func);
        RNA_parameter_set_lookup(&list, "context", &C);
@@ -165,16 +177,17 @@ static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type)
                return;
        
        RNA_struct_free_extension(type, &pt->ext);
+       RNA_struct_free(&BLENDER_RNA, type);
 
        BLI_freelinkN(&art->paneltypes, pt);
-       RNA_struct_free(&BLENDER_RNA, type);
 
        /* update while blender is running */
-       WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
+       WM_main_add_notifier(NC_WINDOW, NULL);
 }
 
-static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
-                                     StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+static StructRNA *rna_Panel_register(
+        Main *bmain, ReportList *reports, void *data, const char *identifier,
+        StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
 {
        ARegionType *art;
        PanelType *pt, dummypt = {NULL};
@@ -186,22 +199,30 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat
        dummypanel.type = &dummypt;
        RNA_pointer_create(NULL, &RNA_Panel, &dummypanel, &dummyptr);
 
+       /* We have to set default context! Else we get a void string... */
+       strcpy(dummypt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+
        /* validate the python class */
        if (validate(&dummyptr, data, have_function) != 0)
                return NULL;
                
        if (strlen(identifier) >= sizeof(dummypt.idname)) {
-               BKE_reportf(reports, RPT_ERROR, "registering panel class: '%s' is too long, maximum length is %d",
+               BKE_reportf(reports, RPT_ERROR, "Registering panel class: '%s' is too long, maximum length is %d",
                            identifier, (int)sizeof(dummypt.idname));
                return NULL;
        }
-       
+
+       if ((dummypt.category[0] == '\0') && (dummypt.region_type == RGN_TYPE_TOOLS)) {
+               /* Use a fallback, otherwise an empty value will draw the panel in every category. */
+               strcpy(dummypt.category, PNL_CATEGORY_FALLBACK);
+       }
+
        if (!(art = region_type_find(reports, dummypt.space_type, dummypt.region_type)))
                return NULL;
 
        /* check if we have registered this panel type before, and remove it */
        for (pt = art->paneltypes.first; pt; pt = pt->next) {
-               if (strcmp(pt->idname, dummypt.idname) == 0) {
+               if (STREQ(pt->idname, dummypt.idname)) {
                        if (pt->ext.srna)
                                rna_Panel_unregister(bmain, pt->ext.srna);
                        else
@@ -209,21 +230,28 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat
                        break;
                }
        }
+       if (!RNA_struct_available_or_report(reports, dummypt.idname)) {
+               return NULL;
+       }
+       if (!RNA_struct_bl_idname_ok_or_report(reports, dummypt.idname, "_PT_")) {
+               return NULL;
+       }
        
        /* create a new panel type */
        pt = MEM_callocN(sizeof(PanelType), "python buttons panel");
        memcpy(pt, &dummypt, sizeof(dummypt));
 
-       pt->ext.srna = RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel");
+       pt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, pt->idname, &RNA_Panel);
+       RNA_def_struct_translation_context(pt->ext.srna, pt->translation_context);
        pt->ext.data = data;
        pt->ext.call = call;
        pt->ext.free = free;
        RNA_struct_blender_type_set(pt->ext.srna, pt);
        RNA_def_struct_flag(pt->ext.srna, STRUCT_NO_IDPROPERTIES);
 
-       pt->poll = (have_function[0])? panel_poll: NULL;
-       pt->draw = (have_function[1])? panel_draw: NULL;
-       pt->draw_header = (have_function[2])? panel_draw_header: NULL;
+       pt->poll = (have_function[0]) ? panel_poll : NULL;
+       pt->draw = (have_function[1]) ? panel_draw : NULL;
+       pt->draw_header = (have_function[2]) ? panel_draw_header : NULL;
 
        /* XXX use "no header" flag for some ordering of panels until we have real panel ordering */
        if (pt->flag & PNL_NO_HEADER) {
@@ -240,15 +268,270 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat
                BLI_addtail(&art->paneltypes, pt);
 
        /* update while blender is running */
-       WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
+       WM_main_add_notifier(NC_WINDOW, NULL);
        
        return pt->ext.srna;
 }
 
-static StructRNA* rna_Panel_refine(PointerRNA *ptr)
+static StructRNA *rna_Panel_refine(PointerRNA *ptr)
+{
+       Panel *hdr = (Panel *)ptr->data;
+       return (hdr->type && hdr->type->ext.srna) ? hdr->type->ext.srna : &RNA_Panel;
+}
+
+/* UIList */
+static unsigned int rna_UIList_filter_const_FILTER_ITEM_get(PointerRNA *UNUSED(ptr))
+{
+       return UILST_FLT_ITEM;
+}
+
+static IDProperty *rna_UIList_idprops(PointerRNA *ptr, bool create)
 {
-       Panel *hdr = (Panel*)ptr->data;
-       return (hdr->type && hdr->type->ext.srna)? hdr->type->ext.srna: &RNA_Panel;
+       uiList *ui_list = (uiList *)ptr->data;
+       if (create && !ui_list->properties) {
+               IDPropertyTemplate val = {0};
+               ui_list->properties = IDP_New(IDP_GROUP, &val, "RNA_UIList IDproperties group");
+       }
+
+       return ui_list->properties;
+}
+
+static void uilist_draw_item(uiList *ui_list, bContext *C, uiLayout *layout, PointerRNA *dataptr, PointerRNA *itemptr,
+                             int icon, PointerRNA *active_dataptr, const char *active_propname, int index, int flt_flag)
+{
+       extern FunctionRNA rna_UIList_draw_item_func;
+
+       PointerRNA ul_ptr;
+       ParameterList list;
+       FunctionRNA *func;
+
+       RNA_pointer_create(&CTX_wm_screen(C)->id, ui_list->type->ext.srna, ui_list, &ul_ptr);
+       func = &rna_UIList_draw_item_func; /* RNA_struct_find_function(&ul_ptr, "draw_item"); */
+
+       RNA_parameter_list_create(&list, &ul_ptr, func);
+       RNA_parameter_set_lookup(&list, "context", &C);
+       RNA_parameter_set_lookup(&list, "layout", &layout);
+       RNA_parameter_set_lookup(&list, "data", dataptr);
+       RNA_parameter_set_lookup(&list, "item", itemptr);
+       RNA_parameter_set_lookup(&list, "icon", &icon);
+       RNA_parameter_set_lookup(&list, "active_data", active_dataptr);
+       RNA_parameter_set_lookup(&list, "active_property", &active_propname);
+       RNA_parameter_set_lookup(&list, "index", &index);
+       RNA_parameter_set_lookup(&list, "flt_flag", &flt_flag);
+       ui_list->type->ext.call((bContext *)C, &ul_ptr, func, &list);
+
+       RNA_parameter_list_free(&list);
+}
+
+static void uilist_draw_filter(uiList *ui_list, bContext *C, uiLayout *layout)
+{
+       extern FunctionRNA rna_UIList_draw_filter_func;
+
+       PointerRNA ul_ptr;
+       ParameterList list;
+       FunctionRNA *func;
+
+       RNA_pointer_create(&CTX_wm_screen(C)->id, ui_list->type->ext.srna, ui_list, &ul_ptr);
+       func = &rna_UIList_draw_filter_func; /* RNA_struct_find_function(&ul_ptr, "draw_filter"); */
+
+       RNA_parameter_list_create(&list, &ul_ptr, func);
+       RNA_parameter_set_lookup(&list, "context", &C);
+       RNA_parameter_set_lookup(&list, "layout", &layout);
+       ui_list->type->ext.call((bContext *)C, &ul_ptr, func, &list);
+
+       RNA_parameter_list_free(&list);
+}
+
+static void uilist_filter_items(uiList *ui_list, bContext *C, PointerRNA *dataptr, const char *propname)
+{
+       extern FunctionRNA rna_UIList_filter_items_func;
+
+       PointerRNA ul_ptr;
+       ParameterList list;
+       FunctionRNA *func;
+       PropertyRNA *parm;
+
+       uiListDyn *flt_data = ui_list->dyn_data;
+       int *filter_flags, *filter_neworder;
+       void *ret1, *ret2;
+       int ret_len;
+       int len = flt_data->items_len = RNA_collection_length(dataptr, propname);
+
+       RNA_pointer_create(&CTX_wm_screen(C)->id, ui_list->type->ext.srna, ui_list, &ul_ptr);
+       func = &rna_UIList_filter_items_func; /* RNA_struct_find_function(&ul_ptr, "filter_items"); */
+
+       RNA_parameter_list_create(&list, &ul_ptr, func);
+       RNA_parameter_set_lookup(&list, "context", &C);
+       RNA_parameter_set_lookup(&list, "data", dataptr);
+       RNA_parameter_set_lookup(&list, "property", &propname);
+
+       ui_list->type->ext.call((bContext *)C, &ul_ptr, func, &list);
+
+       parm = RNA_function_find_parameter(NULL, func, "filter_flags");
+       ret_len = RNA_parameter_dynamic_length_get(&list, parm);
+       if (ret_len != len && ret_len != 0) {
+               printf("%s: Error, py func returned %d items in %s, %d or none were expected.\n", __func__,
+                      RNA_parameter_dynamic_length_get(&list, parm), "filter_flags", len);
+               /* Note: we cannot return here, we would let flt_data in inconsistent state... see T38356. */
+               filter_flags = NULL;
+       }
+       else {
+               RNA_parameter_get(&list, parm, &ret1);
+               filter_flags = (int *)ret1;
+       }
+
+       parm = RNA_function_find_parameter(NULL, func, "filter_neworder");
+       ret_len = RNA_parameter_dynamic_length_get(&list, parm);
+       if (ret_len != len && ret_len != 0) {
+               printf("%s: Error, py func returned %d items in %s, %d or none were expected.\n", __func__,
+                      RNA_parameter_dynamic_length_get(&list, parm), "filter_neworder", len);
+               /* Note: we cannot return here, we would let flt_data in inconsistent state... see T38356. */
+               filter_neworder = NULL;
+       }
+       else {
+               RNA_parameter_get(&list, parm, &ret2);
+               filter_neworder = (int *)ret2;
+       }
+
+       /* We have to do some final checks and transforms... */
+       {
+               int i, filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
+               if (filter_flags) {
+                       flt_data->items_filter_flags = MEM_mallocN(sizeof(int) * len, __func__);
+                       memcpy(flt_data->items_filter_flags, filter_flags, sizeof(int) * len);
+
+                       if (filter_neworder) {
+                               /* For sake of simplicity, py filtering is expected to filter all items, but we actually only want
+                                * reordering data for shown items!
+                                */
+                               int items_shown, shown_idx;
+                               int t_idx, t_ni, prev_ni;
+                               flt_data->items_shown = 0;
+                               for (i = 0, shown_idx = 0; i < len; i++) {
+                                       if ((filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude) {
+                                               filter_neworder[shown_idx++] = filter_neworder[i];
+                                       }
+                               }
+                               items_shown = flt_data->items_shown = shown_idx;
+                               flt_data->items_filter_neworder = MEM_mallocN(sizeof(int) * items_shown, __func__);
+                               /* And now, bring back new indices into the [0, items_shown[ range!
+                                * XXX This is O(N²)... :/
+                                */
+                               for (shown_idx = 0, prev_ni = -1; shown_idx < items_shown; shown_idx++) {
+                                       for (i = 0, t_ni = len, t_idx = -1; i < items_shown; i++) {
+                                               int ni = filter_neworder[i];
+                                               if (ni > prev_ni && ni < t_ni) {
+                                                       t_idx = i;
+                                                       t_ni = ni;
+                                               }
+                                       }
+                                       if (t_idx >= 0) {
+                                               prev_ni = t_ni;
+                                               flt_data->items_filter_neworder[t_idx] = shown_idx;
+                                       }
+                               }
+                       }
+                       else {
+                               /* we still have to set flt_data->items_shown... */
+                               flt_data->items_shown = 0;
+                               for (i = 0; i < len; i++) {
+                                       if ((filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude) {
+                                               flt_data->items_shown++;
+                                       }
+                               }
+                       }
+               }
+               else {
+                       flt_data->items_shown = len;
+
+                       if (filter_neworder) {
+                               flt_data->items_filter_neworder = MEM_mallocN(sizeof(int) * len, __func__);
+                               memcpy(flt_data->items_filter_neworder, filter_neworder, sizeof(int) * len);
+                       }
+               }
+       }
+
+       RNA_parameter_list_free(&list);
+}
+
+static void rna_UIList_unregister(Main *UNUSED(bmain), StructRNA *type)
+{
+       uiListType *ult = RNA_struct_blender_type_get(type);
+
+       if (!ult)
+               return;
+
+       RNA_struct_free_extension(type, &ult->ext);
+       RNA_struct_free(&BLENDER_RNA, type);
+
+       WM_uilisttype_freelink(ult);
+
+       /* update while blender is running */
+       WM_main_add_notifier(NC_WINDOW, NULL);
+}
+
+static StructRNA *rna_UIList_register(
+        Main *bmain, ReportList *reports, void *data, const char *identifier,
+        StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+{
+       uiListType *ult, dummyult = {NULL};
+       uiList dummyuilist = {NULL};
+       PointerRNA dummyul_ptr;
+       int have_function[3];
+       size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */
+
+       /* setup dummy menu & menu type to store static properties in */
+       dummyuilist.type = &dummyult;
+       RNA_pointer_create(NULL, &RNA_UIList, &dummyuilist, &dummyul_ptr);
+
+       /* validate the python class */
+       if (validate(&dummyul_ptr, data, have_function) != 0)
+               return NULL;
+
+       if (strlen(identifier) >= sizeof(dummyult.idname)) {
+               BKE_reportf(reports, RPT_ERROR, "Registering uilist class: '%s' is too long, maximum length is %d",
+                           identifier, (int)sizeof(dummyult.idname));
+               return NULL;
+       }
+
+       /* check if we have registered this uilist type before, and remove it */
+       ult = WM_uilisttype_find(dummyult.idname, true);
+       if (ult && ult->ext.srna) {
+               rna_UIList_unregister(bmain, ult->ext.srna);
+       }
+       if (!RNA_struct_available_or_report(reports, dummyult.idname)) {
+               return NULL;
+       }
+       if (!RNA_struct_bl_idname_ok_or_report(reports, dummyult.idname, "_UL_")) {
+               return NULL;
+       }
+
+       /* create a new menu type */
+       ult = MEM_callocN(sizeof(uiListType) + over_alloc, "python uilist");
+       memcpy(ult, &dummyult, sizeof(dummyult));
+
+       ult->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ult->idname, &RNA_UIList);
+       ult->ext.data = data;
+       ult->ext.call = call;
+       ult->ext.free = free;
+       RNA_struct_blender_type_set(ult->ext.srna, ult);
+
+       ult->draw_item = (have_function[0]) ? uilist_draw_item : NULL;
+       ult->draw_filter = (have_function[1]) ? uilist_draw_filter : NULL;
+       ult->filter_items = (have_function[2]) ? uilist_filter_items : NULL;
+
+       WM_uilisttype_add(ult);
+
+       /* update while blender is running */
+       WM_main_add_notifier(NC_WINDOW, NULL);
+
+       return ult->ext.srna;
+}
+
+static StructRNA *rna_UIList_refine(PointerRNA *ptr)
+{
+       uiList *ui_list = (uiList *)ptr->data;
+       return (ui_list->type && ui_list->type->ext.srna) ? ui_list->type->ext.srna : &RNA_UIList;
 }
 
 /* Header */
@@ -282,16 +565,17 @@ static void rna_Header_unregister(Main *UNUSED(bmain), StructRNA *type)
                return;
        
        RNA_struct_free_extension(type, &ht->ext);
+       RNA_struct_free(&BLENDER_RNA, type);
 
        BLI_freelinkN(&art->headertypes, ht);
-       RNA_struct_free(&BLENDER_RNA, type);
 
        /* update while blender is running */
-       WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
+       WM_main_add_notifier(NC_WINDOW, NULL);
 }
 
-static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
-                                      StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+static StructRNA *rna_Header_register(
+        Main *bmain, ReportList *reports, void *data, const char *identifier,
+        StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
 {
        ARegionType *art;
        HeaderType *ht, dummyht = {NULL};
@@ -308,7 +592,7 @@ static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *da
                return NULL;
 
        if (strlen(identifier) >= sizeof(dummyht.idname)) {
-               BKE_reportf(reports, RPT_ERROR, "registering header class: '%s' is too long, maximum length is %d",
+               BKE_reportf(reports, RPT_ERROR, "Registering header class: '%s' is too long, maximum length is %d",
                            identifier, (int)sizeof(dummyht.idname));
                return NULL;
        }
@@ -318,37 +602,43 @@ static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *da
 
        /* check if we have registered this header type before, and remove it */
        for (ht = art->headertypes.first; ht; ht = ht->next) {
-               if (strcmp(ht->idname, dummyht.idname) == 0) {
+               if (STREQ(ht->idname, dummyht.idname)) {
                        if (ht->ext.srna)
                                rna_Header_unregister(bmain, ht->ext.srna);
                        break;
                }
        }
+       if (!RNA_struct_available_or_report(reports, dummyht.idname)) {
+               return NULL;
+       }
+       if (!RNA_struct_bl_idname_ok_or_report(reports, dummyht.idname, "_HT_")) {
+               return NULL;
+       }
        
        /* create a new header type */
        ht = MEM_callocN(sizeof(HeaderType), "python buttons header");
        memcpy(ht, &dummyht, sizeof(dummyht));
 
-       ht->ext.srna = RNA_def_struct(&BLENDER_RNA, ht->idname, "Header");
+       ht->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ht->idname, &RNA_Header);
        ht->ext.data = data;
        ht->ext.call = call;
        ht->ext.free = free;
        RNA_struct_blender_type_set(ht->ext.srna, ht);
 
-       ht->draw = (have_function[0])? header_draw: NULL;
+       ht->draw = (have_function[0]) ? header_draw : NULL;
 
        BLI_addtail(&art->headertypes, ht);
 
        /* update while blender is running */
-       WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
+       WM_main_add_notifier(NC_WINDOW, NULL);
        
        return ht->ext.srna;
 }
 
-static StructRNArna_Header_refine(PointerRNA *htr)
+static StructRNA *rna_Header_refine(PointerRNA *htr)
 {
-       Header *hdr = (Header*)htr->data;
-       return (hdr->type && hdr->type->ext.srna)? hdr->type->ext.srna: &RNA_Header;
+       Header *hdr = (Header *)htr->data;
+       return (hdr->type && hdr->type->ext.srna) ? hdr->type->ext.srna : &RNA_Header;
 }
 
 /* Menu */
@@ -371,7 +661,7 @@ static int menu_poll(const bContext *C, MenuType *pt)
        pt->ext.call((bContext *)C, &ptr, func, &list);
 
        RNA_parameter_get_lookup(&list, "visible", &ret);
-       visible = *(int*)ret;
+       visible = *(int *)ret;
 
        RNA_parameter_list_free(&list);
 
@@ -404,18 +694,17 @@ static void rna_Menu_unregister(Main *UNUSED(bmain), StructRNA *type)
                return;
        
        RNA_struct_free_extension(type, &mt->ext);
+       RNA_struct_free(&BLENDER_RNA, type);
 
        WM_menutype_freelink(mt);
 
-       RNA_struct_free(&BLENDER_RNA, type);
-
        /* update while blender is running */
-       WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
+       WM_main_add_notifier(NC_WINDOW, NULL);
 }
 
-static char _menu_descr[RNA_DYN_DESCR_MAX];
-static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
-                                    StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+static StructRNA *rna_Menu_register(
+        Main *bmain, ReportList *reports, void *data, const char *identifier,
+        StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
 {
        MenuType *mt, dummymt = {NULL};
        Menu dummymenu = {NULL};
@@ -423,29 +712,38 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data
        int have_function[2];
        size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */
        size_t description_size = 0;
+       char _menu_descr[RNA_DYN_DESCR_MAX];
 
        /* setup dummy menu & menu type to store static properties in */
        dummymenu.type = &dummymt;
+       _menu_descr[0] = '\0';
        dummymenu.type->description = _menu_descr;
        RNA_pointer_create(NULL, &RNA_Menu, &dummymenu, &dummymtr);
 
-       /* clear in case they are left unset */
-       _menu_descr[0] = '\0';
+       /* We have to set default context! Else we get a void string... */
+       strcpy(dummymt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
 
        /* validate the python class */
        if (validate(&dummymtr, data, have_function) != 0)
                return NULL;
        
        if (strlen(identifier) >= sizeof(dummymt.idname)) {
-               BKE_reportf(reports, RPT_ERROR, "registering menu class: '%s' is too long, maximum length is %d",
+               BKE_reportf(reports, RPT_ERROR, "Registering menu class: '%s' is too long, maximum length is %d",
                            identifier, (int)sizeof(dummymt.idname));
                return NULL;
        }
 
        /* check if we have registered this menu type before, and remove it */
-       mt = WM_menutype_find(dummymt.idname, TRUE);
-       if (mt && mt->ext.srna)
+       mt = WM_menutype_find(dummymt.idname, true);
+       if (mt && mt->ext.srna) {
                rna_Menu_unregister(bmain, mt->ext.srna);
+       }
+       if (!RNA_struct_available_or_report(reports, dummymt.idname)) {
+               return NULL;
+       }
+       if (!RNA_struct_bl_idname_ok_or_report(reports, dummymt.idname, "_MT_")) {
+               return NULL;
+       }
        
        /* create a new menu type */
        if (_menu_descr[0]) {
@@ -461,39 +759,44 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data
                memcpy(buf, _menu_descr, description_size);
                mt->description = buf;
        }
+       else
+               mt->description = "";
 
-       mt->ext.srna = RNA_def_struct(&BLENDER_RNA, mt->idname, "Menu");
+       mt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, mt->idname, &RNA_Menu);
+       RNA_def_struct_translation_context(mt->ext.srna, mt->translation_context);
        mt->ext.data = data;
        mt->ext.call = call;
        mt->ext.free = free;
        RNA_struct_blender_type_set(mt->ext.srna, mt);
        RNA_def_struct_flag(mt->ext.srna, STRUCT_NO_IDPROPERTIES);
 
-       mt->poll = (have_function[0])? menu_poll: NULL;
-       mt->draw = (have_function[1])? menu_draw: NULL;
+       mt->poll = (have_function[0]) ? menu_poll : NULL;
+       mt->draw = (have_function[1]) ? menu_draw : NULL;
 
        WM_menutype_add(mt);
 
        /* update while blender is running */
-       WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);
+       WM_main_add_notifier(NC_WINDOW, NULL);
        
        return mt->ext.srna;
 }
 
-static StructRNArna_Menu_refine(PointerRNA *mtr)
+static StructRNA *rna_Menu_refine(PointerRNA *mtr)
 {
-       Menu *hdr = (Menu*)mtr->data;
-       return (hdr->type && hdr->type->ext.srna)? hdr->type->ext.srna: &RNA_Menu;
+       Menu *hdr = (Menu *)mtr->data;
+       return (hdr->type && hdr->type->ext.srna) ? hdr->type->ext.srna : &RNA_Menu;
 }
 
 static void rna_Menu_bl_description_set(PointerRNA *ptr, const char *value)
 {
-       Menu *data = (Menu*)(ptr->data);
+       Menu *data = (Menu *)(ptr->data);
        char *str = (char *)data->type->description;
-       if (!str[0])    BLI_strncpy(str, value, RNA_DYN_DESCR_MAX);  /* utf8 already ensured */
-       else            assert(!"setting the bl_description on a non-builtin menu");
+       if (!str[0]) BLI_strncpy(str, value, RNA_DYN_DESCR_MAX);     /* utf8 already ensured */
+       else assert(!"setting the bl_description on a non-builtin menu");
 }
 
+/* UILayout */
+
 static int rna_UILayout_active_get(PointerRNA *ptr)
 {
        return uiLayoutGetActive(ptr->data);
@@ -598,7 +901,8 @@ static void rna_def_ui_layout(BlenderRNA *brna)
                {UI_LAYOUT_ALIGN_LEFT, "LEFT", 0, "Left", ""},
                {UI_LAYOUT_ALIGN_CENTER, "CENTER", 0, "Center", ""},
                {UI_LAYOUT_ALIGN_RIGHT, "RIGHT", 0, "Right", ""},
-               {0, NULL, 0, NULL, NULL}};
+               {0, NULL, 0, NULL, NULL}
+       };
        
        /* layout */
 
@@ -610,12 +914,12 @@ static void rna_def_ui_layout(BlenderRNA *brna)
        RNA_def_property_boolean_funcs(prop, "rna_UILayout_active_get", "rna_UILayout_active_set");
        
        prop = RNA_def_property(srna, "operator_context", PROP_ENUM, PROP_NONE);
-       RNA_def_property_enum_items(prop, operator_context_items);
+       RNA_def_property_enum_items(prop, rna_enum_operator_context_items);
        RNA_def_property_enum_funcs(prop, "rna_UILayout_op_context_get", "rna_UILayout_op_context_set", NULL);
        
        prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_funcs(prop, "rna_UILayout_enabled_get", "rna_UILayout_enabled_set");
-       RNA_def_property_ui_text(prop, "Enabled", "When false, this (sub)layout is greyed out");
+       RNA_def_property_ui_text(prop, "Enabled", "When false, this (sub)layout is grayed out");
        
        prop = RNA_def_property(srna, "alert", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_funcs(prop, "rna_UILayout_alert_get", "rna_UILayout_alert_set");
@@ -647,39 +951,42 @@ static void rna_def_panel(BlenderRNA *brna)
        FunctionRNA *func;
        
        static EnumPropertyItem panel_flag_items[] = {
-                       {PNL_DEFAULT_CLOSED, "DEFAULT_CLOSED", 0, "Default Closed",
-                                            "Defines if the panel has to be open or collapsed at the time of its creation"},
-                       {PNL_NO_HEADER, "HIDE_HEADER", 0, "Show Header",
-                                       "If set to True, the panel shows a header, which contains a clickable "
-                                       "arrow to collapse the panel and the label (see bl_label)"},
-                       {0, NULL, 0, NULL, NULL}};
+               {PNL_DEFAULT_CLOSED, "DEFAULT_CLOSED", 0, "Default Closed",
+                                    "Defines if the panel has to be open or collapsed at the time of its creation"},
+               {PNL_NO_HEADER, "HIDE_HEADER", 0, "Hide Header",
+                               "If set to False, the panel shows a header, which contains a clickable "
+                               "arrow to collapse the panel and the label (see bl_label)"},
+               {0, NULL, 0, NULL, NULL}
+       };
        
        srna = RNA_def_struct(brna, "Panel", NULL);
        RNA_def_struct_ui_text(srna, "Panel", "Panel containing UI elements");
        RNA_def_struct_sdna(srna, "Panel");
        RNA_def_struct_refine_func(srna, "rna_Panel_refine");
        RNA_def_struct_register_funcs(srna, "rna_Panel_register", "rna_Panel_unregister", NULL);
+       RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+       RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT);
 
        /* poll */
        func = RNA_def_function(srna, "poll", NULL);
        RNA_def_function_ui_description(func, "If this method returns a non-null output, then the panel can be drawn");
-       RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_REGISTER_OPTIONAL);
+       RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL);
        RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", ""));
        parm = RNA_def_pointer(func, "context", "Context", "", "");
-       RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
+       RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
 
        /* draw */
        func = RNA_def_function(srna, "draw", NULL);
        RNA_def_function_ui_description(func, "Draw UI elements into the panel UI layout");
        RNA_def_function_flag(func, FUNC_REGISTER);
        parm = RNA_def_pointer(func, "context", "Context", "", "");
-       RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
+       RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
 
        func = RNA_def_function(srna, "draw_header", NULL);
        RNA_def_function_ui_description(func, "Draw UI elements into the panel's header UI layout");
-       RNA_def_function_flag(func, FUNC_REGISTER);
+       RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
        parm = RNA_def_pointer(func, "context", "Context", "", "");
-       RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
+       RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
 
        prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
        RNA_def_property_struct_type(prop, "UILayout");
@@ -692,38 +999,45 @@ static void rna_def_panel(BlenderRNA *brna)
        /* registration */
        prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
        RNA_def_property_string_sdna(prop, NULL, "type->idname");
-       RNA_def_property_flag(prop, PROP_REGISTER|PROP_NEVER_CLAMP);
+       RNA_def_property_flag(prop, PROP_REGISTER);
        RNA_def_property_ui_text(prop, "ID Name",
                                 "If this is set, the panel gets a custom ID, otherwise it takes the "
                                 "name of the class used to define the panel. For example, if the "
                                 "class name is \"OBJECT_PT_hello\", and bl_idname is not set by the "
                                 "script, then bl_idname = \"OBJECT_PT_hello\"");
 
-       /* panel's label indeed doesn't need PROP_TRANSLATE flag: translation of label happens in runtime
-        * when drawing panel and having this flag set will make runtime switching of language much more tricky
-        * because label will be stored translated */
        prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
        RNA_def_property_string_sdna(prop, NULL, "type->label");
        RNA_def_property_flag(prop, PROP_REGISTER);
        RNA_def_property_ui_text(prop, "Label",
                                 "The panel label, shows up in the panel header at the right of the "
                                 "triangle used to collapse the panel");
-       
+
+       prop = RNA_def_property(srna, "bl_translation_context", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_sdna(prop, NULL, "type->translation_context");
+       RNA_def_property_string_default(prop, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+       RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+       RNA_define_verify_sdna(true);
+
+       prop = RNA_def_property(srna, "bl_category", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_sdna(prop, NULL, "type->category");
+       RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
        prop = RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "type->space_type");
-       RNA_def_property_enum_items(prop, space_type_items);
+       RNA_def_property_enum_items(prop, rna_enum_space_type_items);
        RNA_def_property_flag(prop, PROP_REGISTER);
        RNA_def_property_ui_text(prop, "Space type", "The space where the panel is going to be used in");
        
        prop = RNA_def_property(srna, "bl_region_type", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "type->region_type");
-       RNA_def_property_enum_items(prop, region_type_items);
+       RNA_def_property_enum_items(prop, rna_enum_region_type_items);
        RNA_def_property_flag(prop, PROP_REGISTER);
        RNA_def_property_ui_text(prop, "Region Type", "The region where the panel is going to be used in");
 
        prop = RNA_def_property(srna, "bl_context", PROP_STRING, PROP_NONE);
        RNA_def_property_string_sdna(prop, NULL, "type->context");
-       RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); /* should this be optional? - Campbell */
+       RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); /* Only used in Properties Editor and 3D View - Thomas */
        RNA_def_property_ui_text(prop, "Context",
                                 "The context in which the panel belongs to. (TODO: explain the "
                                 "possible combinations bl_context/bl_region_type/bl_space_type)");
@@ -731,8 +1045,137 @@ static void rna_def_panel(BlenderRNA *brna)
        prop = RNA_def_property(srna, "bl_options", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "type->flag");
        RNA_def_property_enum_items(prop, panel_flag_items);
-       RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL|PROP_ENUM_FLAG);
+       RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG);
        RNA_def_property_ui_text(prop, "Options",  "Options for this panel type");
+
+       prop = RNA_def_property(srna, "use_pin", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", PNL_PIN);
+       RNA_def_property_ui_text(prop, "Pin",  "");
+       /* XXX, should only tag region for redraw */
+       RNA_def_property_update(prop, NC_WINDOW, NULL);
+}
+
+static void rna_def_uilist(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+       PropertyRNA *parm;
+       FunctionRNA *func;
+
+       srna = RNA_def_struct(brna, "UIList", NULL);
+       RNA_def_struct_ui_text(srna, "UIList", "UI list containing the elements of a collection");
+       RNA_def_struct_sdna(srna, "uiList");
+       RNA_def_struct_refine_func(srna, "rna_UIList_refine");
+       RNA_def_struct_register_funcs(srna, "rna_UIList_register", "rna_UIList_unregister", NULL);
+       RNA_def_struct_idprops_func(srna, "rna_UIList_idprops");
+       RNA_def_struct_flag(srna, STRUCT_NO_DATABLOCK_IDPROPERTIES | STRUCT_PUBLIC_NAMESPACE_INHERIT);
+
+       /* Registration */
+       prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_sdna(prop, NULL, "type->idname");
+       RNA_def_property_flag(prop, PROP_REGISTER);
+       RNA_def_property_ui_text(prop, "ID Name",
+                                "If this is set, the uilist gets a custom ID, otherwise it takes the "
+                                "name of the class used to define the uilist (for example, if the "
+                                "class name is \"OBJECT_UL_vgroups\", and bl_idname is not set by the "
+                                "script, then bl_idname = \"OBJECT_UL_vgroups\")");
+
+       /* Data */
+       prop = RNA_def_property(srna, "layout_type", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_items(prop, rna_enum_uilist_layout_type_items);
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+       /* Filter options */
+       prop = RNA_def_property(srna, "use_filter_show", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "filter_flag", UILST_FLT_SHOW);
+       RNA_def_property_ui_text(prop, "Show Filter", "Show filtering options");
+
+       prop = RNA_def_property(srna, "filter_name", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_sdna(prop, NULL, "filter_byname");
+       RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
+       RNA_def_property_ui_text(prop, "Filter by Name", "Only show items matching this name (use '*' as wildcard)");
+
+       prop = RNA_def_property(srna, "use_filter_invert", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "filter_flag", UILST_FLT_EXCLUDE);
+       RNA_def_property_ui_text(prop, "Invert", "Invert filtering (show hidden items, and vice-versa)");
+
+       prop = RNA_def_property(srna, "use_filter_sort_alpha", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "filter_sort_flag", UILST_FLT_SORT_ALPHA);
+       RNA_def_property_ui_icon(prop, ICON_SORTALPHA, 0);
+       RNA_def_property_ui_text(prop, "Sort by Name", "Sort items by their name");
+
+       prop = RNA_def_property(srna, "use_filter_sort_reverse", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "filter_sort_flag", UILST_FLT_SORT_REVERSE);
+       RNA_def_property_ui_text(prop, "Invert", "Invert the order of shown items");
+
+       /* draw_item */
+       func = RNA_def_function(srna, "draw_item", NULL);
+       RNA_def_function_ui_description(func, "Draw an item in the list (NOTE: when you define your own draw_item "
+                                             "function, you may want to check given 'item' is of the right type...)");
+       RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
+       parm = RNA_def_pointer(func, "context", "Context", "", "");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       parm = RNA_def_pointer(func, "layout", "UILayout", "", "Layout to draw the item");
+       RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+       parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take Collection property");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
+       parm = RNA_def_pointer(func, "item", "AnyType", "", "Item of the collection property");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
+       parm = RNA_def_int(func, "icon", 0, 0, INT_MAX, "", "Icon of the item in the collection", 0, INT_MAX);
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       parm = RNA_def_pointer(func, "active_data", "AnyType", "",
+                              "Data from which to take property for the active element");
+       RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
+       parm = RNA_def_string(func, "active_property", NULL, 0, "",
+                             "Identifier of property in active_data, for the active element");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       RNA_def_int(func, "index", 0, 0, INT_MAX, "", "Index of the item in the collection", 0, INT_MAX);
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_PYFUNC_OPTIONAL);
+       prop = RNA_def_property(func, "flt_flag", PROP_INT, PROP_UNSIGNED);
+       RNA_def_property_ui_text(prop, "", "The filter-flag result for this item");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_PYFUNC_OPTIONAL);
+
+       /* draw_filter */
+       func = RNA_def_function(srna, "draw_filter", NULL);
+       RNA_def_function_ui_description(func, "Draw filtering options");
+       RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
+       parm = RNA_def_pointer(func, "context", "Context", "", "");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       parm = RNA_def_pointer(func, "layout", "UILayout", "", "Layout to draw the item");
+       RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+
+       /* filter */
+       func = RNA_def_function(srna, "filter_items", NULL);
+       RNA_def_function_ui_description(func, "Filter and/or re-order items of the collection (output filter results in "
+                                             "filter_flags, and reorder results in filter_neworder arrays)");
+       RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
+       parm = RNA_def_pointer(func, "context", "Context", "", "");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take Collection property");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
+       parm = RNA_def_string(func, "property", NULL, 0, "", "Identifier of property in data, for the collection");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       prop = RNA_def_property(func, "filter_flags", PROP_INT, PROP_UNSIGNED);
+       RNA_def_property_flag(prop, PARM_REQUIRED | PROP_DYNAMIC);
+       RNA_def_property_array(prop, 1);  /* XXX Dummy value, default 0 does not work */
+       RNA_def_property_ui_text(prop, "", "An array of filter flags, one for each item in the collection (NOTE: "
+                                          "FILTER_ITEM bit is reserved, it defines whether the item is shown or not)");
+       RNA_def_function_output(func, prop);
+       prop = RNA_def_property(func, "filter_neworder", PROP_INT, PROP_UNSIGNED);
+       RNA_def_property_flag(prop, PARM_REQUIRED | PROP_DYNAMIC);
+       RNA_def_property_array(prop, 1);  /* XXX Dummy value, default 0 does not work */
+       RNA_def_property_ui_text(prop, "", "An array of indices, one for each item in the collection, mapping the org "
+                                          "index to the new one");
+       RNA_def_function_output(func, prop);
+
+       /* "Constants"! */
+       RNA_define_verify_sdna(0); /* not in sdna */
+
+       prop = RNA_def_property(srna, "bitflag_filter_item", PROP_INT, PROP_UNSIGNED);
+       RNA_def_property_ui_text(prop, "FILTER_ITEM",
+                                      "The value of the reserved bitflag 'FILTER_ITEM' (in filter_flags values)");
+       RNA_def_property_int_funcs(prop, "rna_UIList_filter_const_FILTER_ITEM_get", NULL, NULL);
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 }
 
 static void rna_def_header(BlenderRNA *brna)
@@ -747,13 +1190,14 @@ static void rna_def_header(BlenderRNA *brna)
        RNA_def_struct_sdna(srna, "Header");
        RNA_def_struct_refine_func(srna, "rna_Header_refine");
        RNA_def_struct_register_funcs(srna, "rna_Header_register", "rna_Header_unregister", NULL);
+       RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT);
 
        /* draw */
        func = RNA_def_function(srna, "draw", NULL);
        RNA_def_function_ui_description(func, "Draw UI elements into the header UI layout");
        RNA_def_function_flag(func, FUNC_REGISTER);
        parm = RNA_def_pointer(func, "context", "Context", "", "");
-       RNA_def_property_flag(parm, PROP_REQUIRED);
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
 
        RNA_define_verify_sdna(0); /* not in sdna */
 
@@ -765,7 +1209,7 @@ static void rna_def_header(BlenderRNA *brna)
        /* registration */
        prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
        RNA_def_property_string_sdna(prop, NULL, "type->idname");
-       RNA_def_property_flag(prop, PROP_REGISTER|PROP_NEVER_CLAMP);
+       RNA_def_property_flag(prop, PROP_REGISTER);
        RNA_def_property_ui_text(prop, "ID Name",
                                 "If this is set, the header gets a custom ID, otherwise it takes the "
                                 "name of the class used to define the panel; for example, if the "
@@ -774,7 +1218,7 @@ static void rna_def_header(BlenderRNA *brna)
 
        prop = RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "type->space_type");
-       RNA_def_property_enum_items(prop, space_type_items);
+       RNA_def_property_enum_items(prop, rna_enum_space_type_items);
        RNA_def_property_flag(prop, PROP_REGISTER);
        RNA_def_property_ui_text(prop, "Space type", "The space where the header is going to be used in");
 
@@ -793,23 +1237,25 @@ static void rna_def_menu(BlenderRNA *brna)
        RNA_def_struct_sdna(srna, "Menu");
        RNA_def_struct_refine_func(srna, "rna_Menu_refine");
        RNA_def_struct_register_funcs(srna, "rna_Menu_register", "rna_Menu_unregister", NULL);
+       RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+       RNA_def_struct_flag(srna, STRUCT_PUBLIC_NAMESPACE_INHERIT);
 
        /* poll */
        func = RNA_def_function(srna, "poll", NULL);
        RNA_def_function_ui_description(func, "If this method returns a non-null output, then the menu can be drawn");
-       RNA_def_function_flag(func, FUNC_NO_SELF|FUNC_REGISTER_OPTIONAL);
+       RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL);
        RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", ""));
        parm = RNA_def_pointer(func, "context", "Context", "", "");
-       RNA_def_property_flag(parm, PROP_REQUIRED);
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
 
        /* draw */
        func = RNA_def_function(srna, "draw", NULL);
        RNA_def_function_ui_description(func, "Draw UI elements into the menu UI layout");
        RNA_def_function_flag(func, FUNC_REGISTER);
        parm = RNA_def_pointer(func, "context", "Context", "", "");
-       RNA_def_property_flag(parm, PROP_REQUIRED);
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
 
-       RNA_define_verify_sdna(0); /* not in sdna */
+       RNA_define_verify_sdna(false); /* not in sdna */
 
        prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
        RNA_def_property_pointer_sdna(prop, NULL, "layout");
@@ -819,22 +1265,24 @@ static void rna_def_menu(BlenderRNA *brna)
        /* registration */
        prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
        RNA_def_property_string_sdna(prop, NULL, "type->idname");
-       RNA_def_property_flag(prop, PROP_REGISTER|PROP_NEVER_CLAMP);
+       RNA_def_property_flag(prop, PROP_REGISTER);
        RNA_def_property_ui_text(prop, "ID Name",
                                 "If this is set, the menu gets a custom ID, otherwise it takes the "
                                 "name of the class used to define the menu (for example, if the "
                                 "class name is \"OBJECT_MT_hello\", and bl_idname is not set by the "
                                 "script, then bl_idname = \"OBJECT_MT_hello\")");
 
-       /* menu's label indeed doesn't need PROP_TRANSLATE flag: translation of label happens in runtime
-        * when drawing panel and having this flag set will make runtime switching of language much more tricky
-        * because label will be stored translated */
        prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
        RNA_def_property_string_sdna(prop, NULL, "type->label");
        RNA_def_property_flag(prop, PROP_REGISTER);
        RNA_def_property_ui_text(prop, "Label", "The menu label");
 
-       prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_TRANSLATE);
+       prop = RNA_def_property(srna, "bl_translation_context", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_sdna(prop, NULL, "type->translation_context");
+       RNA_def_property_string_default(prop, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+       RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
+       prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
        RNA_def_property_string_sdna(prop, NULL, "type->description");
        RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
        RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Menu_bl_description_set");
@@ -849,6 +1297,7 @@ void RNA_def_ui(BlenderRNA *brna)
 {
        rna_def_ui_layout(brna);
        rna_def_panel(brna);
+       rna_def_uilist(brna);
        rna_def_header(brna);
        rna_def_menu(brna);
 }