Cleanup/refactor RNA IDs' `remove` functions.
authorBastien Montagne <montagne29@wanadoo.fr>
Sat, 25 Jun 2016 15:01:36 +0000 (17:01 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Sat, 25 Jun 2016 15:10:33 +0000 (17:10 +0200)
Those (one per ID type!) were uselessly duplicated, and badly inconsistent
(some types were actually unlinking before deletion, others were only working if already unlinked!).

Now we use same func and same API for all types, by default deletion is performed only if ID is no more used,
set `do_unlink` parameter to True to always delete ID even if still in use.
Only exception now is with Scene, since we always want to keep at least one!

Note that this will change default behavior of some types (since unlinking is never done anymore by default).

intern/cycles/blender/blender_mesh.cpp
source/blender/makesrna/intern/rna_main_api.c

index 80db51148e613fa6ddd612e364bab85080d20082..4bd385c42001177ad84dffbab7043ed034b3fa39 100644 (file)
@@ -801,7 +801,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
                        }
 
                        /* free derived mesh */
-                       b_data.meshes.remove(b_mesh);
+                       b_data.meshes.remove(b_mesh, false);
                }
        }
        mesh->geometry_flags = requested_geometry_flags;
@@ -1013,7 +1013,7 @@ void BlenderSync::sync_mesh_motion(BL::Object& b_ob,
                sync_curves(mesh, b_mesh, b_ob, true, time_index);
 
        /* free derived mesh */
-       b_data.meshes.remove(b_mesh);
+       b_data.meshes.remove(b_mesh, false);
 }
 
 CCL_NAMESPACE_END
index 679f20fab838d2a6a6833ad9d060c04e66739355..c0a0bc0b55a1c8a800af0a9897235d0005a540f9 100644 (file)
@@ -62,6 +62,7 @@
 #include "BKE_object.h"
 #include "BKE_material.h"
 #include "BKE_icons.h"
+#include "BKE_idcode.h"
 #include "BKE_image.h"
 #include "BKE_texture.h"
 #include "BKE_scene.h"
 #  include "BPY_extern.h"
 #endif
 
+
+static void rna_Main_ID_remove(Main *bmain, ReportList *reports, PointerRNA *id_ptr, int do_unlink)
+{
+       ID *id = id_ptr->data;
+       if (do_unlink) {
+               BKE_libblock_delete(bmain, id);
+               RNA_POINTER_INVALIDATE(id_ptr);
+       }
+       else if (ID_REAL_USERS(id) <= 0) {
+               BKE_libblock_free(bmain, id);
+               RNA_POINTER_INVALIDATE(id_ptr);
+       }
+       else {
+               BKE_reportf(reports, RPT_ERROR,
+                           "%s '%s' must have zero users to be removed, found %d (try with unlink=True parameter)",
+                           BKE_idcode_to_name(GS(id->name)), id->name + 2, ID_REAL_USERS(id));
+       }
+}
+
+
 static Camera *rna_Main_cameras_new(Main *bmain, const char *name)
 {
        ID *id = BKE_camera_add(bmain, name);
        id_us_min(id);
        return (Camera *)id;
 }
-static void rna_Main_cameras_remove(Main *bmain, ReportList *reports, PointerRNA *camera_ptr)
-{
-       Camera *camera = camera_ptr->data;
-       if (ID_REAL_USERS(camera) <= 0) {
-               BKE_libblock_free(bmain, camera);
-               RNA_POINTER_INVALIDATE(camera_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Camera '%s' must have zero users to be removed, found %d",
-                           camera->id.name + 2, ID_REAL_USERS(camera));
-       }
-}
 
 static Scene *rna_Main_scenes_new(Main *bmain, const char *name)
 {
        return BKE_scene_add(bmain, name);
 }
-static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports, PointerRNA *scene_ptr)
+static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports, PointerRNA *scene_ptr, int do_unlink)
 {
        /* don't call BKE_libblock_free(...) directly */
        Scene *scene = scene_ptr->data;
@@ -146,24 +155,23 @@ static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports
        if ((scene_new = scene->id.prev) ||
            (scene_new = scene->id.next))
        {
-               bScreen *sc = CTX_wm_screen(C);
-               if (sc->scene == scene) {
+               if (do_unlink) {
+                       bScreen *sc = CTX_wm_screen(C);
+                       if (sc->scene == scene) {
 
 #ifdef WITH_PYTHON
-                       BPy_BEGIN_ALLOW_THREADS;
+                               BPy_BEGIN_ALLOW_THREADS;
 #endif
 
-                       ED_screen_set_scene(C, sc, scene_new);
+                               ED_screen_set_scene(C, sc, scene_new);
 
 #ifdef WITH_PYTHON
-                       BPy_END_ALLOW_THREADS;
+                               BPy_END_ALLOW_THREADS;
 #endif
 
+                       }
                }
-
-               BKE_libblock_remap(bmain, scene, scene_new, ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_NEVER_NULL_USAGE);
-               BKE_libblock_free(bmain, scene);
-               RNA_POINTER_INVALIDATE(scene_ptr);
+               rna_Main_ID_remove(bmain, reports, scene_ptr, do_unlink);
        }
        else {
                BKE_reportf(reports, RPT_ERROR, "Scene '%s' is the last, cannot be removed", scene->id.name + 2);
@@ -224,38 +232,12 @@ static Object *rna_Main_objects_new(Main *bmain, ReportList *reports, const char
        return ob;
 }
 
-static void rna_Main_objects_remove(Main *bmain, ReportList *reports, PointerRNA *object_ptr)
-{
-       Object *object = object_ptr->data;
-       if (ID_REAL_USERS(object) <= 0) {
-               BKE_libblock_unlink(bmain, object, false);
-               BKE_libblock_free(bmain, object);
-               RNA_POINTER_INVALIDATE(object_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Object '%s' must have zero users to be removed, found %d",
-                           object->id.name + 2, ID_REAL_USERS(object));
-       }
-}
-
 static Material *rna_Main_materials_new(Main *bmain, const char *name)
 {
        ID *id = (ID *)BKE_material_add(bmain, name);
        id_us_min(id);
        return (Material *)id;
 }
-static void rna_Main_materials_remove(Main *bmain, ReportList *reports, PointerRNA *material_ptr)
-{
-       Material *material = material_ptr->data;
-       if (ID_REAL_USERS(material) <= 0) {
-               BKE_libblock_free(bmain, material);
-               RNA_POINTER_INVALIDATE(material_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Material '%s' must have zero users to be removed, found %d",
-                           material->id.name + 2, ID_REAL_USERS(material));
-       }
-}
 
 static EnumPropertyItem *rna_Main_nodetree_type_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
 {
@@ -273,18 +255,6 @@ static struct bNodeTree *rna_Main_nodetree_new(Main *bmain, const char *name, in
        else
                return NULL;
 }
-static void rna_Main_nodetree_remove(Main *bmain, ReportList *reports, PointerRNA *ntree_ptr)
-{
-       bNodeTree *ntree = ntree_ptr->data;
-       if (ID_REAL_USERS(ntree) <= 0) {
-               BKE_libblock_free(bmain, ntree);
-               RNA_POINTER_INVALIDATE(ntree_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Node tree '%s' must have zero users to be removed, found %d",
-                           ntree->id.name + 2, ID_REAL_USERS(ntree));
-       }
-}
 
 static Mesh *rna_Main_meshes_new(Main *bmain, const char *name)
 {
@@ -314,19 +284,6 @@ Mesh *rna_Main_meshes_new_from_object(
        return BKE_mesh_new_from_object(bmain, sce, ob, apply_modifiers, settings, calc_tessface, calc_undeformed);
 }
 
-static void rna_Main_meshes_remove(Main *bmain, ReportList *reports, PointerRNA *mesh_ptr)
-{
-       Mesh *mesh = mesh_ptr->data;
-       if (ID_REAL_USERS(mesh) <= 0) {
-               BKE_libblock_free(bmain, mesh);
-               RNA_POINTER_INVALIDATE(mesh_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Mesh '%s' must have zero users to be removed, found %d",
-                           mesh->id.name + 2, ID_REAL_USERS(mesh));
-       }
-}
-
 static Lamp *rna_Main_lamps_new(Main *bmain, const char *name, int type)
 {
        Lamp *lamp = BKE_lamp_add(bmain, name);
@@ -334,18 +291,6 @@ static Lamp *rna_Main_lamps_new(Main *bmain, const char *name, int type)
        id_us_min(&lamp->id);
        return lamp;
 }
-static void rna_Main_lamps_remove(Main *bmain, ReportList *reports, PointerRNA *lamp_ptr)
-{
-       Lamp *lamp = lamp_ptr->data;
-       if (ID_REAL_USERS(lamp) <= 0) {
-               BKE_libblock_free(bmain, lamp);
-               RNA_POINTER_INVALIDATE(lamp_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Lamp '%s' must have zero users to be removed, found %d",
-                           lamp->id.name + 2, ID_REAL_USERS(lamp));
-       }
-}
 
 static Image *rna_Main_images_new(Main *bmain, const char *name, int width, int height, int alpha, int float_buffer, int stereo3d)
 {
@@ -374,18 +319,6 @@ static Image *rna_Main_images_load(Main *bmain, ReportList *reports, const char
        id_us_min((ID *)ima);
        return ima;
 }
-static void rna_Main_images_remove(Main *bmain, ReportList *reports, PointerRNA *image_ptr)
-{
-       Image *image = image_ptr->data;
-       if (ID_REAL_USERS(image) <= 0) {
-               BKE_libblock_free(bmain, image);
-               RNA_POINTER_INVALIDATE(image_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Image '%s' must have zero users to be removed, found %d",
-                           image->id.name + 2, ID_REAL_USERS(image));
-       }
-}
 
 static Lattice *rna_Main_lattices_new(Main *bmain, const char *name)
 {
@@ -393,18 +326,6 @@ static Lattice *rna_Main_lattices_new(Main *bmain, const char *name)
        id_us_min(&lt->id);
        return lt;
 }
-static void rna_Main_lattices_remove(Main *bmain, ReportList *reports, PointerRNA *lt_ptr)
-{
-       Lattice *lt = lt_ptr->data;
-       if (ID_REAL_USERS(lt) <= 0) {
-               BKE_libblock_free(bmain, lt);
-               RNA_POINTER_INVALIDATE(lt_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Lattice '%s' must have zero users to be removed, found %d",
-                           lt->id.name + 2, ID_REAL_USERS(lt));
-       }
-}
 
 static Curve *rna_Main_curves_new(Main *bmain, const char *name, int type)
 {
@@ -412,18 +333,6 @@ static Curve *rna_Main_curves_new(Main *bmain, const char *name, int type)
        id_us_min(&cu->id);
        return cu;
 }
-static void rna_Main_curves_remove(Main *bmain, ReportList *reports, PointerRNA *cu_ptr)
-{
-       Curve *cu = cu_ptr->data;
-       if (ID_REAL_USERS(cu) <= 0) {
-               BKE_libblock_free(bmain, cu);
-               RNA_POINTER_INVALIDATE(cu_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Curve '%s' must have zero users to be removed, found %d",
-                           cu->id.name + 2, ID_REAL_USERS(cu));
-       }
-}
 
 static MetaBall *rna_Main_metaballs_new(Main *bmain, const char *name)
 {
@@ -431,18 +340,6 @@ static MetaBall *rna_Main_metaballs_new(Main *bmain, const char *name)
        id_us_min(&mb->id);
        return mb;
 }
-static void rna_Main_metaballs_remove(Main *bmain, ReportList *reports, PointerRNA *mb_ptr)
-{
-       MetaBall *mb = mb_ptr->data;
-       if (ID_REAL_USERS(mb) <= 0) {
-               BKE_libblock_free(bmain, mb);
-               RNA_POINTER_INVALIDATE(mb_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Metaball '%s' must have zero users to be removed, found %d",
-                           mb->id.name + 2, ID_REAL_USERS(mb));
-       }
-}
 
 static VFont *rna_Main_fonts_load(Main *bmain, ReportList *reports, const char *filepath, int check_existing)
 {
@@ -464,18 +361,6 @@ static VFont *rna_Main_fonts_load(Main *bmain, ReportList *reports, const char *
        return font;
 
 }
-static void rna_Main_fonts_remove(Main *bmain, ReportList *reports, PointerRNA *vfont_ptr)
-{
-       VFont *vfont = vfont_ptr->data;
-       if (ID_REAL_USERS(vfont) <= 0) {
-               BKE_libblock_free(bmain, vfont);
-               RNA_POINTER_INVALIDATE(vfont_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Font '%s' must have zero users to be removed, found %d",
-                           vfont->id.name + 2, ID_REAL_USERS(vfont));
-       }
-}
 
 static Tex *rna_Main_textures_new(Main *bmain, const char *name, int type)
 {
@@ -484,18 +369,6 @@ static Tex *rna_Main_textures_new(Main *bmain, const char *name, int type)
        id_us_min(&tex->id);
        return tex;
 }
-static void rna_Main_textures_remove(Main *bmain, ReportList *reports, PointerRNA *tex_ptr)
-{
-       Tex *tex = tex_ptr->data;
-       if (ID_REAL_USERS(tex) <= 0) {
-               BKE_libblock_free(bmain, tex);
-               RNA_POINTER_INVALIDATE(tex_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Texture '%s' must have zero users to be removed, found %d",
-                           tex->id.name + 2, ID_REAL_USERS(tex));
-       }
-}
 
 static Brush *rna_Main_brushes_new(Main *bmain, const char *name, int mode)
 {
@@ -504,50 +377,17 @@ static Brush *rna_Main_brushes_new(Main *bmain, const char *name, int mode)
        return brush;
 }
 
-static void rna_Main_brushes_remove(Main *bmain, ReportList *reports, PointerRNA *brush_ptr)
-{
-       Brush *brush = brush_ptr->data;
-       if (ID_REAL_USERS(brush) <= 0) {
-               BKE_brush_unlink(bmain, brush);
-               BKE_libblock_free(bmain, brush);
-               RNA_POINTER_INVALIDATE(brush_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Brush '%s' must have zero users to be removed, found %d",
-                           brush->id.name + 2, ID_REAL_USERS(brush));
-       }
-}
-
 static World *rna_Main_worlds_new(Main *bmain, const char *name)
 {
        World *world = add_world(bmain, name);
        id_us_min(&world->id);
        return world;
 }
-static void rna_Main_worlds_remove(Main *bmain, ReportList *reports, PointerRNA *world_ptr)
-{
-       Group *world = world_ptr->data;
-       if (ID_REAL_USERS(world) <= 0) {
-               BKE_libblock_free(bmain, world);
-               RNA_POINTER_INVALIDATE(world_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "World '%s' must have zero users to be removed, found %d",
-                           world->id.name + 2, ID_REAL_USERS(world));
-       }
-}
 
 static Group *rna_Main_groups_new(Main *bmain, const char *name)
 {
        return BKE_group_add(bmain, name);
 }
-static void rna_Main_groups_remove(Main *bmain, PointerRNA *group_ptr)
-{
-       Group *group = group_ptr->data;
-       BKE_libblock_unlink(bmain, group, false);
-       BKE_libblock_free(bmain, group);
-       RNA_POINTER_INVALIDATE(group_ptr);
-}
 
 static Speaker *rna_Main_speakers_new(Main *bmain, const char *name)
 {
@@ -555,18 +395,6 @@ static Speaker *rna_Main_speakers_new(Main *bmain, const char *name)
        id_us_min(&speaker->id);
        return speaker;
 }
-static void rna_Main_speakers_remove(Main *bmain, ReportList *reports, PointerRNA *speaker_ptr)
-{
-       Speaker *speaker = speaker_ptr->data;
-       if (ID_REAL_USERS(speaker) <= 0) {
-               BKE_libblock_free(bmain, speaker);
-               RNA_POINTER_INVALIDATE(speaker_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Speaker '%s' must have zero users to be removed, found %d",
-                           speaker->id.name + 2, ID_REAL_USERS(speaker));
-       }
-}
 
 static bSound *rna_Main_sounds_load(Main *bmain, const char *name, int check_existing)
 {
@@ -582,30 +410,11 @@ static bSound *rna_Main_sounds_load(Main *bmain, const char *name, int check_exi
        id_us_min(&sound->id);
        return sound;
 }
-static void rna_Main_sounds_remove(Main *bmain, ReportList *reports, PointerRNA *sound_ptr)
-{
-       Speaker *sound = sound_ptr->data;
-       if (ID_REAL_USERS(sound) <= 0) {
-               BKE_libblock_free(bmain, sound);
-               RNA_POINTER_INVALIDATE(sound_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Sound '%s' must have zero users to be removed, found %d",
-                           sound->id.name + 2, ID_REAL_USERS(sound));
-       }
-}
 
 static Text *rna_Main_texts_new(Main *bmain, const char *name)
 {
        return BKE_text_add(bmain, name);
 }
-static void rna_Main_texts_remove(Main *bmain, PointerRNA *text_ptr)
-{
-       Text *text = text_ptr->data;
-       BKE_text_unlink(bmain, text);
-       BKE_libblock_free(bmain, text);
-       RNA_POINTER_INVALIDATE(text_ptr);
-}
 
 static Text *rna_Main_texts_load(Main *bmain, ReportList *reports, const char *filepath, int is_internal)
 {
@@ -627,18 +436,6 @@ static bArmature *rna_Main_armatures_new(Main *bmain, const char *name)
        id_us_min(&arm->id);
        return arm;
 }
-static void rna_Main_armatures_remove(Main *bmain, ReportList *reports, PointerRNA *arm_ptr)
-{
-       bArmature *arm = arm_ptr->data;
-       if (ID_REAL_USERS(arm) <= 0) {
-               BKE_libblock_free(bmain, arm);
-               RNA_POINTER_INVALIDATE(arm_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Armature '%s' must have zero users to be removed, found %d",
-                           arm->id.name + 2, ID_REAL_USERS(arm));
-       }
-}
 
 static bAction *rna_Main_actions_new(Main *bmain, const char *name)
 {
@@ -646,18 +443,6 @@ static bAction *rna_Main_actions_new(Main *bmain, const char *name)
        id_fake_user_clear(&act->id);
        return act;
 }
-static void rna_Main_actions_remove(Main *bmain, ReportList *reports, PointerRNA *act_ptr)
-{
-       bAction *act = act_ptr->data;
-       if (ID_REAL_USERS(act) <= 0) {
-               BKE_libblock_free(bmain, act);
-               RNA_POINTER_INVALIDATE(act_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Action '%s' must have zero users to be removed, found %d",
-                           act->id.name + 2, ID_REAL_USERS(act));
-       }
-}
 
 static ParticleSettings *rna_Main_particles_new(Main *bmain, const char *name)
 {
@@ -665,18 +450,6 @@ static ParticleSettings *rna_Main_particles_new(Main *bmain, const char *name)
        id_us_min(&part->id);
        return part;
 }
-static void rna_Main_particles_remove(Main *bmain, ReportList *reports, PointerRNA *part_ptr)
-{
-       ParticleSettings *part = part_ptr->data;
-       if (ID_REAL_USERS(part) <= 0) {
-               BKE_libblock_free(bmain, part);
-               RNA_POINTER_INVALIDATE(part_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Particle settings '%s' must have zero users to be removed, found %d",
-                           part->id.name + 2, ID_REAL_USERS(part));
-       }
-}
 
 static Palette *rna_Main_palettes_new(Main *bmain, const char *name)
 {
@@ -684,18 +457,6 @@ static Palette *rna_Main_palettes_new(Main *bmain, const char *name)
        id_us_min(&palette->id);
        return (Palette *)palette;
 }
-static void rna_Main_palettes_remove(Main *bmain, ReportList *reports, PointerRNA *palette_ptr)
-{
-       Palette *palette = palette_ptr->data;
-       if (ID_REAL_USERS(palette) <= 0) {
-               BKE_libblock_free(bmain, palette);
-               RNA_POINTER_INVALIDATE(palette_ptr);
-       }
-       else {
-               BKE_reportf(reports, RPT_ERROR, "Palette settings '%s' must have zero users to be removed, found %d",
-                           palette->id.name + 2, ID_REAL_USERS(palette));
-       }
-}
 
 static MovieClip *rna_Main_movieclip_load(Main *bmain, ReportList *reports, const char *filepath, int check_existing)
 {
@@ -718,14 +479,6 @@ static MovieClip *rna_Main_movieclip_load(Main *bmain, ReportList *reports, cons
        return clip;
 }
 
-static void rna_Main_movieclips_remove(Main *bmain, PointerRNA *clip_ptr)
-{
-       MovieClip *clip = clip_ptr->data;
-       BKE_movieclip_unlink(bmain, clip);
-       BKE_libblock_free(bmain, clip);
-       RNA_POINTER_INVALIDATE(clip_ptr);
-}
-
 static Mask *rna_Main_mask_new(Main *bmain, const char *name)
 {
        Mask *mask;
@@ -735,26 +488,6 @@ static Mask *rna_Main_mask_new(Main *bmain, const char *name)
        return mask;
 }
 
-static void rna_Main_masks_remove(Main *bmain, PointerRNA *mask_ptr)
-{
-       Mask *mask = mask_ptr->data;
-       BKE_libblock_free(bmain, mask);
-       RNA_POINTER_INVALIDATE(mask_ptr);
-}
-
-static void rna_Main_grease_pencil_remove(Main *bmain, ReportList *reports, PointerRNA *gpd_ptr)
-{
-       bGPdata *gpd = gpd_ptr->data;
-       if (ID_REAL_USERS(gpd) <= 0) {
-               BKE_gpencil_free(gpd);
-               BKE_libblock_free(bmain, gpd);
-               RNA_POINTER_INVALIDATE(gpd_ptr);
-       }
-       else
-               BKE_reportf(reports, RPT_ERROR, "Grease pencil '%s' must have zero users to be removed, found %d",
-                           gpd->id.name + 2, ID_REAL_USERS(gpd));
-}
-
 static FreestyleLineStyle *rna_Main_linestyles_new(Main *bmain, const char *name)
 {
        FreestyleLineStyle *linestyle = BKE_linestyle_new(bmain, name);
@@ -762,17 +495,6 @@ static FreestyleLineStyle *rna_Main_linestyles_new(Main *bmain, const char *name
        return linestyle;
 }
 
-static void rna_Main_linestyles_remove(Main *bmain, ReportList *reports, FreestyleLineStyle *linestyle)
-{
-       if (ID_REAL_USERS(linestyle) <= 0)
-               BKE_libblock_free(bmain, linestyle);
-       else
-               BKE_reportf(reports, RPT_ERROR, "Line style '%s' must have zero users to be removed, found %d",
-                           linestyle->id.name + 2, ID_REAL_USERS(linestyle));
-
-       /* XXX python now has invalid pointer? */
-}
-
 /* tag and is_updated functions, all the same */
 #define RNA_MAIN_ID_TAG_FUNCS_DEF(_func_name, _listbase_name, _id_type)            \
        static void rna_Main_##_func_name##_tag(Main *bmain, int value) {              \
@@ -855,12 +577,15 @@ void RNA_def_main_cameras(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "camera", "Camera", "", "New camera data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_cameras_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a camera from the current blendfile");
        parm = RNA_def_pointer(func, "camera", "Camera", "", "Camera to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "",
+                       "Unlink all usages of this camera before deleting it "
+                       "(WARNING: will also delete objects instancing that camera data)");
 
        func = RNA_def_function(srna, "tag", "rna_Main_cameras_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -897,6 +622,7 @@ void RNA_def_main_scenes(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this scene before deleting it");
 
        func = RNA_def_function(srna, "tag", "rna_Main_scenes_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -931,12 +657,13 @@ void RNA_def_main_objects(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "object", "Object", "", "New object data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_objects_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_ui_description(func, "Remove a object from the current blendfile");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        parm = RNA_def_pointer(func, "object", "Object", "", "Object to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this object before deleting it");
 
        func = RNA_def_function(srna, "tag", "rna_Main_objects_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -967,12 +694,13 @@ void RNA_def_main_materials(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "material", "Material", "", "New material data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_materials_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a material from the current blendfile");
        parm = RNA_def_pointer(func, "material", "Material", "", "Material to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this material before deleting it");
 
        func = RNA_def_function(srna, "tag", "rna_Main_materials_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1010,12 +738,13 @@ void RNA_def_main_node_groups(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "tree", "NodeTree", "", "New node tree data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_nodetree_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a node tree from the current blendfile");
        parm = RNA_def_pointer(func, "tree", "NodeTree", "", "Node tree to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this node tree before deleting it");
 
        func = RNA_def_function(srna, "tag", "rna_Main_node_groups_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1068,12 +797,15 @@ void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop)
                               "Mesh created from object, remove it if it is only used for export");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_meshes_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a mesh from the current blendfile");
        parm = RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "",
+                       "Unlink all usages of this mesh before deleting it "
+                       "(WARNING: will also delete objects instancing that mesh data)");
 
        func = RNA_def_function(srna, "tag", "rna_Main_meshes_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1105,12 +837,15 @@ void RNA_def_main_lamps(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "lamp", "Lamp", "", "New lamp data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_lamps_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a lamp from the current blendfile");
        parm = RNA_def_pointer(func, "lamp", "Lamp", "", "Lamp to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "",
+                       "Unlink all usages of this lamp before deleting it "
+                       "(WARNING: will also delete objects instancing that lamp data)");
 
        func = RNA_def_function(srna, "tag", "rna_Main_lamps_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1220,12 +955,13 @@ void RNA_def_main_images(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "image", "Image", "", "New image data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_images_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove an image from the current blendfile");
        parm = RNA_def_pointer(func, "image", "Image", "", "Image to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this image before deleting it");
 
        func = RNA_def_function(srna, "tag", "rna_Main_images_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1256,12 +992,15 @@ void RNA_def_main_lattices(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "lattice", "Lattice", "", "New lattices data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_lattices_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a lattice from the current blendfile");
        parm = RNA_def_pointer(func, "lattice", "Lattice", "", "Lattice to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "",
+                       "Unlink all usages of this lattice before deleting it "
+                       "(WARNING: will also delete objects instancing that lattice data)");
 
        func = RNA_def_function(srna, "tag", "rna_Main_lattices_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1293,12 +1032,15 @@ void RNA_def_main_curves(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "curve", "Curve", "", "New curve data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_curves_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a curve from the current blendfile");
        parm = RNA_def_pointer(func, "curve", "Curve", "", "Curve to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "",
+                       "Unlink all usages of this curve before deleting it "
+                       "(WARNING: will also delete objects instancing that curve data)");
 
        func = RNA_def_function(srna, "tag", "rna_Main_curves_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1328,12 +1070,15 @@ void RNA_def_main_metaballs(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "metaball", "MetaBall", "", "New metaball data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_metaballs_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a metaball from the current blendfile");
        parm = RNA_def_pointer(func, "metaball", "MetaBall", "", "Metaball to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "",
+                       "Unlink all usages of this metaball before deleting it "
+                       "(WARNING: will also delete objects instancing that metaball data)");
 
        func = RNA_def_function(srna, "tag", "rna_Main_metaballs_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1365,12 +1110,13 @@ void RNA_def_main_fonts(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "vfont", "VectorFont", "", "New font data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_fonts_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a font from the current blendfile");
        parm = RNA_def_pointer(func, "vfont", "VectorFont", "", "Font to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this font before deleting it");
 
        func = RNA_def_function(srna, "tag", "rna_Main_fonts_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1402,12 +1148,13 @@ void RNA_def_main_textures(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "texture", "Texture", "", "New texture data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_textures_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a texture from the current blendfile");
        parm = RNA_def_pointer(func, "texture", "Texture", "", "Texture to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this texture before deleting it");
 
        func = RNA_def_function(srna, "tag", "rna_Main_textures_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1438,12 +1185,13 @@ void RNA_def_main_brushes(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "brush", "Brush", "", "New brush data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_brushes_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a brush from the current blendfile");
        parm = RNA_def_pointer(func, "brush", "Brush", "", "Brush to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this brush before deleting it");
 
        func = RNA_def_function(srna, "tag", "rna_Main_brushes_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1474,12 +1222,13 @@ void RNA_def_main_worlds(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "world", "World", "", "New world data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_worlds_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a world from the current blendfile");
        parm = RNA_def_pointer(func, "world", "World", "", "World to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this world before deleting it");
 
        func = RNA_def_function(srna, "tag", "rna_Main_worlds_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1510,11 +1259,13 @@ void RNA_def_main_groups(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "group", "Group", "", "New group data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_groups_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_ui_description(func, "Remove a group from the current blendfile");
+       RNA_def_function_flag(func, FUNC_USE_REPORTS);
        parm = RNA_def_pointer(func, "group", "Group", "", "Group to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this group before deleting it");
 
        func = RNA_def_function(srna, "tag", "rna_Main_groups_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1545,12 +1296,15 @@ void RNA_def_main_speakers(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "speaker", "Speaker", "", "New speaker data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_speakers_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a speaker from the current blendfile");
        parm = RNA_def_pointer(func, "speaker", "Speaker", "", "Speaker to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "",
+                       "Unlink all usages of this speaker before deleting it "
+                       "(WARNING: will also delete objects instancing that speaker data)");
 
        func = RNA_def_function(srna, "tag", "rna_Main_speakers_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1581,11 +1335,13 @@ void RNA_def_main_texts(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "text", "Text", "", "New text data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_texts_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_ui_description(func, "Remove a text from the current blendfile");
+       RNA_def_function_flag(func, FUNC_USE_REPORTS);
        parm = RNA_def_pointer(func, "text", "Text", "", "Text to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this text before deleting it");
 
        /* load func */
        func = RNA_def_function(srna, "load", "rna_Main_texts_load");
@@ -1629,12 +1385,13 @@ void RNA_def_main_sounds(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "sound", "Sound", "", "New text data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_sounds_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a sound from the current blendfile");
        parm = RNA_def_pointer(func, "sound", "Sound", "", "Sound to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this sound before deleting it");
 
        func = RNA_def_function(srna, "tag", "rna_Main_sounds_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1665,12 +1422,15 @@ void RNA_def_main_armatures(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "armature", "Armature", "", "New armature data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_armatures_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a armature from the current blendfile");
        parm = RNA_def_pointer(func, "armature", "Armature", "", "Armature to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "",
+                       "Unlink all usages of this armature before deleting it "
+                       "(WARNING: will also delete objects instancing that armature data)");
 
        func = RNA_def_function(srna, "tag", "rna_Main_armatures_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1700,12 +1460,13 @@ void RNA_def_main_actions(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "action", "Action", "", "New action data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_actions_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a action from the current blendfile");
        parm = RNA_def_pointer(func, "action", "Action", "", "Action to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this action before deleting it");
 
        func = RNA_def_function(srna, "tag", "rna_Main_actions_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1735,12 +1496,13 @@ void RNA_def_main_particles(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "particle", "ParticleSettings", "", "New particle settings data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_particles_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a particle settings instance from the current blendfile");
        parm = RNA_def_pointer(func, "particle", "ParticleSettings", "", "Particle Settings to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of those particle settings before deleting them");
 
        func = RNA_def_function(srna, "tag", "rna_Main_particles_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1770,12 +1532,13 @@ void RNA_def_main_palettes(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "palette", "Palette", "", "New palette data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_palettes_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a palette from the current blendfile");
        parm = RNA_def_pointer(func, "palette", "Palette", "", "Palette to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this palette before deleting it");
 
        func = RNA_def_function(srna, "tag", "rna_Main_palettes_tag");
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
@@ -1809,12 +1572,13 @@ void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "grease_pencil", "GreasePencil", "", "New grease pencil data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_grease_pencil_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a grease pencil instance from the current blendfile");
        parm = RNA_def_pointer(func, "grease_pencil", "GreasePencil", "", "Grease Pencil to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this grease pencil before deleting it");
 
        prop = RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -1837,11 +1601,13 @@ void RNA_def_main_movieclips(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_boolean(func, "value", 0, "Value", "");
        RNA_def_property_flag(parm, PROP_REQUIRED);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_movieclips_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
+       RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a movie clip from the current blendfile.");
        parm = RNA_def_pointer(func, "clip", "MovieClip", "", "Movie clip to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this movie clip before deleting it");
 
        /* load func */
        func = RNA_def_function(srna, "load", "rna_Main_movieclip_load");
@@ -1887,11 +1653,13 @@ void RNA_def_main_masks(BlenderRNA *brna, PropertyRNA *cprop)
        RNA_def_function_return(func, parm);
 
        /* remove func */
-       func = RNA_def_function(srna, "remove", "rna_Main_masks_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
+       RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a masks from the current blendfile.");
        parm = RNA_def_pointer(func, "mask", "Mask", "", "Mask to remove");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
        RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this mask before deleting it");
 
        prop = RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -1922,11 +1690,13 @@ void RNA_def_main_linestyles(BlenderRNA *brna, PropertyRNA *cprop)
        parm = RNA_def_pointer(func, "linestyle", "FreestyleLineStyle", "", "New line style data-block");
        RNA_def_function_return(func, parm);
 
-       func = RNA_def_function(srna, "remove", "rna_Main_linestyles_remove");
+       func = RNA_def_function(srna, "remove", "rna_Main_ID_remove");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
        RNA_def_function_ui_description(func, "Remove a line style instance from the current blendfile");
        parm = RNA_def_pointer(func, "linestyle", "FreestyleLineStyle", "", "Line style to remove");
-       RNA_def_property_flag(parm, PROP_REQUIRED);
+       RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+       RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+       RNA_def_boolean(func, "do_unlink", false, "", "Unlink all usages of this line style before deleting it");
 
        prop = RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);