Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/windowmanager/intern/wm_dragdrop.c')
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index 6fdcbab889c..9684c21605a 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -39,6 +39,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_idtype.h"
+#include "BKE_lib_id.h"
#include "GPU_shader.h"
#include "GPU_state.h"
@@ -95,11 +96,13 @@ ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid)
wmDropBox *WM_dropbox_add(ListBase *lb,
const char *idname,
bool (*poll)(bContext *, wmDrag *, const wmEvent *, const char **),
- void (*copy)(wmDrag *, wmDropBox *))
+ void (*copy)(wmDrag *, wmDropBox *),
+ void (*cancel)(struct Main *, wmDrag *, wmDropBox *))
{
wmDropBox *drop = MEM_callocN(sizeof(wmDropBox), "wmDropBox");
drop->poll = poll;
drop->copy = copy;
+ drop->cancel = cancel;
drop->ot = WM_operatortype_find(idname, 0);
drop->opcontext = WM_OP_INVOKE_DEFAULT;
@@ -382,6 +385,9 @@ static ID *wm_drag_asset_id_import(wmDragAsset *asset_drag)
/**
* When dragging a local ID, return that. Otherwise, if dragging an asset-handle, link or append
* that depending on what was chosen by the drag-box (currently append only in fact).
+ *
+ * Use #WM_drag_free_imported_drag_ID() as cancel callback of the drop-box, so that the asset
+ * import is rolled back if the drop operator fails.
*/
ID *WM_drag_get_local_ID_or_import_from_asset(const wmDrag *drag, int idcode)
{
@@ -402,6 +408,39 @@ ID *WM_drag_get_local_ID_or_import_from_asset(const wmDrag *drag, int idcode)
return wm_drag_asset_id_import(asset_drag);
}
+/**
+ * \brief Free asset ID imported for cancelled drop.
+ *
+ * If the asset was imported (linked/appended) using #WM_drag_get_local_ID_or_import_from_asset()`
+ * (typically via a #wmDropBox.copy() callback), we want the ID to be removed again if the drop
+ * operator cancels.
+ * This is for use as #wmDropBox.cancel() callback.
+ */
+void WM_drag_free_imported_drag_ID(struct Main *bmain, wmDrag *drag, wmDropBox *drop)
+{
+ if (drag->type != WM_DRAG_ASSET) {
+ return;
+ }
+
+ wmDragAsset *asset_drag = WM_drag_get_asset_data(drag, 0);
+ if (!asset_drag) {
+ return;
+ }
+
+ /* Get name from property, not asset data - it may have changed after importing to ensure
+ * uniqueness (name is assumed to be set from the imported ID name). */
+ char name[MAX_ID_NAME - 2];
+ RNA_string_get(drop->ptr, "name", name);
+ if (!name[0]) {
+ return;
+ }
+
+ ID *id = BKE_libblock_find_name(bmain, asset_drag->id_type, name);
+ if (id) {
+ BKE_id_delete(bmain, id);
+ }
+}
+
/* ************** draw ***************** */
static void wm_drop_operator_draw(const char *name, int x, int y)