Blender  V2.93
outliner_tools.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2004 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "MEM_guardedalloc.h"
25 
26 #include "CLG_log.h"
27 
28 #include "DNA_anim_types.h"
29 #include "DNA_armature_types.h"
30 #include "DNA_collection_types.h"
31 #include "DNA_constraint_types.h"
32 #include "DNA_gpencil_types.h"
33 #include "DNA_hair_types.h"
34 #include "DNA_light_types.h"
35 #include "DNA_linestyle_types.h"
36 #include "DNA_material_types.h"
37 #include "DNA_mesh_types.h"
38 #include "DNA_meta_types.h"
39 #include "DNA_modifier_types.h"
40 #include "DNA_object_types.h"
41 #include "DNA_pointcloud_types.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_sequence_types.h"
44 #include "DNA_simulation_types.h"
45 #include "DNA_volume_types.h"
46 #include "DNA_world_types.h"
47 
48 #include "BLI_blenlib.h"
49 #include "BLI_ghash.h"
50 #include "BLI_utildefines.h"
51 
52 #include "BKE_anim_data.h"
53 #include "BKE_animsys.h"
54 #include "BKE_armature.h"
55 #include "BKE_collection.h"
56 #include "BKE_constraint.h"
57 #include "BKE_context.h"
58 #include "BKE_fcurve.h"
59 #include "BKE_global.h"
60 #include "BKE_idtype.h"
61 #include "BKE_layer.h"
62 #include "BKE_lib_id.h"
63 #include "BKE_lib_override.h"
64 #include "BKE_lib_query.h"
65 #include "BKE_main.h"
66 #include "BKE_object.h"
67 #include "BKE_report.h"
68 #include "BKE_scene.h"
69 #include "BKE_screen.h"
70 
71 #include "DEG_depsgraph.h"
72 #include "DEG_depsgraph_build.h"
73 
74 #include "ED_object.h"
75 #include "ED_outliner.h"
76 #include "ED_scene.h"
77 #include "ED_screen.h"
78 #include "ED_sequencer.h"
79 #include "ED_undo.h"
80 
81 #include "WM_api.h"
82 #include "WM_message.h"
83 #include "WM_types.h"
84 
85 #include "UI_interface.h"
86 #include "UI_resources.h"
87 #include "UI_view2d.h"
88 
89 #include "RNA_access.h"
90 #include "RNA_define.h"
91 #include "RNA_enum_types.h"
92 
93 #include "SEQ_sequencer.h"
94 
95 #include "outliner_intern.h"
96 
97 static CLG_LogRef LOG = {"ed.outliner.tools"};
98 
99 /* -------------------------------------------------------------------- */
104  TreeElement *te, int *scenelevel, int *objectlevel, int *idlevel, int *datalevel)
105 {
106  TreeStoreElem *tselem = TREESTORE(te);
107  if (tselem->flag & TSE_SELECTED) {
108  /* Layer collection points to collection ID. */
109  if (!ELEM(tselem->type, TSE_SOME_ID, TSE_LAYER_COLLECTION)) {
110  if (*datalevel == 0) {
111  *datalevel = tselem->type;
112  }
113  else if (*datalevel != tselem->type) {
114  *datalevel = -1;
115  }
116  }
117  else {
118  const int idcode = (int)GS(tselem->id->name);
119  bool is_standard_id = false;
120  switch ((ID_Type)idcode) {
121  case ID_SCE:
122  *scenelevel = 1;
123  break;
124  case ID_OB:
125  *objectlevel = 1;
126  break;
127 
128  case ID_ME:
129  case ID_CU:
130  case ID_MB:
131  case ID_LT:
132  case ID_LA:
133  case ID_AR:
134  case ID_CA:
135  case ID_SPK:
136  case ID_MA:
137  case ID_TE:
138  case ID_IP:
139  case ID_IM:
140  case ID_SO:
141  case ID_KE:
142  case ID_WO:
143  case ID_AC:
144  case ID_TXT:
145  case ID_GR:
146  case ID_LS:
147  case ID_LI:
148  case ID_VF:
149  case ID_NT:
150  case ID_BR:
151  case ID_PA:
152  case ID_GD:
153  case ID_MC:
154  case ID_MSK:
155  case ID_PAL:
156  case ID_PC:
157  case ID_CF:
158  case ID_WS:
159  case ID_LP:
160  case ID_HA:
161  case ID_PT:
162  case ID_VO:
163  case ID_SIM:
164  is_standard_id = true;
165  break;
166  case ID_WM:
167  case ID_SCR:
168  /* Those are ignored here. */
169  /* Note: while Screens should be manageable here, deleting a screen used by a workspace
170  * will cause crashes when trying to use that workspace, so for now let's play minimal,
171  * safe change. */
172  break;
173  }
174  if (idcode == ID_NLA) {
175  /* Fake one, not an actual ID type... */
176  is_standard_id = true;
177  }
178 
179  if (is_standard_id) {
180  if (*idlevel == 0) {
181  *idlevel = idcode;
182  }
183  else if (*idlevel != idcode) {
184  *idlevel = -1;
185  }
187  *datalevel = 0;
188  }
189  }
190  }
191  }
192 }
193 
195 {
197 
198  return te;
199 }
200 
202 {
204  return false;
205  }
206  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
207  TreeElement *te = get_target_element(space_outliner);
208  if (te == NULL) {
209  return false;
210  }
211 
212  return true;
213 }
214 
216  ReportList *UNUSED(reports),
217  Scene *UNUSED(scene),
218  TreeElement *UNUSED(te),
219  TreeStoreElem *tsep,
220  TreeStoreElem *UNUSED(tselem),
221  void *UNUSED(user_data))
222 {
223  /* just set action to NULL */
225 }
226 
228  ReportList *UNUSED(reports),
229  Scene *UNUSED(scene),
230  TreeElement *te,
231  TreeStoreElem *tsep,
232  TreeStoreElem *UNUSED(tselem),
233  void *UNUSED(user_data))
234 {
235  Material **matar = NULL;
236  int a, totcol = 0;
237 
238  if (GS(tsep->id->name) == ID_OB) {
239  Object *ob = (Object *)tsep->id;
240  totcol = ob->totcol;
241  matar = ob->mat;
242  }
243  else if (GS(tsep->id->name) == ID_ME) {
244  Mesh *me = (Mesh *)tsep->id;
245  totcol = me->totcol;
246  matar = me->mat;
247  }
248  else if (GS(tsep->id->name) == ID_CU) {
249  Curve *cu = (Curve *)tsep->id;
250  totcol = cu->totcol;
251  matar = cu->mat;
252  }
253  else if (GS(tsep->id->name) == ID_MB) {
254  MetaBall *mb = (MetaBall *)tsep->id;
255  totcol = mb->totcol;
256  matar = mb->mat;
257  }
258  else if (GS(tsep->id->name) == ID_HA) {
259  Hair *hair = (Hair *)tsep->id;
260  totcol = hair->totcol;
261  matar = hair->mat;
262  }
263  else if (GS(tsep->id->name) == ID_PT) {
264  PointCloud *pointcloud = (PointCloud *)tsep->id;
265  totcol = pointcloud->totcol;
266  matar = pointcloud->mat;
267  }
268  else if (GS(tsep->id->name) == ID_VO) {
269  Volume *volume = (Volume *)tsep->id;
270  totcol = volume->totcol;
271  matar = volume->mat;
272  }
273  else {
274  BLI_assert(0);
275  }
276 
277  if (LIKELY(matar != NULL)) {
278  for (a = 0; a < totcol; a++) {
279  if (a == te->index && matar[a]) {
280  id_us_min(&matar[a]->id);
281  matar[a] = NULL;
282  }
283  }
284  }
285 }
286 
288  ReportList *UNUSED(reports),
289  Scene *UNUSED(scene),
290  TreeElement *te,
291  TreeStoreElem *tsep,
292  TreeStoreElem *UNUSED(tselem),
293  void *UNUSED(user_data))
294 {
295  MTex **mtex = NULL;
296  int a;
297 
298  if (GS(tsep->id->name) == ID_LS) {
300  mtex = ls->mtex;
301  }
302  else {
303  return;
304  }
305 
306  for (a = 0; a < MAX_MTEX; a++) {
307  if (a == te->index && mtex[a]) {
308  if (mtex[a]->tex) {
309  id_us_min(&mtex[a]->tex->id);
310  mtex[a]->tex = NULL;
311  }
312  }
313  }
314 }
315 
317  ReportList *UNUSED(reports),
318  Scene *UNUSED(scene),
319  TreeElement *UNUSED(te),
320  TreeStoreElem *tsep,
321  TreeStoreElem *tselem,
322  void *UNUSED(user_data))
323 {
324  Main *bmain = CTX_data_main(C);
325  Collection *collection = (Collection *)tselem->id;
326 
327  if (tsep) {
328  if (GS(tsep->id->name) == ID_OB) {
329  Object *ob = (Object *)tsep->id;
333  }
334  else if (GS(tsep->id->name) == ID_GR) {
335  Collection *parent = (Collection *)tsep->id;
336  id_fake_user_set(&collection->id);
337  BKE_collection_child_remove(bmain, parent, collection);
340  }
341  else if (GS(tsep->id->name) == ID_SCE) {
342  Scene *scene = (Scene *)tsep->id;
344  id_fake_user_set(&collection->id);
345  BKE_collection_child_remove(bmain, parent, collection);
348  }
349  }
350 }
351 
353  ReportList *UNUSED(reports),
354  Scene *UNUSED(scene),
355  TreeElement *te,
356  TreeStoreElem *tsep,
357  TreeStoreElem *tselem,
358  void *UNUSED(user_data))
359 {
360  if (tsep && tsep->id) {
361  Main *bmain = CTX_data_main(C);
362  Object *ob = (Object *)tselem->id;
363 
364  if (GS(tsep->id->name) == ID_OB) {
365  /* Parented objects need to find which collection to unlink from. */
366  TreeElement *te_parent = te->parent;
367  while (tsep && GS(tsep->id->name) == ID_OB) {
368  te_parent = te_parent->parent;
369  tsep = te_parent ? TREESTORE(te_parent) : NULL;
370  }
371  }
372 
373  if (tsep && tsep->id) {
374  if (GS(tsep->id->name) == ID_GR) {
375  Collection *parent = (Collection *)tsep->id;
376  BKE_collection_object_remove(bmain, parent, ob, true);
379  }
380  else if (GS(tsep->id->name) == ID_SCE) {
381  Scene *scene = (Scene *)tsep->id;
383  BKE_collection_object_remove(bmain, parent, ob, true);
386  }
387  }
388  }
389 }
390 
392  ReportList *UNUSED(reports),
393  Scene *UNUSED(scene),
394  TreeElement *UNUSED(te),
395  TreeStoreElem *tsep,
396  TreeStoreElem *tselem,
397  void *UNUSED(user_data))
398 {
399  Scene *parscene = (Scene *)tsep->id;
400  World *wo = (World *)tselem->id;
401 
402  /* need to use parent scene not just scene, otherwise may end up getting wrong one */
403  id_us_min(&wo->id);
404  parscene->world = NULL;
405 }
406 
408  ReportList *reports,
409  Scene *scene,
410  SpaceOutliner *space_outliner,
411  ListBase *lb,
412  outliner_operation_fn operation_fn,
413  void *user_data)
414 {
415  LISTBASE_FOREACH (TreeElement *, te, lb) {
416  TreeStoreElem *tselem = TREESTORE(te);
417  if (tselem->flag & TSE_SELECTED) {
418  if (((tselem->type == TSE_SOME_ID) && (te->idcode != 0)) ||
419  tselem->type == TSE_LAYER_COLLECTION) {
420  TreeStoreElem *tsep = te->parent ? TREESTORE(te->parent) : NULL;
421  operation_fn(C, reports, scene, te, tsep, tselem, user_data);
422  }
423  }
424  if (TSELEM_OPEN(tselem, space_outliner)) {
426  C, reports, scene, space_outliner, &te->subtree, operation_fn, user_data);
427  }
428  }
429 }
430 
433 /* -------------------------------------------------------------------- */
440 
442  {OL_SCENE_OP_DELETE, "DELETE", ICON_X, "Delete", ""},
443  {0, NULL, 0, NULL, NULL},
444 };
445 
447  bContext *C,
449  ListBase *lb,
450  bool (*operation_fn)(bContext *, eOutliner_PropSceneOps, TreeElement *, TreeStoreElem *))
451 {
452  bool success = false;
453 
454  LISTBASE_FOREACH (TreeElement *, te, lb) {
455  TreeStoreElem *tselem = TREESTORE(te);
456  if (tselem->flag & TSE_SELECTED) {
457  if (operation_fn(C, event, te, tselem)) {
458  success = true;
459  }
460  }
461  }
462 
463  return success;
464 }
465 
466 static bool scene_fn(bContext *C,
468  TreeElement *UNUSED(te),
469  TreeStoreElem *tselem)
470 {
471  Scene *scene = (Scene *)tselem->id;
472 
473  if (event == OL_SCENE_OP_DELETE) {
476  }
477  else {
478  return false;
479  }
480  }
481 
482  return true;
483 }
484 
486 {
487  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
488  const eOutliner_PropSceneOps event = RNA_enum_get(op->ptr, "type");
489 
490  if (outliner_do_scene_operation(C, event, &space_outliner->tree, scene_fn) == false) {
491  return OPERATOR_CANCELLED;
492  }
493 
494  if (event == OL_SCENE_OP_DELETE) {
495  outliner_cleanup_tree(space_outliner);
496  ED_undo_push(C, "Delete Scene(s)");
497  }
498  else {
499  BLI_assert(0);
500  return OPERATOR_CANCELLED;
501  }
502 
503  return OPERATOR_FINISHED;
504 }
505 
507 {
508  /* identifiers */
509  ot->name = "Outliner Scene Operation";
510  ot->idname = "OUTLINER_OT_scene_operation";
511  ot->description = "Context menu for scene operations";
512 
513  /* callbacks */
517 
518  ot->flag = 0;
519 
520  ot->prop = RNA_def_enum(ot->srna, "type", prop_scene_op_types, 0, "Scene Operation", "");
521 }
522 
525 /* -------------------------------------------------------------------- */
534 typedef struct MergedSearchData {
538 
540  const ListBase *tree, short tselem_type, short type, const char *str, uiSearchItems *items)
541 {
542  char name[64];
543  int iconid;
544 
546  TreeStoreElem *tselem = TREESTORE(te);
547 
548  if (tree_element_id_type_to_index(te) == type && tselem_type == tselem->type) {
549  if (BLI_strcasestr(te->name, str)) {
550  BLI_strncpy(name, te->name, 64);
551 
552  iconid = tree_element_get_icon(tselem, te).icon;
553 
554  /* Don't allow duplicate named items */
555  if (UI_search_items_find_index(items, name) == -1) {
556  if (!UI_search_item_add(items, name, te, iconid, 0, 0)) {
557  break;
558  }
559  }
560  }
561  }
562 
563  merged_element_search_fn_recursive(&te->subtree, tselem_type, type, str, items);
564  }
565 }
566 
567 /* Get a list of elements that match the search string */
569  void *data,
570  const char *str,
571  uiSearchItems *items,
572  const bool UNUSED(is_first))
573 {
574  MergedSearchData *search_data = (MergedSearchData *)data;
575  TreeElement *parent = search_data->parent_element;
576  TreeElement *te = search_data->select_element;
577 
579 
581 }
582 
583 /* Activate an element from the merged element search menu */
584 static void merged_element_search_exec_fn(struct bContext *C, void *UNUSED(arg1), void *element)
585 {
586  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
588 
589  outliner_item_select(C, space_outliner, te, OL_ITEM_SELECT | OL_ITEM_ACTIVATE);
590 
591  ED_outliner_select_sync_from_outliner(C, space_outliner);
592 }
593 
599 {
600  static char search[64] = "";
601  uiBlock *block;
602  uiBut *but;
603 
604  /* Clear search on each menu creation */
605  *search = '\0';
606 
607  block = UI_block_begin(C, region, __func__, UI_EMBOSS);
610 
611  short menu_width = 10 * UI_UNIT_X;
612  but = uiDefSearchBut(
613  block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, menu_width, UI_UNIT_Y, 0, 0, "");
615  NULL,
617  data,
618  false,
619  NULL,
621  NULL);
623 
624  /* Fake button to hold space for search items */
625  uiDefBut(block,
627  0,
628  "",
629  10,
630  10 - UI_searchbox_size_y(),
631  menu_width,
633  NULL,
634  0,
635  0,
636  0,
637  0,
638  NULL);
639 
640  /* Center the menu on the cursor */
641  UI_block_bounds_set_popup(block, 6, (const int[2]){-(menu_width / 2), 0});
642 
643  return block;
644 }
645 
647  TreeElement *parent_te,
648  TreeElement *activate_te)
649 {
650  MergedSearchData *select_data = MEM_callocN(sizeof(MergedSearchData), "merge_search_data");
651  select_data->parent_element = parent_te;
652  select_data->select_element = activate_te;
653 
655 }
656 
658  ReportList *UNUSED(reports),
659  Scene *UNUSED(scene),
660  TreeElement *UNUSED(te),
661  TreeStoreElem *UNUSED(tsep),
662  TreeStoreElem *tselem,
663  void *UNUSED(user_data))
664 {
665  ViewLayer *view_layer = CTX_data_view_layer(C);
666  Object *ob = (Object *)tselem->id;
667  Base *base = BKE_view_layer_base_find(view_layer, ob);
668 
669  if (base) {
671  }
672 }
673 
676 /* -------------------------------------------------------------------- */
681  ReportList *UNUSED(reports),
682  Scene *UNUSED(scene),
683  TreeElement *te,
684  TreeStoreElem *UNUSED(tsep),
685  TreeStoreElem *UNUSED(tselem),
686  void *UNUSED(user_data))
687 {
688  /* Don't extend because this toggles, which is nice for Ctrl-Click but not for a menu item.
689  * it's especially confusing when multiple items are selected since some toggle on/off. */
690  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
692  C, space_outliner, te, OL_ITEM_SELECT | OL_ITEM_ACTIVATE | OL_ITEM_RECURSIVE);
693 }
694 
696  ReportList *UNUSED(reports),
697  Scene *UNUSED(scene),
698  TreeElement *UNUSED(te),
699  TreeStoreElem *UNUSED(tsep),
700  TreeStoreElem *tselem,
701  void *UNUSED(user_data))
702 {
703  ViewLayer *view_layer = CTX_data_view_layer(C);
704  Object *ob = (Object *)tselem->id;
705  Base *base = BKE_view_layer_base_find(view_layer, ob);
706 
707  if (base) {
708  base->flag &= ~BASE_SELECTED;
709  }
710 }
711 
713 {
714  if (ob) {
715  Main *bmain = CTX_data_main(C);
716  if (ob->id.tag & LIB_TAG_INDIRECT) {
717  BKE_reportf(
718  reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", ob->id.name + 2);
719  return;
720  }
721  if (ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0 &&
723  BKE_reportf(reports,
724  RPT_WARNING,
725  "Cannot delete object '%s' from scene '%s', indirectly used objects need at "
726  "least one user",
727  ob->id.name + 2,
728  scene->id.name + 2);
729  return;
730  }
731 
732  /* Check also library later. */
733  if ((ob->mode & OB_MODE_EDIT) && BKE_object_is_in_editmode(ob)) {
735  }
736  BKE_id_delete(bmain, ob);
737  }
738 }
739 
740 static void id_local_fn(bContext *C,
741  ReportList *UNUSED(reports),
742  Scene *UNUSED(scene),
743  TreeElement *UNUSED(te),
744  TreeStoreElem *UNUSED(tsep),
745  TreeStoreElem *tselem,
746  void *UNUSED(user_data))
747 {
748  if (ID_IS_LINKED(tselem->id) && (tselem->id->tag & LIB_TAG_EXTERN)) {
749  Main *bmain = CTX_data_main(C);
750  /* if the ID type has no special local function,
751  * just clear the lib */
752  if (BKE_lib_id_make_local(bmain, tselem->id, false, 0) == false) {
753  BKE_lib_id_clear_library_data(bmain, tselem->id);
754  }
755  else {
757  }
758  }
759  else if (ID_IS_OVERRIDE_LIBRARY_REAL(tselem->id)) {
761  }
762 }
763 
765  ReportList *reports,
766  Scene *UNUSED(scene),
767  TreeElement *UNUSED(te),
768  TreeStoreElem *UNUSED(tsep),
769  TreeStoreElem *tselem,
770  void *UNUSED(user_data))
771 {
772  BLI_assert(TSE_IS_REAL_ID(tselem));
773  ID *id_proxy = tselem->id;
774  BLI_assert(GS(id_proxy->name) == ID_OB);
775  Object *ob_proxy = (Object *)id_proxy;
777 
778  if (ob_proxy->proxy == NULL) {
779  return;
780  }
781 
783  CTX_data_main(C), scene, CTX_data_view_layer(C), ob_proxy)) {
784  BKE_reportf(
785  reports,
787  "Could not create a library override from proxy '%s' (might use already local data?)",
788  ob_proxy->id.name + 2);
789  return;
790  }
791 
794 }
795 
796 typedef struct OutlinerLibOverrideData {
804 
806  ReportList *reports,
807  Scene *scene,
808  TreeElement *te,
809  TreeStoreElem *tsep,
810  TreeStoreElem *tselem,
811  void *user_data)
812 {
813  BLI_assert(TSE_IS_REAL_ID(tselem));
814  ID *id_root = tselem->id;
816  const bool do_hierarchy = data->do_hierarchy;
817  bool success = false;
818 
819  ID *id_reference = NULL;
820  bool is_override_instancing_object = false;
821  if (tsep != NULL && tsep->type == TSE_SOME_ID && tsep->id != NULL &&
822  GS(tsep->id->name) == ID_OB) {
823  Object *ob = (Object *)tsep->id;
824  if (ob->type == OB_EMPTY && &ob->instance_collection->id == id_root) {
825  BLI_assert(GS(id_root->name) == ID_GR);
826  /* Empty instantiating the collection we override, we need to pass it to BKE overriding code
827  * for proper handling. */
828  id_reference = tsep->id;
829  is_override_instancing_object = true;
830  }
831  }
832 
833  if (ID_IS_OVERRIDABLE_LIBRARY(id_root) || (ID_IS_LINKED(id_root) && do_hierarchy)) {
834  Main *bmain = CTX_data_main(C);
835 
836  id_root->tag |= LIB_TAG_DOIT;
837 
838  /* For now, remap all local usages of linked ID to local override one here. */
839  ID *id_iter;
840  FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
841  if (ID_IS_LINKED(id_iter)) {
842  id_iter->tag &= ~LIB_TAG_DOIT;
843  }
844  else {
845  id_iter->tag |= LIB_TAG_DOIT;
846  }
847  }
849 
850  if (do_hierarchy) {
851  /* Tag all linked parents in tree hierarchy to be also overridden. */
852  while ((te = te->parent) != NULL) {
853  if (!TSE_IS_REAL_ID(te->store_elem)) {
854  continue;
855  }
856  if (!ID_IS_LINKED(te->store_elem->id)) {
857  break;
858  }
859  te->store_elem->id->tag |= LIB_TAG_DOIT;
860  }
862  bmain, CTX_data_scene(C), CTX_data_view_layer(C), id_root, id_reference);
863  }
864  else if (ID_IS_OVERRIDABLE_LIBRARY(id_root)) {
865  success = BKE_lib_override_library_create_from_id(bmain, id_root, true) != NULL;
866 
867  /* Cleanup. */
869  BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
870  }
871 
872  /* Remove the instance empty from this scene, the items now have an overridden collection
873  * instead. */
874  if (success && is_override_instancing_object) {
875  ED_object_base_free_and_unlink(bmain, scene, (Object *)id_reference);
876  }
877  }
878  if (!success) {
879  BKE_reportf(reports,
880  RPT_WARNING,
881  "Could not create library override from data-block '%s'",
882  id_root->name);
883  }
884 }
885 
887  ReportList *UNUSED(reports),
888  Scene *UNUSED(scene),
889  TreeElement *UNUSED(te),
890  TreeStoreElem *UNUSED(tsep),
891  TreeStoreElem *tselem,
892  void *user_data)
893 {
894  BLI_assert(TSE_IS_REAL_ID(tselem));
895  ID *id_root = tselem->id;
897  const bool do_hierarchy = data->do_hierarchy;
898 
899  if (ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) {
900  Main *bmain = CTX_data_main(C);
901 
902  if (do_hierarchy) {
904  }
905  else {
906  BKE_lib_override_library_id_reset(bmain, id_root);
907  }
908 
911  }
912  else {
913  CLOG_WARN(&LOG, "Could not reset library override of data block '%s'", id_root->name);
914  }
915 }
916 
918  ReportList *UNUSED(reports),
919  Scene *scene,
920  TreeElement *te,
921  TreeStoreElem *UNUSED(tsep),
922  TreeStoreElem *tselem,
923  void *user_data)
924 {
925  BLI_assert(TSE_IS_REAL_ID(tselem));
926  ID *id_root = tselem->id;
928  const bool do_hierarchy_enforce = data->do_resync_hierarchy_enforce;
929 
930  if (ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) {
931  Main *bmain = CTX_data_main(C);
932 
933  id_root->tag |= LIB_TAG_DOIT;
934 
935  /* Tag all linked parents in tree hierarchy to be also overridden. */
936  while ((te = te->parent) != NULL) {
937  if (!TSE_IS_REAL_ID(te->store_elem)) {
938  continue;
939  }
941  break;
942  }
943  te->store_elem->id->tag |= LIB_TAG_DOIT;
944  }
945 
947  bmain, scene, CTX_data_view_layer(C), id_root, NULL, do_hierarchy_enforce, true);
948 
950  }
951  else {
952  CLOG_WARN(&LOG, "Could not resync library override of data block '%s'", id_root->name);
953  }
954 }
955 
957  ReportList *UNUSED(reports),
958  Scene *UNUSED(scene),
959  TreeElement *te,
960  TreeStoreElem *UNUSED(tsep),
961  TreeStoreElem *tselem,
962  void *UNUSED(user_data))
963 {
964  BLI_assert(TSE_IS_REAL_ID(tselem));
965  ID *id_root = tselem->id;
966 
967  if (ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) {
968  Main *bmain = CTX_data_main(C);
969 
970  id_root->tag |= LIB_TAG_DOIT;
971 
972  /* Tag all linked parents in tree hierarchy to be also overridden. */
973  while ((te = te->parent) != NULL) {
974  if (!TSE_IS_REAL_ID(te->store_elem)) {
975  continue;
976  }
978  break;
979  }
980  te->store_elem->id->tag |= LIB_TAG_DOIT;
981  }
982 
983  BKE_lib_override_library_delete(bmain, id_root);
984 
986  }
987  else {
988  CLOG_WARN(&LOG, "Could not delete library override of data block '%s'", id_root->name);
989  }
990 }
991 
993  ReportList *UNUSED(reports),
994  Scene *UNUSED(scene),
995  TreeElement *UNUSED(te),
996  TreeStoreElem *UNUSED(tsep),
997  TreeStoreElem *tselem,
998  void *UNUSED(user_data))
999 {
1000  ID *id = tselem->id;
1001 
1002  id_fake_user_set(id);
1003 }
1004 
1006  ReportList *UNUSED(reports),
1007  Scene *UNUSED(scene),
1008  TreeElement *UNUSED(te),
1009  TreeStoreElem *UNUSED(tsep),
1010  TreeStoreElem *tselem,
1011  void *UNUSED(user_data))
1012 {
1013  ID *id = tselem->id;
1014 
1015  id_fake_user_clear(id);
1016 }
1017 
1019  ReportList *UNUSED(reports),
1020  Scene *UNUSED(scene),
1021  TreeElement *UNUSED(te),
1022  TreeStoreElem *UNUSED(tsep),
1023  TreeStoreElem *tselem,
1024  void *UNUSED(user_data))
1025 {
1026  ID *id = tselem->id;
1027 
1029 }
1030 
1032  ReportList *UNUSED(reports),
1033  Scene *UNUSED(scene),
1034  TreeElement *te,
1035  TreeStoreElem *tsep,
1036  TreeStoreElem *tselem,
1037  void *UNUSED(user_data))
1038 {
1039  /* This callback runs for all selected elements, some of which may not be actions which results
1040  * in a crash. */
1041  if (te->idcode != ID_AC) {
1042  return;
1043  }
1044 
1045  ID *id = tselem->id;
1046 
1047  if (id) {
1048  IdAdtTemplate *iat = (IdAdtTemplate *)tsep->id;
1049  PointerRNA ptr = {NULL};
1050  PropertyRNA *prop;
1051 
1052  RNA_pointer_create(&iat->id, &RNA_AnimData, iat->adt, &ptr);
1053  prop = RNA_struct_find_property(&ptr, "action");
1054 
1055  id_single_user(C, id, &ptr, prop);
1056  }
1057 }
1058 
1060  ReportList *UNUSED(reports),
1061  Scene *UNUSED(scene),
1062  TreeElement *UNUSED(te),
1063  TreeStoreElem *tsep,
1064  TreeStoreElem *tselem,
1065  void *UNUSED(user_data))
1066 {
1067  ID *id = tselem->id;
1068 
1069  /* need to use parent scene not just scene, otherwise may end up getting wrong one */
1070  if (id) {
1071  Scene *parscene = (Scene *)tsep->id;
1072  PointerRNA ptr = {NULL};
1073  PropertyRNA *prop;
1074 
1075  RNA_id_pointer_create(&parscene->id, &ptr);
1076  prop = RNA_struct_find_property(&ptr, "world");
1077 
1078  id_single_user(C, id, &ptr, prop);
1079  }
1080 }
1081 
1087  ReportList *reports,
1088  Scene *scene_act,
1089  SpaceOutliner *space_outliner,
1090  ListBase *lb,
1091  outliner_operation_fn operation_fn,
1092  void *user_data,
1093  bool recurse_selected)
1094 {
1095  LISTBASE_FOREACH (TreeElement *, te, lb) {
1096  TreeStoreElem *tselem = TREESTORE(te);
1097  bool select_handled = false;
1098  if (tselem->flag & TSE_SELECTED) {
1099  if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) {
1100  /* When objects selected in other scenes... dunno if that should be allowed. */
1101  Scene *scene_owner = (Scene *)outliner_search_back(te, ID_SCE);
1102  if (scene_owner && scene_act != scene_owner) {
1104  }
1105  /* Important to use 'scene_owner' not scene_act else deleting objects can crash.
1106  * only use 'scene_act' when 'scene_owner' is NULL, which can happen when the
1107  * outliner isn't showing scenes: Visible Layer draw mode for eg. */
1108  operation_fn(
1109  C, reports, scene_owner ? scene_owner : scene_act, te, NULL, tselem, user_data);
1110  select_handled = true;
1111  }
1112  }
1113  if (TSELEM_OPEN(tselem, space_outliner)) {
1114  if ((select_handled == false) || recurse_selected) {
1116  reports,
1117  scene_act,
1118  space_outliner,
1119  &te->subtree,
1120  operation_fn,
1121  NULL,
1122  recurse_selected);
1123  }
1124  }
1125  }
1126 }
1127 
1129  ReportList *reports,
1130  Scene *scene_act,
1131  SpaceOutliner *space_outliner,
1132  ListBase *lb,
1133  outliner_operation_fn operation_fn)
1134 {
1136  C, reports, scene_act, space_outliner, lb, operation_fn, NULL, true);
1137 }
1138 
1141 /* -------------------------------------------------------------------- */
1145 static void clear_animdata_fn(int UNUSED(event),
1146  TreeElement *UNUSED(te),
1147  TreeStoreElem *tselem,
1148  void *UNUSED(arg))
1149 {
1150  BKE_animdata_free(tselem->id, true);
1152 }
1153 
1154 static void unlinkact_animdata_fn(int UNUSED(event),
1155  TreeElement *UNUSED(te),
1156  TreeStoreElem *tselem,
1157  void *UNUSED(arg))
1158 {
1159  /* just set action to NULL */
1160  BKE_animdata_set_action(NULL, tselem->id, NULL);
1162 }
1163 
1164 static void cleardrivers_animdata_fn(int UNUSED(event),
1165  TreeElement *UNUSED(te),
1166  TreeStoreElem *tselem,
1167  void *UNUSED(arg))
1168 {
1169  IdAdtTemplate *iat = (IdAdtTemplate *)tselem->id;
1170 
1171  /* just free drivers - stored as a list of F-Curves */
1172  BKE_fcurves_free(&iat->adt->drivers);
1174 }
1175 
1176 static void refreshdrivers_animdata_fn(int UNUSED(event),
1177  TreeElement *UNUSED(te),
1178  TreeStoreElem *tselem,
1179  void *UNUSED(arg))
1180 {
1181  IdAdtTemplate *iat = (IdAdtTemplate *)tselem->id;
1182 
1183  /* Loop over drivers, performing refresh
1184  * (i.e. check graph_buttons.c and rna_fcurve.c for details). */
1185  LISTBASE_FOREACH (FCurve *, fcu, &iat->adt->drivers) {
1186  fcu->flag &= ~FCURVE_DISABLED;
1187 
1188  if (fcu->driver) {
1189  fcu->driver->flag &= ~DRIVER_FLAG_INVALID;
1190  }
1191  }
1192 }
1193 
1196 /* -------------------------------------------------------------------- */
1207 
1213 
1219 
1220 static void pchan_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
1221 {
1222  bPoseChannel *pchan = (bPoseChannel *)te->directdata;
1223 
1224  if (event == OL_DOP_SELECT) {
1225  pchan->bone->flag |= BONE_SELECTED;
1226  }
1227  else if (event == OL_DOP_DESELECT) {
1228  pchan->bone->flag &= ~BONE_SELECTED;
1229  }
1230  else if (event == OL_DOP_HIDE) {
1231  pchan->bone->flag |= BONE_HIDDEN_P;
1232  pchan->bone->flag &= ~BONE_SELECTED;
1233  }
1234  else if (event == OL_DOP_UNHIDE) {
1235  pchan->bone->flag &= ~BONE_HIDDEN_P;
1236  }
1237 }
1238 
1239 static void bone_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
1240 {
1241  Bone *bone = (Bone *)te->directdata;
1242 
1243  if (event == OL_DOP_SELECT) {
1244  bone->flag |= BONE_SELECTED;
1245  }
1246  else if (event == OL_DOP_DESELECT) {
1247  bone->flag &= ~BONE_SELECTED;
1248  }
1249  else if (event == OL_DOP_HIDE) {
1250  bone->flag |= BONE_HIDDEN_P;
1251  bone->flag &= ~BONE_SELECTED;
1252  }
1253  else if (event == OL_DOP_UNHIDE) {
1254  bone->flag &= ~BONE_HIDDEN_P;
1255  }
1256 }
1257 
1258 static void ebone_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
1259 {
1260  EditBone *ebone = (EditBone *)te->directdata;
1261 
1262  if (event == OL_DOP_SELECT) {
1263  ebone->flag |= BONE_SELECTED;
1264  }
1265  else if (event == OL_DOP_DESELECT) {
1266  ebone->flag &= ~BONE_SELECTED;
1267  }
1268  else if (event == OL_DOP_HIDE) {
1269  ebone->flag |= BONE_HIDDEN_A;
1270  ebone->flag &= ~BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL;
1271  }
1272  else if (event == OL_DOP_UNHIDE) {
1273  ebone->flag &= ~BONE_HIDDEN_A;
1274  }
1275 }
1276 
1277 static void sequence_fn(int event, TreeElement *te, TreeStoreElem *tselem, void *scene_ptr)
1278 {
1279  Sequence *seq = (Sequence *)te->directdata;
1280  if (event == OL_DOP_SELECT) {
1281  Scene *scene = (Scene *)scene_ptr;
1282  Editing *ed = SEQ_editing_get(scene, false);
1283  if (BLI_findindex(ed->seqbasep, seq) != -1) {
1285  }
1286  }
1287 
1288  (void)tselem;
1289 }
1290 
1291 static void gpencil_layer_fn(int event,
1292  TreeElement *te,
1293  TreeStoreElem *UNUSED(tselem),
1294  void *UNUSED(arg))
1295 {
1296  bGPDlayer *gpl = (bGPDlayer *)te->directdata;
1297 
1298  if (event == OL_DOP_SELECT) {
1299  gpl->flag |= GP_LAYER_SELECT;
1300  }
1301  else if (event == OL_DOP_DESELECT) {
1302  gpl->flag &= ~GP_LAYER_SELECT;
1303  }
1304  else if (event == OL_DOP_HIDE) {
1305  gpl->flag |= GP_LAYER_HIDE;
1306  }
1307  else if (event == OL_DOP_UNHIDE) {
1308  gpl->flag &= ~GP_LAYER_HIDE;
1309  }
1310 }
1311 
1312 static void data_select_linked_fn(int event,
1313  TreeElement *te,
1314  TreeStoreElem *UNUSED(tselem),
1315  void *C_v)
1316 {
1317  if (event == OL_DOP_SELECT_LINKED) {
1318  if (RNA_struct_is_ID(te->rnaptr.type)) {
1319  bContext *C = (bContext *)C_v;
1320  ID *id = te->rnaptr.data;
1321 
1323  }
1324  }
1325 }
1326 
1327 static void constraint_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *C_v)
1328 {
1329  bContext *C = C_v;
1330  Main *bmain = CTX_data_main(C);
1331  bConstraint *constraint = (bConstraint *)te->directdata;
1332  Object *ob = (Object *)outliner_search_back(te, ID_OB);
1333 
1334  if (event == OL_CONSTRAINTOP_ENABLE) {
1335  constraint->flag &= ~CONSTRAINT_OFF;
1336  ED_object_constraint_update(bmain, ob);
1338  }
1339  else if (event == OL_CONSTRAINTOP_DISABLE) {
1340  constraint->flag = CONSTRAINT_OFF;
1341  ED_object_constraint_update(bmain, ob);
1343  }
1344  else if (event == OL_CONSTRAINTOP_DELETE) {
1345  ListBase *lb = NULL;
1346 
1347  if (TREESTORE(te->parent->parent)->type == TSE_POSE_CHANNEL) {
1348  lb = &((bPoseChannel *)te->parent->parent->directdata)->constraints;
1349  }
1350  else {
1351  lb = &ob->constraints;
1352  }
1353 
1354  if (BKE_constraint_remove_ex(lb, ob, constraint, true)) {
1355  /* there's no active constraint now, so make sure this is the case */
1356  BKE_constraints_active_set(&ob->constraints, NULL);
1357 
1358  /* needed to set the flags on posebones correctly */
1359  ED_object_constraint_update(bmain, ob);
1360 
1362  te->store_elem->flag &= ~TSE_SELECTED;
1363  }
1364  }
1365 }
1366 
1367 static void modifier_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *Carg)
1368 {
1369  bContext *C = (bContext *)Carg;
1370  Main *bmain = CTX_data_main(C);
1372  ModifierData *md = (ModifierData *)te->directdata;
1373  Object *ob = (Object *)outliner_search_back(te, ID_OB);
1374 
1375  if (event == OL_MODIFIER_OP_TOGVIS) {
1379  }
1380  else if (event == OL_MODIFIER_OP_TOGREN) {
1381  md->mode ^= eModifierMode_Render;
1384  }
1385  else if (event == OL_MODIFIER_OP_DELETE) {
1386  ED_object_modifier_remove(NULL, bmain, scene, ob, md);
1388  te->store_elem->flag &= ~TSE_SELECTED;
1389  }
1390 }
1391 
1393  SpaceOutliner *space_outliner,
1394  int type,
1395  int event,
1396  ListBase *lb,
1397  void (*operation_fn)(int, TreeElement *, TreeStoreElem *, void *),
1398  void *arg)
1399 {
1400  LISTBASE_FOREACH (TreeElement *, te, lb) {
1401  TreeStoreElem *tselem = TREESTORE(te);
1402  if (tselem->flag & TSE_SELECTED) {
1403  if (tselem->type == type) {
1404  operation_fn(event, te, tselem, arg);
1405  }
1406  }
1407  if (TSELEM_OPEN(tselem, space_outliner)) {
1408  outliner_do_data_operation(space_outliner, type, event, &te->subtree, operation_fn, arg);
1409  }
1410  }
1411 }
1412 
1414  ReportList *reports, Main *bmain, ViewLayer *view_layer, Scene *scene, Base *base)
1415 {
1416  Base *child_base, *base_next;
1417  Object *object, *parent;
1418 
1419  if (!base) {
1420  return NULL;
1421  }
1422 
1423  object = base->object;
1424  for (child_base = view_layer->object_bases.first; child_base; child_base = base_next) {
1425  base_next = child_base->next;
1426  for (parent = child_base->object->parent; parent && (parent != object);
1427  parent = parent->parent) {
1428  /* pass */
1429  }
1430  if (parent) {
1431  base_next = outline_batch_delete_hierarchy(reports, bmain, view_layer, scene, child_base);
1432  }
1433  }
1434 
1435  base_next = base->next;
1436 
1437  if (object->id.tag & LIB_TAG_INDIRECT) {
1438  BKE_reportf(reports,
1439  RPT_WARNING,
1440  "Cannot delete indirectly linked object '%s'",
1441  base->object->id.name + 2);
1442  return base_next;
1443  }
1444  if (ID_REAL_USERS(object) <= 1 && ID_EXTRA_USERS(object) == 0 &&
1445  BKE_library_ID_is_indirectly_used(bmain, object)) {
1446  BKE_reportf(reports,
1447  RPT_WARNING,
1448  "Cannot delete object '%s' from scene '%s', indirectly used objects need at least "
1449  "one user",
1450  object->id.name + 2,
1451  scene->id.name + 2);
1452  return base_next;
1453  }
1454 
1455  DEG_id_tag_update_ex(bmain, &object->id, ID_RECALC_BASE_FLAGS);
1456  BKE_scene_collections_object_remove(bmain, scene, object, false);
1457 
1458  if (object->id.us == 0) {
1459  object->id.tag |= LIB_TAG_DOIT;
1460  }
1461 
1462  return base_next;
1463 }
1464 
1466  ReportList *reports,
1467  Scene *scene,
1468  Object *ob)
1469 {
1470  ViewLayer *view_layer = CTX_data_view_layer(C);
1471  Object *obedit = CTX_data_edit_object(C);
1472 
1473  Base *base = BKE_view_layer_base_find(view_layer, ob);
1474 
1475  if (base) {
1476  /* Check also library later. */
1477  for (; obedit && (obedit != base->object); obedit = obedit->parent) {
1478  /* pass */
1479  }
1480  if (obedit == base->object) {
1482  }
1483 
1484  outline_batch_delete_hierarchy(reports, CTX_data_main(C), view_layer, scene, base);
1485  }
1486 }
1487 
1490 /* -------------------------------------------------------------------- */
1494 enum {
1501 };
1502 
1504  {OL_OP_SELECT, "SELECT", ICON_RESTRICT_SELECT_OFF, "Select", ""},
1505  {OL_OP_DESELECT, "DESELECT", 0, "Deselect", ""},
1506  {OL_OP_SELECT_HIERARCHY, "SELECT_HIERARCHY", 0, "Select Hierarchy", ""},
1507  {OL_OP_REMAP,
1508  "REMAP",
1509  0,
1510  "Remap Users",
1511  "Make all users of selected data-blocks to use instead a new chosen one"},
1512  {OL_OP_RENAME, "RENAME", 0, "Rename", ""},
1514  "OBJECT_PROXY_TO_OVERRIDE",
1515  0,
1516  "Convert Proxy to Override",
1517  "Convert a Proxy object to a full library override, including all its dependencies"},
1518  {0, NULL, 0, NULL, NULL},
1519 };
1520 
1522 {
1523  Main *bmain = CTX_data_main(C);
1525  wmWindow *win = CTX_wm_window(C);
1526  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1527  int event;
1528  const char *str = NULL;
1529  bool selection_changed = false;
1530 
1531  /* check for invalid states */
1532  if (space_outliner == NULL) {
1533  return OPERATOR_CANCELLED;
1534  }
1535 
1536  event = RNA_enum_get(op->ptr, "type");
1537 
1538  if (event == OL_OP_SELECT) {
1539  Scene *sce = scene; /* To be able to delete, scenes are set... */
1541  C, op->reports, scene, space_outliner, &space_outliner->tree, object_select_fn);
1542  if (scene != sce) {
1543  WM_window_set_active_scene(bmain, C, win, sce);
1544  }
1545 
1546  str = "Select Objects";
1547  selection_changed = true;
1548  }
1549  else if (event == OL_OP_SELECT_HIERARCHY) {
1550  Scene *sce = scene; /* To be able to delete, scenes are set... */
1552  op->reports,
1553  scene,
1554  space_outliner,
1555  &space_outliner->tree,
1557  NULL,
1558  false);
1559  if (scene != sce) {
1560  WM_window_set_active_scene(bmain, C, win, sce);
1561  }
1562  str = "Select Object Hierarchy";
1563  selection_changed = true;
1564  }
1565  else if (event == OL_OP_DESELECT) {
1567  C, op->reports, scene, space_outliner, &space_outliner->tree, object_deselect_fn);
1568  str = "Deselect Objects";
1569  selection_changed = true;
1570  }
1571  else if (event == OL_OP_REMAP) {
1573  C, op->reports, scene, space_outliner, &space_outliner->tree, id_remap_fn, NULL);
1574  /* No undo push here, operator does it itself (since it's a modal one, the op_undo_depth
1575  * trick does not work here). */
1576  }
1577  else if (event == OL_OP_RENAME) {
1579  C, op->reports, scene, space_outliner, &space_outliner->tree, item_rename_fn);
1580  str = "Rename Object";
1581  }
1582  else if (event == OL_OP_PROXY_TO_OVERRIDE_CONVERT) {
1584  op->reports,
1585  scene,
1586  space_outliner,
1587  &space_outliner->tree,
1589  str = "Convert Proxy to Override";
1590  }
1591  else {
1592  BLI_assert(0);
1593  return OPERATOR_CANCELLED;
1594  }
1595 
1596  if (selection_changed) {
1600  }
1601 
1602  if (str != NULL) {
1603  ED_undo_push(C, str);
1604  }
1605 
1606  return OPERATOR_FINISHED;
1607 }
1608 
1610 {
1611  /* identifiers */
1612  ot->name = "Outliner Object Operation";
1613  ot->idname = "OUTLINER_OT_object_operation";
1614 
1615  /* callbacks */
1619 
1620  ot->flag = 0;
1621 
1622  ot->prop = RNA_def_enum(ot->srna, "type", prop_object_op_types, 0, "Object Operation", "");
1623 }
1624 
1627 /* -------------------------------------------------------------------- */
1631 typedef void (*OutlinerDeleteFunc)(bContext *C, ReportList *reports, Scene *scene, Object *ob);
1632 
1634  ReportList *reports,
1635  Scene *scene,
1636  GSet *objects_to_delete,
1637  OutlinerDeleteFunc delete_fn)
1638 {
1639  GSetIterator objects_to_delete_iter;
1640  GSET_ITER (objects_to_delete_iter, objects_to_delete) {
1641  Object *ob = (Object *)BLI_gsetIterator_getKey(&objects_to_delete_iter);
1642 
1643  delete_fn(C, reports, scene, ob);
1644  }
1645 }
1646 
1648 {
1649  GSet *objects_to_delete = (GSet *)customdata;
1650  TreeStoreElem *tselem = TREESTORE(te);
1651 
1653  return TRAVERSE_CONTINUE;
1654  }
1655 
1656  if ((tselem->type != TSE_SOME_ID) || (tselem->id == NULL) || (GS(tselem->id->name) != ID_OB)) {
1657  return TRAVERSE_SKIP_CHILDS;
1658  }
1659 
1660  BLI_gset_add(objects_to_delete, tselem->id);
1661 
1662  return TRAVERSE_CONTINUE;
1663 }
1664 
1666 {
1667  Main *bmain = CTX_data_main(C);
1669  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1670  struct wmMsgBus *mbus = CTX_wm_message_bus(C);
1671  ViewLayer *view_layer = CTX_data_view_layer(C);
1672  const Base *basact_prev = BASACT(view_layer);
1673 
1674  const bool delete_hierarchy = RNA_boolean_get(op->ptr, "hierarchy");
1675 
1676  /* Get selected objects skipping duplicates to prevent deleting objects linked to multiple
1677  * collections twice */
1678  GSet *objects_to_delete = BLI_gset_ptr_new(__func__);
1679  outliner_tree_traverse(space_outliner,
1680  &space_outliner->tree,
1681  0,
1682  TSE_SELECTED,
1684  objects_to_delete);
1685 
1686  if (delete_hierarchy) {
1687  BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
1688 
1690  C, op->reports, scene, objects_to_delete, object_batch_delete_hierarchy_fn);
1691 
1693  }
1694  else {
1696  }
1697 
1698  BLI_gset_free(objects_to_delete, NULL);
1699 
1700  outliner_collection_delete(C, bmain, scene, op->reports, delete_hierarchy);
1701 
1702  /* Tree management normally happens from draw_outliner(), but when
1703  * you're clicking too fast on Delete object from context menu in
1704  * outliner several mouse events can be handled in one cycle without
1705  * handling notifiers/redraw which leads to deleting the same object twice.
1706  * cleanup tree here to prevent such cases. */
1707  outliner_cleanup_tree(space_outliner);
1708 
1710  DEG_relations_tag_update(bmain);
1711 
1712  if (basact_prev != BASACT(view_layer)) {
1714  WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active);
1715  }
1716 
1721 
1722  return OPERATOR_FINISHED;
1723 }
1724 
1726 {
1727  /* identifiers */
1728  ot->name = "Delete";
1729  ot->idname = "OUTLINER_OT_delete";
1730  ot->description = "Delete selected objects and collections";
1731 
1732  /* callbacks */
1735 
1736  /* flags */
1738 
1739  /* properties */
1740  PropertyRNA *prop = RNA_def_boolean(
1741  ot->srna, "hierarchy", false, "Hierarchy", "Delete child objects and collections");
1743 }
1744 
1747 /* -------------------------------------------------------------------- */
1751 typedef enum eOutlinerIdOpTypes {
1753 
1769 
1772 
1776 
1779 
1780 /* TODO: implement support for changing the ID-block used. */
1782  {OUTLINER_IDOP_UNLINK, "UNLINK", 0, "Unlink", ""},
1783  {OUTLINER_IDOP_MARK_ASSET, "MARK_ASSET", 0, "Mark Asset", ""},
1784  {OUTLINER_IDOP_CLEAR_ASSET, "CLEAR_ASSET", 0, "Clear Asset", ""},
1785  {OUTLINER_IDOP_LOCAL, "LOCAL", 0, "Make Local", ""},
1786  {OUTLINER_IDOP_SINGLE, "SINGLE", 0, "Make Single User", ""},
1787  {OUTLINER_IDOP_DELETE, "DELETE", ICON_X, "Delete", ""},
1789  "REMAP",
1790  0,
1791  "Remap Users",
1792  "Make all users of selected data-blocks to use instead current (clicked) one"},
1793  {0, "", 0, NULL, NULL},
1795  "OVERRIDE_LIBRARY_CREATE",
1796  0,
1797  "Make Library Override",
1798  "Make a local override of this linked data-block"},
1800  "OVERRIDE_LIBRARY_CREATE_HIERARCHY",
1801  0,
1802  "Make Library Override Hierarchy",
1803  "Make a local override of this linked data-block, and its hierarchy of dependencies"},
1805  "OVERRIDE_LIBRARY_PROXY_CONVERT",
1806  0,
1807  "Convert Proxy to Override",
1808  "Convert a Proxy object to a full library override, including all its dependencies"},
1810  "OVERRIDE_LIBRARY_RESET",
1811  0,
1812  "Reset Library Override",
1813  "Reset this local override to its linked values"},
1815  "OVERRIDE_LIBRARY_RESET_HIERARCHY",
1816  0,
1817  "Reset Library Override Hierarchy",
1818  "Reset this local override to its linked values, as well as its hierarchy of dependencies"},
1820  "OVERRIDE_LIBRARY_RESYNC_HIERARCHY",
1821  0,
1822  "Resync Library Override Hierarchy",
1823  "Rebuild this local override from its linked reference, as well as its hierarchy of "
1824  "dependencies"},
1826  "OVERRIDE_LIBRARY_RESYNC_HIERARCHY_ENFORCE",
1827  0,
1828  "Resync Library Override Hierarchy Enforce",
1829  "Rebuild this local override from its linked reference, as well as its hierarchy of "
1830  "dependencies, enforcing that hierarchy to match the linked data (i.e. ignoring exiting "
1831  "overrides on data-blocks pointer properties)"},
1833  "OVERRIDE_LIBRARY_DELETE_HIERARCHY",
1834  0,
1835  "Delete Library Override Hierarchy",
1836  "Delete this local override (including its hierarchy of override dependencies) and relink "
1837  "its usages to the linked data-blocks"},
1838  {0, "", 0, NULL, NULL},
1839  {OUTLINER_IDOP_COPY, "COPY", ICON_COPYDOWN, "Copy", ""},
1840  {OUTLINER_IDOP_PASTE, "PASTE", ICON_PASTEDOWN, "Paste", ""},
1841  {0, "", 0, NULL, NULL},
1843  "ADD_FAKE",
1844  0,
1845  "Add Fake User",
1846  "Ensure data-block gets saved even if it isn't in use (e.g. for motion and material "
1847  "libraries)"},
1848  {OUTLINER_IDOP_FAKE_CLEAR, "CLEAR_FAKE", 0, "Clear Fake User", ""},
1849  {OUTLINER_IDOP_RENAME, "RENAME", 0, "Rename", ""},
1850  {OUTLINER_IDOP_SELECT_LINKED, "SELECT_LINKED", 0, "Select Linked", ""},
1851  {0, NULL, 0, NULL, NULL},
1852 };
1853 
1855  PointerRNA *UNUSED(ptr),
1856  PropertyRNA *UNUSED(prop),
1857  const int enum_value)
1858 {
1860  return false;
1861  }
1862 
1863  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1864  TreeElement *te = get_target_element(space_outliner);
1865  TreeStoreElem *tselem = TREESTORE(te);
1866  if (!TSE_IS_REAL_ID(tselem)) {
1867  return false;
1868  }
1869 
1870  switch (enum_value) {
1873  return U.experimental.use_asset_browser;
1875  if (ID_IS_OVERRIDABLE_LIBRARY(tselem->id)) {
1876  return true;
1877  }
1878  return false;
1880  if (ID_IS_OVERRIDABLE_LIBRARY(tselem->id) || (ID_IS_LINKED(tselem->id))) {
1881  return true;
1882  }
1883  return false;
1885  if (GS(tselem->id->name) == ID_OB) {
1886  Object *ob = (Object *)tselem->id;
1887 
1888  if ((ob != NULL) && (ob->proxy != NULL)) {
1889  return true;
1890  }
1891  }
1892  return false;
1893  }
1899  if (ID_IS_OVERRIDE_LIBRARY_REAL(tselem->id) && !ID_IS_LINKED(tselem->id)) {
1900  return true;
1901  }
1902  return false;
1903  case OUTLINER_IDOP_SINGLE:
1904  if (ELEM(space_outliner->outlinevis, SO_SCENES, SO_VIEW_LAYER)) {
1905  return true;
1906  }
1907  /* TODO(dalai): enable in the few cases where this can be supported
1908  * (i.e., when we have a valid parent for the tselem). */
1909  return false;
1910  }
1911 
1912  return true;
1913 }
1914 
1916  PointerRNA *ptr,
1917  PropertyRNA *prop,
1918  bool *r_free)
1919 {
1920  EnumPropertyItem *items = NULL;
1921  int totitem = 0;
1922 
1923  if ((C == NULL) || (ED_operator_outliner_active(C) == false)) {
1924  return prop_id_op_types;
1925  }
1926  for (const EnumPropertyItem *it = prop_id_op_types; it->identifier != NULL; it++) {
1927  if (!outliner_id_operation_item_poll(C, ptr, prop, it->value)) {
1928  continue;
1929  }
1930  RNA_enum_item_add(&items, &totitem, it);
1931  }
1932  RNA_enum_item_end(&items, &totitem);
1933  *r_free = true;
1934 
1935  return items;
1936 }
1937 
1939 {
1942  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1943  int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
1944 
1945  /* check for invalid states */
1946  if (space_outliner == NULL) {
1947  return OPERATOR_CANCELLED;
1948  }
1949 
1950  TreeElement *te = get_target_element(space_outliner);
1951  get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
1952 
1953  eOutlinerIdOpTypes event = RNA_enum_get(op->ptr, "type");
1954  switch (event) {
1955  case OUTLINER_IDOP_UNLINK: {
1956  /* unlink datablock from its parent */
1957  if (objectlevel) {
1959  C, op->reports, scene, space_outliner, &space_outliner->tree, unlink_object_fn, NULL);
1960 
1962  ED_undo_push(C, "Unlink Object");
1963  break;
1964  }
1965 
1966  switch (idlevel) {
1967  case ID_AC:
1969  op->reports,
1970  scene,
1971  space_outliner,
1972  &space_outliner->tree,
1974  NULL);
1975 
1977  ED_undo_push(C, "Unlink action");
1978  break;
1979  case ID_MA:
1981  op->reports,
1982  scene,
1983  space_outliner,
1984  &space_outliner->tree,
1986  NULL);
1987 
1989  ED_undo_push(C, "Unlink material");
1990  break;
1991  case ID_TE:
1993  op->reports,
1994  scene,
1995  space_outliner,
1996  &space_outliner->tree,
1998  NULL);
1999 
2001  ED_undo_push(C, "Unlink texture");
2002  break;
2003  case ID_WO:
2005  C, op->reports, scene, space_outliner, &space_outliner->tree, unlink_world_fn, NULL);
2006 
2008  ED_undo_push(C, "Unlink world");
2009  break;
2010  case ID_GR:
2012  op->reports,
2013  scene,
2014  space_outliner,
2015  &space_outliner->tree,
2017  NULL);
2018 
2020  ED_undo_push(C, "Unlink Collection");
2021  break;
2022  default:
2023  BKE_report(op->reports, RPT_WARNING, "Not yet implemented");
2024  break;
2025  }
2026  break;
2027  }
2028  case OUTLINER_IDOP_MARK_ASSET: {
2029  WM_operator_name_call(C, "ASSET_OT_mark", WM_OP_EXEC_DEFAULT, NULL);
2030  break;
2031  }
2033  WM_operator_name_call(C, "ASSET_OT_clear", WM_OP_EXEC_DEFAULT, NULL);
2034  break;
2035  }
2036  case OUTLINER_IDOP_LOCAL: {
2037  /* make local */
2039  C, op->reports, scene, space_outliner, &space_outliner->tree, id_local_fn, NULL);
2040  ED_undo_push(C, "Localized Data");
2041  break;
2042  }
2045  op->reports,
2046  scene,
2047  space_outliner,
2048  &space_outliner->tree,
2050  &(OutlinerLibOverrideData){.do_hierarchy = false});
2051  ED_undo_push(C, "Overridden Data");
2052  break;
2053  }
2056  op->reports,
2057  scene,
2058  space_outliner,
2059  &space_outliner->tree,
2061  &(OutlinerLibOverrideData){.do_hierarchy = true});
2062  ED_undo_push(C, "Overridden Data Hierarchy");
2063  break;
2064  }
2067  op->reports,
2068  scene,
2069  space_outliner,
2070  &space_outliner->tree,
2072  ED_undo_push(C, "Convert Proxy to Override");
2073  break;
2074  }
2077  op->reports,
2078  scene,
2079  space_outliner,
2080  &space_outliner->tree,
2082  &(OutlinerLibOverrideData){.do_hierarchy = false});
2083  ED_undo_push(C, "Reset Overridden Data");
2084  break;
2085  }
2088  op->reports,
2089  scene,
2090  space_outliner,
2091  &space_outliner->tree,
2093  &(OutlinerLibOverrideData){.do_hierarchy = true});
2094  ED_undo_push(C, "Reset Overridden Data Hierarchy");
2095  break;
2096  }
2099  op->reports,
2100  scene,
2101  space_outliner,
2102  &space_outliner->tree,
2104  &(OutlinerLibOverrideData){.do_hierarchy = true});
2105  ED_undo_push(C, "Resync Overridden Data Hierarchy");
2106  break;
2107  }
2110  C,
2111  op->reports,
2112  scene,
2113  space_outliner,
2114  &space_outliner->tree,
2116  &(OutlinerLibOverrideData){.do_hierarchy = true, .do_resync_hierarchy_enforce = true});
2117  ED_undo_push(C, "Resync Overridden Data Hierarchy");
2118  break;
2119  }
2122  op->reports,
2123  scene,
2124  space_outliner,
2125  &space_outliner->tree,
2127  &(OutlinerLibOverrideData){.do_hierarchy = true});
2128  ED_undo_push(C, "Delete Overridden Data Hierarchy");
2129  break;
2130  }
2131  case OUTLINER_IDOP_SINGLE: {
2132  /* make single user */
2133  switch (idlevel) {
2134  case ID_AC:
2136  op->reports,
2137  scene,
2138  space_outliner,
2139  &space_outliner->tree,
2141  NULL);
2142 
2144  ED_undo_push(C, "Single-User Action");
2145  break;
2146 
2147  case ID_WO:
2149  op->reports,
2150  scene,
2151  space_outliner,
2152  &space_outliner->tree,
2154  NULL);
2155 
2157  ED_undo_push(C, "Single-User World");
2158  break;
2159 
2160  default:
2161  BKE_report(op->reports, RPT_WARNING, "Not yet implemented");
2162  break;
2163  }
2164  break;
2165  }
2166  case OUTLINER_IDOP_DELETE: {
2167  if (idlevel > 0) {
2169  C, op->reports, scene, space_outliner, &space_outliner->tree, id_delete_fn, NULL);
2170  ED_undo_push(C, "Delete");
2171  }
2172  break;
2173  }
2174  case OUTLINER_IDOP_REMAP: {
2175  if (idlevel > 0) {
2177  C, op->reports, scene, space_outliner, &space_outliner->tree, id_remap_fn, NULL);
2178  /* No undo push here, operator does it itself (since it's a modal one, the op_undo_depth
2179  * trick does not work here). */
2180  }
2181  break;
2182  }
2183  case OUTLINER_IDOP_COPY: {
2184  wm->op_undo_depth++;
2185  WM_operator_name_call(C, "OUTLINER_OT_id_copy", WM_OP_INVOKE_DEFAULT, NULL);
2186  wm->op_undo_depth--;
2187  /* No need for undo, this operation does not change anything... */
2188  break;
2189  }
2190  case OUTLINER_IDOP_PASTE: {
2191  wm->op_undo_depth++;
2192  WM_operator_name_call(C, "OUTLINER_OT_id_paste", WM_OP_INVOKE_DEFAULT, NULL);
2193  wm->op_undo_depth--;
2195  ED_undo_push(C, "Paste");
2196  break;
2197  }
2198  case OUTLINER_IDOP_FAKE_ADD: {
2199  /* set fake user */
2201  C, op->reports, scene, space_outliner, &space_outliner->tree, id_fake_user_set_fn, NULL);
2202 
2204  ED_undo_push(C, "Add Fake User");
2205  break;
2206  }
2207  case OUTLINER_IDOP_FAKE_CLEAR: {
2208  /* clear fake user */
2210  op->reports,
2211  scene,
2212  space_outliner,
2213  &space_outliner->tree,
2215  NULL);
2216 
2218  ED_undo_push(C, "Clear Fake User");
2219  break;
2220  }
2221  case OUTLINER_IDOP_RENAME: {
2222  /* rename */
2224  C, op->reports, scene, space_outliner, &space_outliner->tree, item_rename_fn, NULL);
2225 
2227  ED_undo_push(C, "Rename");
2228  break;
2229  }
2232  C, op->reports, scene, space_outliner, &space_outliner->tree, id_select_linked_fn, NULL);
2234  ED_undo_push(C, "Select");
2235  break;
2236 
2237  default:
2238  /* Invalid - unhandled. */
2239  break;
2240  }
2241 
2242  /* wrong notifier still... */
2244 
2245  /* XXX: this is just so that outliner is always up to date. */
2247 
2248  return OPERATOR_FINISHED;
2249 }
2250 
2252 {
2253  /* identifiers */
2254  ot->name = "Outliner ID Data Operation";
2255  ot->idname = "OUTLINER_OT_id_operation";
2256 
2257  /* callbacks */
2261 
2262  ot->flag = 0;
2263 
2264  ot->prop = RNA_def_enum(ot->srna, "type", prop_id_op_types, 0, "ID Data Operation", "");
2266 }
2267 
2270 /* -------------------------------------------------------------------- */
2274 typedef enum eOutlinerLibOpTypes {
2276 
2282 
2284  {OL_LIB_RENAME, "RENAME", 0, "Rename", ""},
2285  {OL_LIB_DELETE,
2286  "DELETE",
2287  ICON_X,
2288  "Delete",
2289  "Delete this library and all its item.\n"
2290  "Warning: No undo"},
2291  {OL_LIB_RELOCATE,
2292  "RELOCATE",
2293  0,
2294  "Relocate",
2295  "Select a new path for this library, and reload all its data"},
2296  {OL_LIB_RELOAD, "RELOAD", ICON_FILE_REFRESH, "Reload", "Reload all data from this library"},
2297  {0, NULL, 0, NULL, NULL},
2298 };
2299 
2301 {
2303  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
2304  int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
2305 
2306  /* check for invalid states */
2307  if (space_outliner == NULL) {
2308  return OPERATOR_CANCELLED;
2309  }
2310 
2311  TreeElement *te = get_target_element(space_outliner);
2312  get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
2313 
2314  eOutlinerLibOpTypes event = RNA_enum_get(op->ptr, "type");
2315  switch (event) {
2316  case OL_LIB_RENAME: {
2318  C, op->reports, scene, space_outliner, &space_outliner->tree, item_rename_fn, NULL);
2319 
2321  ED_undo_push(C, "Rename Library");
2322  break;
2323  }
2324  case OL_LIB_DELETE: {
2326  C, op->reports, scene, space_outliner, &space_outliner->tree, id_delete_fn, NULL);
2327  ED_undo_push(C, "Delete Library");
2328  break;
2329  }
2330  case OL_LIB_RELOCATE: {
2332  C, op->reports, scene, space_outliner, &space_outliner->tree, lib_relocate_fn, NULL);
2333  /* No undo push here, operator does it itself (since it's a modal one, the op_undo_depth
2334  * trick does not work here). */
2335  break;
2336  }
2337  case OL_LIB_RELOAD: {
2339  C, op->reports, scene, space_outliner, &space_outliner->tree, lib_reload_fn, NULL);
2340  /* No undo push here, operator does it itself (since it's a modal one, the op_undo_depth
2341  * trick does not work here). */
2342  break;
2343  }
2344  default:
2345  /* invalid - unhandled */
2346  break;
2347  }
2348 
2349  /* wrong notifier still... */
2351 
2352  /* XXX: this is just so that outliner is always up to date */
2354 
2355  return OPERATOR_FINISHED;
2356 }
2357 
2359 {
2360  /* identifiers */
2361  ot->name = "Outliner Library Operation";
2362  ot->idname = "OUTLINER_OT_lib_operation";
2363 
2364  /* callbacks */
2368 
2369  ot->prop = RNA_def_enum(
2370  ot->srna, "type", outliner_lib_op_type_items, 0, "Library Operation", "");
2371 }
2372 
2375 /* -------------------------------------------------------------------- */
2380  SpaceOutliner *space_outliner,
2381  int type,
2382  ListBase *lb,
2383  ID *newid,
2384  void (*operation_fn)(TreeElement *, TreeStoreElem *, TreeStoreElem *, ID *))
2385 {
2386  LISTBASE_FOREACH (TreeElement *, te, lb) {
2387  TreeStoreElem *tselem = TREESTORE(te);
2388  if (tselem->flag & TSE_SELECTED) {
2389  if (tselem->type == type) {
2390  TreeStoreElem *tsep = te->parent ? TREESTORE(te->parent) : NULL;
2391  operation_fn(te, tselem, tsep, newid);
2392  }
2393  }
2394  if (TSELEM_OPEN(tselem, space_outliner)) {
2395  outliner_do_id_set_operation(space_outliner, type, &te->subtree, newid, operation_fn);
2396  }
2397  }
2398 }
2399 
2401  TreeStoreElem *tselem,
2402  TreeStoreElem *tsep,
2403  ID *actId)
2404 {
2405  bAction *act = (bAction *)actId;
2406 
2407  if (tselem->type == TSE_ANIM_DATA) {
2408  /* "animation" entries - action is child of this */
2409  BKE_animdata_set_action(NULL, tselem->id, act);
2410  }
2411  /* TODO: if any other "expander" channels which own actions need to support this menu,
2412  * add: tselem->type = ...
2413  */
2414  else if (tsep && (tsep->type == TSE_ANIM_DATA)) {
2415  /* "animation" entries case again */
2416  BKE_animdata_set_action(NULL, tsep->id, act);
2417  }
2418  /* TODO: other cases not supported yet. */
2419 }
2420 
2422 {
2423  Main *bmain = CTX_data_main(C);
2424  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
2425  int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
2426  bAction *act;
2427 
2428  TreeElement *te = get_target_element(space_outliner);
2429  get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
2430 
2431  /* get action to use */
2432  act = BLI_findlink(&bmain->actions, RNA_enum_get(op->ptr, "action"));
2433 
2434  if (act == NULL) {
2435  BKE_report(op->reports, RPT_ERROR, "No valid action to add");
2436  return OPERATOR_CANCELLED;
2437  }
2438  if (act->idroot == 0) {
2439  /* Hopefully in this case (i.e. library of userless actions),
2440  * the user knows what they're doing. */
2441  BKE_reportf(op->reports,
2442  RPT_WARNING,
2443  "Action '%s' does not specify what data-blocks it can be used on "
2444  "(try setting the 'ID Root Type' setting from the data-blocks editor "
2445  "for this action to avoid future problems)",
2446  act->id.name + 2);
2447  }
2448 
2449  /* perform action if valid channel */
2450  if (datalevel == TSE_ANIM_DATA) {
2452  space_outliner, datalevel, &space_outliner->tree, (ID *)act, actionset_id_fn);
2453  }
2454  else if (idlevel == ID_AC) {
2456  space_outliner, idlevel, &space_outliner->tree, (ID *)act, actionset_id_fn);
2457  }
2458  else {
2459  return OPERATOR_CANCELLED;
2460  }
2461 
2462  /* set notifier that things have changed */
2464  ED_undo_push(C, "Set action");
2465 
2466  /* done */
2467  return OPERATOR_FINISHED;
2468 }
2469 
2471 {
2472  PropertyRNA *prop;
2473 
2474  /* identifiers */
2475  ot->name = "Outliner Set Action";
2476  ot->idname = "OUTLINER_OT_action_set";
2477  ot->description = "Change the active action used";
2478 
2479  /* api callbacks */
2483 
2484  /* flags */
2486 
2487  /* props */
2488  /* TODO: this would be nicer as an ID-pointer... */
2489  prop = RNA_def_enum(ot->srna, "action", DummyRNA_NULL_items, 0, "Action", "");
2492  ot->prop = prop;
2493 }
2494 
2497 /* -------------------------------------------------------------------- */
2503 
2505 
2508 
2512 
2515  "CLEAR_ANIMDATA",
2516  0,
2517  "Clear Animation Data",
2518  "Remove this animation data container"},
2519  {OUTLINER_ANIMOP_SET_ACT, "SET_ACT", 0, "Set Action", ""},
2520  {OUTLINER_ANIMOP_CLEAR_ACT, "CLEAR_ACT", 0, "Unlink Action", ""},
2521  {OUTLINER_ANIMOP_REFRESH_DRV, "REFRESH_DRIVERS", 0, "Refresh Drivers", ""},
2522  {OUTLINER_ANIMOP_CLEAR_DRV, "CLEAR_DRIVERS", 0, "Clear Drivers", ""},
2523  {0, NULL, 0, NULL, NULL},
2524 };
2525 
2527 {
2529  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
2530  int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
2531  TreeElement *te = get_target_element(space_outliner);
2532  get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
2533 
2534  if (datalevel != TSE_ANIM_DATA) {
2535  return OPERATOR_CANCELLED;
2536  }
2537 
2538  /* perform the core operation */
2539  eOutliner_AnimDataOps event = RNA_enum_get(op->ptr, "type");
2540  switch (event) {
2542  /* Remove Animation Data - this may remove the active action, in some cases... */
2544  space_outliner, datalevel, event, &space_outliner->tree, clear_animdata_fn, NULL);
2545 
2547  ED_undo_push(C, "Clear Animation Data");
2548  break;
2549 
2551  /* delegate once again... */
2552  wm->op_undo_depth++;
2553  WM_operator_name_call(C, "OUTLINER_OT_action_set", WM_OP_INVOKE_REGION_WIN, NULL);
2554  wm->op_undo_depth--;
2555  ED_undo_push(C, "Set active action");
2556  break;
2557 
2559  /* clear active action - using standard rules */
2561  space_outliner, datalevel, event, &space_outliner->tree, unlinkact_animdata_fn, NULL);
2562 
2564  ED_undo_push(C, "Unlink action");
2565  break;
2566 
2568  outliner_do_data_operation(space_outliner,
2569  datalevel,
2570  event,
2571  &space_outliner->tree,
2573  NULL);
2574 
2576  /* ED_undo_push(C, "Refresh Drivers"); No undo needed - shouldn't have any impact? */
2577  break;
2578 
2581  space_outliner, datalevel, event, &space_outliner->tree, cleardrivers_animdata_fn, NULL);
2582 
2584  ED_undo_push(C, "Clear Drivers");
2585  break;
2586 
2587  default: /* Invalid. */
2588  break;
2589  }
2590 
2591  /* update dependencies */
2593 
2594  return OPERATOR_FINISHED;
2595 }
2596 
2598 {
2599  /* identifiers */
2600  ot->name = "Outliner Animation Data Operation";
2601  ot->idname = "OUTLINER_OT_animdata_operation";
2602 
2603  /* callbacks */
2607 
2608  ot->flag = 0;
2609 
2610  ot->prop = RNA_def_enum(ot->srna, "type", prop_animdata_op_types, 0, "Animation Operation", "");
2611 }
2612 
2615 /* -------------------------------------------------------------------- */
2620  {OL_CONSTRAINTOP_ENABLE, "ENABLE", ICON_HIDE_OFF, "Enable", ""},
2621  {OL_CONSTRAINTOP_DISABLE, "DISABLE", ICON_HIDE_ON, "Disable", ""},
2622  {OL_CONSTRAINTOP_DELETE, "DELETE", ICON_X, "Delete", ""},
2623  {0, NULL, 0, NULL, NULL},
2624 };
2625 
2627 {
2628  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
2629  eOutliner_PropConstraintOps event = RNA_enum_get(op->ptr, "type");
2630 
2632  space_outliner, TSE_CONSTRAINT, event, &space_outliner->tree, constraint_fn, C);
2633 
2634  if (event == OL_CONSTRAINTOP_DELETE) {
2635  outliner_cleanup_tree(space_outliner);
2636  }
2637 
2638  ED_undo_push(C, "Constraint operation");
2639 
2640  return OPERATOR_FINISHED;
2641 }
2642 
2644 {
2645  /* identifiers */
2646  ot->name = "Outliner Constraint Operation";
2647  ot->idname = "OUTLINER_OT_constraint_operation";
2648 
2649  /* callbacks */
2653 
2654  ot->flag = 0;
2655 
2656  ot->prop = RNA_def_enum(
2657  ot->srna, "type", prop_constraint_op_types, 0, "Constraint Operation", "");
2658 }
2659 
2662 /* -------------------------------------------------------------------- */
2667  {OL_MODIFIER_OP_TOGVIS, "TOGVIS", ICON_RESTRICT_VIEW_OFF, "Toggle Viewport Use", ""},
2668  {OL_MODIFIER_OP_TOGREN, "TOGREN", ICON_RESTRICT_RENDER_OFF, "Toggle Render Use", ""},
2669  {OL_MODIFIER_OP_DELETE, "DELETE", ICON_X, "Delete", ""},
2670  {0, NULL, 0, NULL, NULL},
2671 };
2672 
2674 {
2675  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
2676  eOutliner_PropModifierOps event = RNA_enum_get(op->ptr, "type");
2677 
2679  space_outliner, TSE_MODIFIER, event, &space_outliner->tree, modifier_fn, C);
2680 
2681  if (event == OL_MODIFIER_OP_DELETE) {
2682  outliner_cleanup_tree(space_outliner);
2683  }
2684 
2685  ED_undo_push(C, "Modifier operation");
2686 
2687  return OPERATOR_FINISHED;
2688 }
2689 
2691 {
2692  /* identifiers */
2693  ot->name = "Outliner Modifier Operation";
2694  ot->idname = "OUTLINER_OT_modifier_operation";
2695 
2696  /* callbacks */
2700 
2701  ot->flag = 0;
2702 
2703  ot->prop = RNA_def_enum(ot->srna, "type", prop_modifier_op_types, 0, "Modifier Operation", "");
2704 }
2705 
2708 /* -------------------------------------------------------------------- */
2712 /* XXX: select linked is for RNA structs only. */
2714  {OL_DOP_SELECT, "SELECT", 0, "Select", ""},
2715  {OL_DOP_DESELECT, "DESELECT", 0, "Deselect", ""},
2716  {OL_DOP_HIDE, "HIDE", 0, "Hide", ""},
2717  {OL_DOP_UNHIDE, "UNHIDE", 0, "Unhide", ""},
2718  {OL_DOP_SELECT_LINKED, "SELECT_LINKED", 0, "Select Linked", ""},
2719  {0, NULL, 0, NULL, NULL},
2720 };
2721 
2723 {
2724  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
2725  int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
2726  TreeElement *te = get_target_element(space_outliner);
2727  get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
2728 
2729  eOutliner_PropDataOps event = RNA_enum_get(op->ptr, "type");
2730  switch (datalevel) {
2731  case TSE_POSE_CHANNEL: {
2733  space_outliner, datalevel, event, &space_outliner->tree, pchan_fn, NULL);
2735  ED_undo_push(C, "PoseChannel operation");
2736 
2737  break;
2738  }
2739  case TSE_BONE: {
2741  space_outliner, datalevel, event, &space_outliner->tree, bone_fn, NULL);
2743  ED_undo_push(C, "Bone operation");
2744 
2745  break;
2746  }
2747  case TSE_EBONE: {
2749  space_outliner, datalevel, event, &space_outliner->tree, ebone_fn, NULL);
2751  ED_undo_push(C, "EditBone operation");
2752 
2753  break;
2754  }
2755  case TSE_SEQUENCE: {
2758  space_outliner, datalevel, event, &space_outliner->tree, sequence_fn, scene);
2759 
2760  break;
2761  }
2762  case TSE_GP_LAYER: {
2764  space_outliner, datalevel, event, &space_outliner->tree, gpencil_layer_fn, NULL);
2766  ED_undo_push(C, "Grease Pencil Layer operation");
2767 
2768  break;
2769  }
2770  case TSE_RNA_STRUCT:
2771  if (event == OL_DOP_SELECT_LINKED) {
2773  space_outliner, datalevel, event, &space_outliner->tree, data_select_linked_fn, C);
2774  }
2775 
2776  break;
2777 
2778  default:
2779  BKE_report(op->reports, RPT_WARNING, "Not yet implemented");
2780  break;
2781  }
2782 
2783  return OPERATOR_FINISHED;
2784 }
2785 
2787 {
2788  /* identifiers */
2789  ot->name = "Outliner Data Operation";
2790  ot->idname = "OUTLINER_OT_data_operation";
2791 
2792  /* callbacks */
2796 
2797  ot->flag = 0;
2798 
2799  ot->prop = RNA_def_enum(ot->srna, "type", prop_data_op_types, 0, "Data Operation", "");
2800 }
2801 
2804 /* -------------------------------------------------------------------- */
2808 static int outliner_operator_menu(bContext *C, const char *opname)
2809 {
2810  wmOperatorType *ot = WM_operatortype_find(opname, false);
2812  uiLayout *layout = UI_popup_menu_layout(pup);
2813 
2814  /* set this so the default execution context is the same as submenus */
2817 
2818  uiItemS(layout);
2819 
2820  uiItemMContents(layout, "OUTLINER_MT_context_menu");
2821 
2822  UI_popup_menu_end(C, pup);
2823 
2824  return OPERATOR_INTERFACE;
2825 }
2826 
2828  ReportList *reports,
2829  ARegion *region,
2830  SpaceOutliner *space_outliner,
2831  TreeElement *te)
2832 {
2833  int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
2834  TreeStoreElem *tselem = TREESTORE(te);
2835 
2836  int select_flag = OL_ITEM_ACTIVATE | OL_ITEM_SELECT;
2837  if (tselem->flag & TSE_SELECTED) {
2838  select_flag |= OL_ITEM_EXTEND;
2839  }
2840 
2841  outliner_item_select(C, space_outliner, te, select_flag);
2842 
2843  /* Only redraw, don't rebuild here because TreeElement pointers will
2844  * become invalid and operations will crash. */
2846  ED_outliner_select_sync_from_outliner(C, space_outliner);
2847 
2848  get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
2849 
2850  if (scenelevel) {
2851  if (objectlevel || datalevel || idlevel) {
2852  BKE_report(reports, RPT_WARNING, "Mixed selection");
2853  return OPERATOR_CANCELLED;
2854  }
2855  return outliner_operator_menu(C, "OUTLINER_OT_scene_operation");
2856  }
2857  if (objectlevel) {
2858  WM_menu_name_call(C, "OUTLINER_MT_object", WM_OP_INVOKE_REGION_WIN);
2859  return OPERATOR_FINISHED;
2860  }
2861  if (idlevel) {
2862  if (idlevel == -1 || datalevel) {
2863  BKE_report(reports, RPT_WARNING, "Mixed selection");
2864  return OPERATOR_CANCELLED;
2865  }
2866 
2867  switch (idlevel) {
2868  case ID_GR:
2869  WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
2870  return OPERATOR_FINISHED;
2871  break;
2872  case ID_LI:
2873  return outliner_operator_menu(C, "OUTLINER_OT_lib_operation");
2874  break;
2875  default:
2876  return outliner_operator_menu(C, "OUTLINER_OT_id_operation");
2877  break;
2878  }
2879  }
2880  else if (datalevel) {
2881  if (datalevel == -1) {
2882  BKE_report(reports, RPT_WARNING, "Mixed selection");
2883  return OPERATOR_CANCELLED;
2884  }
2885  if (datalevel == TSE_ANIM_DATA) {
2886  return outliner_operator_menu(C, "OUTLINER_OT_animdata_operation");
2887  }
2888  if (datalevel == TSE_DRIVER_BASE) {
2889  /* do nothing... no special ops needed yet */
2890  return OPERATOR_CANCELLED;
2891  }
2892  if (datalevel == TSE_LAYER_COLLECTION) {
2893  WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
2894  return OPERATOR_FINISHED;
2895  }
2897  WM_menu_name_call(C, "OUTLINER_MT_collection_new", WM_OP_INVOKE_REGION_WIN);
2898  return OPERATOR_FINISHED;
2899  }
2900  if (datalevel == TSE_ID_BASE) {
2901  /* do nothing... there are no ops needed here yet */
2902  return OPERATOR_CANCELLED;
2903  }
2904  if (datalevel == TSE_CONSTRAINT) {
2905  return outliner_operator_menu(C, "OUTLINER_OT_constraint_operation");
2906  }
2907  if (datalevel == TSE_MODIFIER) {
2908  return outliner_operator_menu(C, "OUTLINER_OT_modifier_operation");
2909  }
2910  return outliner_operator_menu(C, "OUTLINER_OT_data_operation");
2911  }
2912 
2913  return OPERATOR_CANCELLED;
2914 }
2915 
2916 static int outliner_operation(bContext *C, wmOperator *op, const wmEvent *event)
2917 {
2918  ARegion *region = CTX_wm_region(C);
2919  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
2921  float view_mval[2];
2922 
2923  if (but) {
2925  }
2926 
2928  &region->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
2929 
2930  TreeElement *hovered_te = outliner_find_item_at_y(
2931  space_outliner, &space_outliner->tree, view_mval[1]);
2932  if (!hovered_te) {
2933  /* Let this fall through to 'OUTLINER_MT_context_menu'. */
2934  return OPERATOR_PASS_THROUGH;
2935  }
2936 
2937  return do_outliner_operation_event(C, op->reports, region, space_outliner, hovered_te);
2938 }
2939 
2940 /* Menu only! Calls other operators */
2942 {
2943  ot->name = "Context Menu";
2944  ot->idname = "OUTLINER_OT_operation";
2945  ot->description = "Context menu for item operations";
2946 
2948 
2950 }
2951 
bool BKE_animdata_set_action(struct ReportList *reports, struct ID *id, struct bAction *act)
Definition: anim_data.c:150
void BKE_animdata_free(struct ID *id, const bool do_id_user)
Definition: anim_data.c:230
bool BKE_collection_child_remove(struct Main *bmain, struct Collection *parent, struct Collection *child)
Definition: collection.c:1621
bool BKE_scene_collections_object_remove(struct Main *bmain, struct Scene *scene, struct Object *object, const bool free_us)
Definition: collection.c:1243
bool BKE_collection_object_remove(struct Main *bmain, struct Collection *collection, struct Object *object, const bool free_us)
Definition: collection.c:1193
bool BKE_constraint_remove_ex(ListBase *list, struct Object *ob, struct bConstraint *con, bool clear_dep)
Definition: constraint.c:5526
void BKE_constraints_active_set(ListBase *list, struct bConstraint *con)
Definition: constraint.c:5829
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct Object * CTX_data_edit_object(const bContext *C)
Definition: context.c:1296
struct SpaceOutliner * CTX_wm_space_outliner(const bContext *C)
Definition: context.c:836
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct ReportList * CTX_wm_reports(const bContext *C)
Definition: context.c:751
struct wmMsgBus * CTX_wm_message_bus(const bContext *C)
Definition: context.c:746
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
void BKE_fcurves_free(ListBase *list)
Definition: fcurve.c:103
struct Base * BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Object *ob)
Definition: layer.c:394
void id_us_min(struct ID *id)
Definition: lib_id.c:297
void BKE_main_id_tag_all(struct Main *mainvar, const int tag, const bool value)
Definition: lib_id.c:923
void id_fake_user_set(struct ID *id)
Definition: lib_id.c:328
void BKE_main_id_clear_newpoins(struct Main *bmain)
Definition: lib_id.c:1738
bool BKE_lib_id_make_local(struct Main *bmain, struct ID *id, const bool test, const int flags)
Definition: lib_id.c:479
bool id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop)
Definition: lib_id.c:747
bool void BKE_lib_id_clear_library_data(struct Main *bmain, struct ID *id)
Definition: lib_id.c:202
void BKE_id_delete(struct Main *bmain, void *idv) ATTR_NONNULL()
void id_fake_user_clear(struct ID *id)
Definition: lib_id.c:336
size_t BKE_id_multi_tagged_delete(struct Main *bmain) ATTR_NONNULL()
bool BKE_lib_override_library_create(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, struct ID *id_root, struct ID *id_reference)
Definition: lib_override.c:788
struct ID * BKE_lib_override_library_create_from_id(struct Main *bmain, struct ID *reference_id, const bool do_tagged_remap)
Definition: lib_override.c:254
void BKE_lib_override_library_id_hierarchy_reset(struct Main *bmain, struct ID *id_root)
void BKE_lib_override_library_make_local(struct ID *id)
void BKE_lib_override_library_id_reset(struct Main *bmain, struct ID *id_root)
bool BKE_lib_override_library_proxy_convert(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, struct Object *ob_proxy)
Definition: lib_override.c:834
void BKE_lib_override_library_delete(struct Main *bmain, struct ID *id_root)
bool BKE_lib_override_library_resync(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, struct ID *id_root, struct Collection *override_resync_residual_storage, const bool do_hierarchy_enforce, const bool do_post_process)
Definition: lib_override.c:876
bool BKE_library_ID_is_indirectly_used(struct Main *bmain, void *idv)
Definition: lib_query.c:588
#define FOREACH_MAIN_ID_END
Definition: BKE_main.h:250
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition: BKE_main.h:244
General operations, lookup, etc. for blender objects.
bool BKE_object_is_in_editmode(const struct Object *ob)
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
void BKE_reportf(ReportList *reports, ReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert(a)
Definition: BLI_assert.h:58
struct GSet GSet
Definition: BLI_ghash.h:189
GSet * BLI_gset_ptr_new(const char *info)
#define GSET_ITER(gs_iter_, gset_)
Definition: BLI_ghash.h:268
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1253
BLI_INLINE void * BLI_gsetIterator_getKey(GSetIterator *gsi)
Definition: BLI_ghash.h:255
bool BLI_gset_add(GSet *gs, void *key)
Definition: BLI_ghash.c:1160
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
char * BLI_strcasestr(const char *s, const char *find) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:578
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define UNUSED(x)
#define ELEM(...)
#define LIKELY(x)
#define CLOG_WARN(clg_ref,...)
Definition: CLG_log.h:203
void DEG_id_tag_update_ex(struct Main *bmain, struct ID *id, int flag)
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
#define ID_EXTRA_USERS(id)
Definition: DNA_ID.h:414
@ ID_RECALC_TRANSFORM
Definition: DNA_ID.h:599
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:654
@ ID_RECALC_SELECT
Definition: DNA_ID.h:638
@ ID_RECALC_ANIMATION
Definition: DNA_ID.h:614
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
@ ID_RECALC_BASE_FLAGS
Definition: DNA_ID.h:641
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id)
Definition: DNA_ID.h:438
@ LIB_TAG_INDIRECT
Definition: DNA_ID.h:524
@ LIB_TAG_DOIT
Definition: DNA_ID.h:554
@ LIB_TAG_EXTERN
Definition: DNA_ID.h:521
#define ID_IS_OVERRIDABLE_LIBRARY(_id)
Definition: DNA_ID.h:430
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
#define ID_REAL_USERS(id)
Definition: DNA_ID.h:413
ID_Type
Definition: DNA_ID_enums.h:56
@ ID_WM
Definition: DNA_ID_enums.h:84
@ ID_CA
Definition: DNA_ID_enums.h:68
@ ID_AR
Definition: DNA_ID_enums.h:78
@ ID_MC
Definition: DNA_ID_enums.h:85
@ ID_CF
Definition: DNA_ID_enums.h:90
@ ID_LI
Definition: DNA_ID_enums.h:58
@ ID_TE
Definition: DNA_ID_enums.h:64
@ ID_IM
Definition: DNA_ID_enums.h:65
@ ID_VO
Definition: DNA_ID_enums.h:95
@ ID_WS
Definition: DNA_ID_enums.h:91
@ ID_NT
Definition: DNA_ID_enums.h:80
@ ID_LA
Definition: DNA_ID_enums.h:67
@ ID_KE
Definition: DNA_ID_enums.h:70
@ ID_TXT
Definition: DNA_ID_enums.h:74
@ ID_SO
Definition: DNA_ID_enums.h:76
@ ID_SCE
Definition: DNA_ID_enums.h:57
@ ID_LS
Definition: DNA_ID_enums.h:87
@ ID_MSK
Definition: DNA_ID_enums.h:86
@ ID_GD
Definition: DNA_ID_enums.h:83
@ ID_PAL
Definition: DNA_ID_enums.h:88
@ ID_BR
Definition: DNA_ID_enums.h:81
@ ID_LP
Definition: DNA_ID_enums.h:92
@ ID_HA
Definition: DNA_ID_enums.h:93
@ ID_WO
Definition: DNA_ID_enums.h:71
@ ID_SIM
Definition: DNA_ID_enums.h:96
@ ID_MA
Definition: DNA_ID_enums.h:63
@ ID_AC
Definition: DNA_ID_enums.h:79
@ ID_SCR
Definition: DNA_ID_enums.h:72
@ ID_VF
Definition: DNA_ID_enums.h:73
@ ID_ME
Definition: DNA_ID_enums.h:60
@ ID_IP
Definition: DNA_ID_enums.h:69
@ ID_GR
Definition: DNA_ID_enums.h:77
@ ID_SPK
Definition: DNA_ID_enums.h:75
@ ID_MB
Definition: DNA_ID_enums.h:62
@ ID_LT
Definition: DNA_ID_enums.h:66
@ ID_OB
Definition: DNA_ID_enums.h:59
@ ID_PA
Definition: DNA_ID_enums.h:82
@ ID_PT
Definition: DNA_ID_enums.h:94
@ ID_CU
Definition: DNA_ID_enums.h:61
@ ID_PC
Definition: DNA_ID_enums.h:89
#define ID_NLA
Definition: DNA_ID_enums.h:112
@ DRIVER_FLAG_INVALID
@ FCURVE_DISABLED
@ BONE_ROOTSEL
@ BONE_SELECTED
@ BONE_HIDDEN_A
@ BONE_HIDDEN_P
@ BONE_TIPSEL
Object groups, one object can be in many groups at once.
@ CONSTRAINT_OFF
@ GP_LAYER_SELECT
@ GP_LAYER_HIDE
@ BASE_SELECTED
@ eModifierMode_Render
@ eModifierMode_Realtime
@ OB_MODE_EDIT
Object is a sort of wrapper for general info.
@ OB_EMPTY
#define TSE_IS_REAL_ID(_tse)
@ TSE_POSE_CHANNEL
@ TSE_GP_LAYER
@ TSE_SEQUENCE
@ TSE_VIEW_COLLECTION_BASE
@ TSE_ANIM_DATA
@ TSE_EBONE
@ TSE_BONE
@ TSE_CONSTRAINT
@ TSE_SCENE_COLLECTION_BASE
@ TSE_LAYER_COLLECTION
@ TSE_ID_BASE
@ TSE_SOME_ID
@ TSE_DRIVER_BASE
@ TSE_MODIFIER
@ TSE_RNA_STRUCT
@ TSE_SELECTED
@ TSE_ACTIVE
#define BASACT(_view_layer)
@ SO_VIEW_LAYER
@ SO_SCENES
@ OPERATOR_CANCELLED
@ OPERATOR_INTERFACE
@ OPERATOR_FINISHED
@ OPERATOR_PASS_THROUGH
@ RPT_ERROR_INVALID_INPUT
void ED_object_base_select(struct Base *base, eObjectSelect_Mode mode)
Definition: object_select.c:98
@ EM_FREEDATA
Definition: ED_object.h:204
bool ED_object_editmode_exit_ex(struct Main *bmain, struct Scene *scene, struct Object *obedit, int flag)
Definition: object_edit.c:676
void ED_object_constraint_update(struct Main *bmain, struct Object *ob)
bool ED_object_modifier_remove(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, struct ModifierData *md)
bool ED_object_editmode_exit(struct bContext *C, int flag)
Definition: object_edit.c:718
void ED_object_select_linked_by_id(struct bContext *C, struct ID *id)
void ED_object_base_free_and_unlink(struct Main *bmain, struct Scene *scene, struct Object *ob)
Definition: object_add.c:1958
@ BA_SELECT
Definition: ED_object.h:147
void ED_outliner_select_sync_from_all_tag(struct bContext *C)
Definition: outliner_sync.c:80
void ED_outliner_select_sync_from_object_tag(struct bContext *C)
Definition: outliner_sync.c:56
void ED_outliner_select_sync_from_outliner(struct bContext *C, struct SpaceOutliner *space_outliner)
bool ED_scene_delete(struct bContext *C, struct Main *bmain, struct Scene *scene) ATTR_NONNULL()
Definition: scene_edit.c:84
void ED_region_tag_redraw_no_rebuild(struct ARegion *region)
Definition: area.c:686
bool ED_operator_outliner_active(struct bContext *C)
Definition: screen_ops.c:259
void ED_sequencer_select_sequence_single(struct Scene *scene, struct Sequence *seq, bool deselect_all)
void ED_undo_push(struct bContext *C, const char *str)
Definition: ed_undo.c:117
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
StructRNA RNA_AnimData
const EnumPropertyItem * RNA_action_itemf(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, bool *r_free)
@ PROP_ENUM_NO_TRANSLATE
Definition: RNA_types.h:279
@ PROP_SKIP_SAVE
Definition: RNA_types.h:204
#define C
Definition: RandGen.cpp:39
#define MAX_MTEX
Definition: Stroke.h:45
#define UI_UNIT_Y
@ UI_EMBOSS
Definition: UI_interface.h:107
void UI_block_theme_style_set(uiBlock *block, char theme_style)
Definition: interface.c:3547
int UI_searchbox_size_y(void)
void uiLayoutSetOperatorContext(uiLayout *layout, int opcontext)
@ UI_BUT_ACTIVATE_ON_INIT
Definition: UI_interface.h:222
uiBut * uiDefBut(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:4687
void UI_block_bounds_set_popup(uiBlock *block, int addval, const int bounds_offset[2])
Definition: interface.c:598
bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid, int state, const uint8_t name_prefix_offset)
uiBut * UI_context_active_but_get(const struct bContext *C)
struct uiLayout * UI_popup_menu_layout(uiPopupMenu *pup)
void UI_but_tooltip_timer_remove(struct bContext *C, uiBut *but)
void uiItemS(uiLayout *layout)
void UI_but_func_search_set(uiBut *but, uiButSearchCreateFn search_create_fn, uiButSearchUpdateFn search_update_fn, void *arg, const bool free_arg, uiButSearchArgFreeFn search_arg_free_fn, uiButHandleFunc search_exec_fn, void *active)
Definition: interface.c:6613
void UI_popup_block_invoke(struct bContext *C, uiBlockCreateFunc func, void *arg, void(*arg_free)(void *arg))
void uiItemMContents(uiLayout *layout, const char *menuname)
@ UI_BLOCK_SEARCH_MENU
Definition: UI_interface.h:152
@ UI_BLOCK_LOOP
Definition: UI_interface.h:140
@ UI_BLOCK_MOVEMOUSE_QUIT
Definition: UI_interface.h:148
void uiItemsEnumO(uiLayout *layout, const char *opname, const char *propname)
uiBlock * UI_block_begin(const struct bContext *C, struct ARegion *region, const char *name, eUIEmbossType emboss)
void UI_popup_menu_end(struct bContext *C, struct uiPopupMenu *pup)
uiBut * uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, int x, int y, short width, short height, float a1, float a2, const char *tip)
Definition: interface.c:6573
int UI_search_items_find_index(uiSearchItems *items, const char *name)
#define UI_UNIT_X
void UI_block_flag_enable(uiBlock *block, int flag)
Definition: interface.c:6067
@ UI_BTYPE_LABEL
Definition: UI_interface.h:358
@ UI_BLOCK_THEME_STYLE_POPUP
Definition: UI_interface.h:671
void UI_but_flag_enable(uiBut *but, int flag)
Definition: interface.c:6077
uiPopupMenu * UI_popup_menu_begin(struct bContext *C, const char *title, int icon) ATTR_NONNULL()
void UI_view2d_region_to_view(const struct View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
#define ND_WORLD
Definition: WM_types.h:353
#define NC_WINDOW
Definition: WM_types.h:277
#define NC_ID
Definition: WM_types.h:296
#define ND_NLA_ACTCHANGE
Definition: WM_types.h:398
#define ND_OB_ACTIVE
Definition: WM_types.h:340
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define NC_WM
Definition: WM_types.h:276
#define ND_DATA
Definition: WM_types.h:408
#define NC_ANIMATION
Definition: WM_types.h:289
@ WM_OP_INVOKE_REGION_WIN
Definition: WM_types.h:198
@ WM_OP_INVOKE_DEFAULT
Definition: WM_types.h:197
@ WM_OP_EXEC_DEFAULT
Definition: WM_types.h:204
#define ND_DATACHANGED
Definition: WM_types.h:313
#define ND_OB_SELECT
Definition: WM_types.h:342
#define NC_SCENE
Definition: WM_types.h:279
#define ND_LAYER_CONTENT
Definition: WM_types.h:354
#define ND_MODIFIER
Definition: WM_types.h:363
#define ND_POSE
Definition: WM_types.h:359
#define NA_EDITED
Definition: WM_types.h:462
#define ND_CONSTRAINT
Definition: WM_types.h:365
#define NA_REMOVED
Definition: WM_types.h:465
#define NC_GPENCIL
Definition: WM_types.h:300
#define ND_LAYER
Definition: WM_types.h:350
#define ND_OB_SHADING
Definition: WM_types.h:358
#define ND_SPACE_VIEW3D
Definition: WM_types.h:423
#define NC_OBJECT
Definition: WM_types.h:280
#define ND_ANIMCHAN
Definition: WM_types.h:396
#define NC_SPACE
Definition: WM_types.h:293
#define ND_SPACE_OUTLINER
Definition: WM_types.h:422
ATTR_WARN_UNUSED_RESULT const void * element
unsigned int U
Definition: btGjkEpa3.h:78
Scene scene
void * user_data
void * tree
#define str(s)
#define GS(x)
Definition: iris.c:241
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static unsigned a[3]
Definition: RandGen.cpp:92
bool active
all scheduled work for the GPU.
void outliner_collection_delete(bContext *C, Main *bmain, Scene *scene, ReportList *reports, bool hierarchy)
bool outliner_is_collection_tree_element(const TreeElement *te)
int tree_element_id_type_to_index(TreeElement *te)
TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
void id_remap_fn(bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
void lib_reload_fn(bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
void id_delete_fn(bContext *C, ReportList *reports, Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
void item_rename_fn(bContext *C, ReportList *reports, Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
void lib_relocate_fn(bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
@ OL_ITEM_EXTEND
@ OL_ITEM_RECURSIVE
@ OL_ITEM_SELECT
@ OL_ITEM_ACTIVATE
bool outliner_tree_traverse(const SpaceOutliner *space_outliner, ListBase *tree, int filter_te_flag, int filter_tselem_flag, TreeTraversalFunc func, void *customdata)
TreeElement * outliner_find_element_with_flag(const ListBase *lb, short flag)
void outliner_item_select(struct bContext *C, struct SpaceOutliner *space_outliner, struct TreeElement *te, const short select_flag)
#define TREESTORE(a)
void outliner_cleanup_tree(struct SpaceOutliner *space_outliner)
void(* outliner_operation_fn)(struct bContext *C, struct ReportList *, struct Scene *scene, struct TreeElement *, struct TreeStoreElem *, TreeStoreElem *, void *)
TreeElement * outliner_find_item_at_y(const SpaceOutliner *space_outliner, const ListBase *tree, float view_co_y)
struct ID * outliner_search_back(TreeElement *te, short idcode)
#define TSELEM_OPEN(telm, sv)
TreeTraversalAction
@ TRAVERSE_SKIP_CHILDS
@ TRAVERSE_CONTINUE
static void unlink_texture_fn(bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *UNUSED(tselem), void *UNUSED(user_data))
static void outliner_object_delete_fn(bContext *C, ReportList *reports, Scene *scene, Object *ob)
static void id_select_linked_fn(bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
void OUTLINER_OT_object_operation(wmOperatorType *ot)
static void id_local_fn(bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
static int outliner_modifier_operation_exec(bContext *C, wmOperator *op)
eOutliner_PropConstraintOps
@ OL_CONSTRAINTOP_DISABLE
@ OL_CONSTRAINTOP_ENABLE
@ OL_CONSTRAINTOP_DELETE
static void id_override_library_resync_fn(bContext *C, ReportList *UNUSED(reports), Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *user_data)
static void id_override_library_reset_fn(bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *user_data)
static void object_batch_delete_hierarchy_fn(bContext *C, ReportList *reports, Scene *scene, Object *ob)
static int do_outliner_operation_event(bContext *C, ReportList *reports, ARegion *region, SpaceOutliner *space_outliner, TreeElement *te)
static const EnumPropertyItem prop_data_op_types[]
static int outliner_scene_operation_exec(bContext *C, wmOperator *op)
static void ebone_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
static void refreshdrivers_animdata_fn(int UNUSED(event), TreeElement *UNUSED(te), TreeStoreElem *tselem, void *UNUSED(arg))
eOutliner_AnimDataOps
@ OUTLINER_ANIMOP_INVALID
@ OUTLINER_ANIMOP_CLEAR_ADT
@ OUTLINER_ANIMOP_CLEAR_DRV
@ OUTLINER_ANIMOP_REFRESH_DRV
@ OUTLINER_ANIMOP_CLEAR_ACT
@ OUTLINER_ANIMOP_SET_ACT
static int outliner_action_set_exec(bContext *C, wmOperator *op)
static void unlink_material_fn(bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *UNUSED(tselem), void *UNUSED(user_data))
static const EnumPropertyItem prop_object_op_types[]
static void outliner_do_libdata_operation(bContext *C, ReportList *reports, Scene *scene, SpaceOutliner *space_outliner, ListBase *lb, outliner_operation_fn operation_fn, void *user_data)
eOutliner_PropDataOps
@ OL_DOP_HIDE
@ OL_DOP_SELECT_LINKED
@ OL_DOP_SELECT
@ OL_DOP_DESELECT
@ OL_DOP_UNHIDE
static void merged_element_search_exec_fn(struct bContext *C, void *UNUSED(arg1), void *element)
struct MergedSearchData MergedSearchData
static TreeTraversalAction outliner_find_objects_to_delete(TreeElement *te, void *customdata)
static bool outliner_id_operation_item_poll(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), const int enum_value)
static void outliner_do_id_set_operation(SpaceOutliner *space_outliner, int type, ListBase *lb, ID *newid, void(*operation_fn)(TreeElement *, TreeStoreElem *, TreeStoreElem *, ID *))
static void actionset_id_fn(TreeElement *UNUSED(te), TreeStoreElem *tselem, TreeStoreElem *tsep, ID *actId)
static void object_select_fn(bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
static void outliner_do_data_operation(SpaceOutliner *space_outliner, int type, int event, ListBase *lb, void(*operation_fn)(int, TreeElement *, TreeStoreElem *, void *), void *arg)
void OUTLINER_OT_data_operation(wmOperatorType *ot)
static const EnumPropertyItem prop_id_op_types[]
static const EnumPropertyItem * outliner_id_operation_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *prop, bool *r_free)
void OUTLINER_OT_action_set(wmOperatorType *ot)
@ OL_OP_REMAP
@ OL_OP_PROXY_TO_OVERRIDE_CONVERT
@ OL_OP_RENAME
@ OL_OP_SELECT_HIERARCHY
@ OL_OP_SELECT
@ OL_OP_DESELECT
eOutlinerLibOpTypes
@ OL_LIB_RELOAD
@ OL_LIB_DELETE
@ OL_LIB_INVALID
@ OL_LIB_RELOCATE
@ OL_LIB_RENAME
static void merged_element_search_update_fn(const bContext *UNUSED(C), void *data, const char *str, uiSearchItems *items, const bool UNUSED(is_first))
static void data_select_linked_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *C_v)
static int outliner_lib_operation_exec(bContext *C, wmOperator *op)
static void id_fake_user_set_fn(bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
static void pchan_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
void OUTLINER_OT_delete(wmOperatorType *ot)
static TreeElement * get_target_element(SpaceOutliner *space_outliner)
static void get_element_operation_type(TreeElement *te, int *scenelevel, int *objectlevel, int *idlevel, int *datalevel)
static int outliner_delete_exec(bContext *C, wmOperator *op)
void OUTLINER_OT_lib_operation(wmOperatorType *ot)
static void unlinkact_animdata_fn(int UNUSED(event), TreeElement *UNUSED(te), TreeStoreElem *tselem, void *UNUSED(arg))
void OUTLINER_OT_animdata_operation(wmOperatorType *ot)
static void unlink_collection_fn(bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *tsep, TreeStoreElem *tselem, void *UNUSED(user_data))
eOutlinerIdOpTypes
@ OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY
@ OUTLINER_IDOP_SINGLE
@ OUTLINER_IDOP_UNLINK
@ OUTLINER_IDOP_FAKE_ADD
@ OUTLINER_IDOP_SELECT_LINKED
@ OUTLINER_IDOP_OVERRIDE_LIBRARY_PROXY_CONVERT
@ OUTLINER_IDOP_INVALID
@ OUTLINER_IDOP_REMAP
@ OUTLINER_IDOP_FAKE_CLEAR
@ OUTLINER_IDOP_COPY
@ OUTLINER_IDOP_OVERRIDE_LIBRARY_RESYNC_HIERARCHY
@ OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET
@ OUTLINER_IDOP_DELETE
@ OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE
@ OUTLINER_IDOP_OVERRIDE_LIBRARY_DELETE_HIERARCHY
@ OUTLINER_IDOP_CLEAR_ASSET
@ OUTLINER_IDOP_OVERRIDE_LIBRARY_RESYNC_HIERARCHY_ENFORCE
@ OUTLINER_IDOP_PASTE
@ OUTLINER_IDOP_LOCAL
@ OUTLINER_IDOP_RENAME
@ OUTLINER_IDOP_MARK_ASSET
@ OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY
static int outliner_animdata_operation_exec(bContext *C, wmOperator *op)
static const EnumPropertyItem prop_animdata_op_types[]
static void object_deselect_fn(bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
static uiBlock * merged_element_search_menu(bContext *C, ARegion *region, void *data)
void merged_element_search_menu_invoke(bContext *C, TreeElement *parent_te, TreeElement *activate_te)
static void object_select_hierarchy_fn(bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *UNUSED(tselem), void *UNUSED(user_data))
static void id_fake_user_clear_fn(bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
static int outliner_data_operation_exec(bContext *C, wmOperator *op)
static bool outliner_operation_tree_element_poll(bContext *C)
static void modifier_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *Carg)
void outliner_do_object_operation(bContext *C, ReportList *reports, Scene *scene_act, SpaceOutliner *space_outliner, ListBase *lb, outliner_operation_fn operation_fn)
static void outliner_do_object_delete(bContext *C, ReportList *reports, Scene *scene, GSet *objects_to_delete, OutlinerDeleteFunc delete_fn)
static void merged_element_search_fn_recursive(const ListBase *tree, short tselem_type, short type, const char *str, uiSearchItems *items)
static const EnumPropertyItem outliner_lib_op_type_items[]
static void unlink_action_fn(bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *tsep, TreeStoreElem *UNUSED(tselem), void *UNUSED(user_data))
void(* OutlinerDeleteFunc)(bContext *C, ReportList *reports, Scene *scene, Object *ob)
static void singleuser_world_fn(bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *tsep, TreeStoreElem *tselem, void *UNUSED(user_data))
static void unlink_object_fn(bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem, void *UNUSED(user_data))
static const EnumPropertyItem prop_modifier_op_types[]
static void singleuser_action_fn(bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem, void *UNUSED(user_data))
static void id_override_library_create_fn(bContext *C, ReportList *reports, Scene *scene, TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem, void *user_data)
eOutliner_PropModifierOps
@ OL_MODIFIER_OP_TOGVIS
@ OL_MODIFIER_OP_TOGREN
@ OL_MODIFIER_OP_DELETE
static int outliner_constraint_operation_exec(bContext *C, wmOperator *op)
void OUTLINER_OT_scene_operation(wmOperatorType *ot)
void OUTLINER_OT_id_operation(wmOperatorType *ot)
static void constraint_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *C_v)
static void cleardrivers_animdata_fn(int UNUSED(event), TreeElement *UNUSED(te), TreeStoreElem *tselem, void *UNUSED(arg))
static int outliner_object_operation_exec(bContext *C, wmOperator *op)
static bool scene_fn(bContext *C, eOutliner_PropSceneOps event, TreeElement *UNUSED(te), TreeStoreElem *tselem)
static void unlink_world_fn(bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *tsep, TreeStoreElem *tselem, void *UNUSED(user_data))
static void clear_animdata_fn(int UNUSED(event), TreeElement *UNUSED(te), TreeStoreElem *tselem, void *UNUSED(arg))
static void object_proxy_to_override_convert_fn(bContext *C, ReportList *reports, Scene *UNUSED(scene), TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
struct OutlinerLibOverrideData OutlinerLibOverrideData
static CLG_LogRef LOG
void OUTLINER_OT_operation(wmOperatorType *ot)
static void bone_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
static int outliner_operator_menu(bContext *C, const char *opname)
eOutliner_PropSceneOps
@ OL_SCENE_OP_DELETE
void outliner_do_object_operation_ex(bContext *C, ReportList *reports, Scene *scene_act, SpaceOutliner *space_outliner, ListBase *lb, outliner_operation_fn operation_fn, void *user_data, bool recurse_selected)
static void id_override_library_delete_fn(bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
static const EnumPropertyItem prop_scene_op_types[]
static Base * outline_batch_delete_hierarchy(ReportList *reports, Main *bmain, ViewLayer *view_layer, Scene *scene, Base *base)
static int outliner_id_operation_exec(bContext *C, wmOperator *op)
static void sequence_fn(int event, TreeElement *te, TreeStoreElem *tselem, void *scene_ptr)
void OUTLINER_OT_constraint_operation(wmOperatorType *ot)
static bool outliner_do_scene_operation(bContext *C, eOutliner_PropSceneOps event, ListBase *lb, bool(*operation_fn)(bContext *, eOutliner_PropSceneOps, TreeElement *, TreeStoreElem *))
void OUTLINER_OT_modifier_operation(wmOperatorType *ot)
static const EnumPropertyItem prop_constraint_op_types[]
static void gpencil_layer_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
static int outliner_operation(bContext *C, wmOperator *op, const wmEvent *event)
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:122
bool RNA_struct_is_ID(const StructRNA *type)
Definition: rna_access.c:797
const char * RNA_property_identifier(const PropertyRNA *prop)
Definition: rna_access.c:1145
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
void RNA_enum_item_end(EnumPropertyItem **items, int *totitem)
Definition: rna_define.c:4470
void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
Definition: rna_define.c:4416
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
Definition: rna_define.c:3819
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
const EnumPropertyItem DummyRNA_NULL_items[]
Definition: rna_rna.c:40
Editing * SEQ_editing_get(Scene *scene, bool alloc)
Definition: sequencer.c:232
ListBase drivers
struct Base * next
short flag
struct Object * object
struct Material ** mat
short totcol
ListBase * seqbasep
const char * identifier
Definition: RNA_types.h:446
struct MTex * mtex[18]
struct Material ** mat
short totcol
Definition: DNA_ID.h:273
int tag
Definition: DNA_ID.h:292
int us
Definition: DNA_ID.h:293
char name[66]
Definition: DNA_ID.h:283
AnimData * adt
void * first
Definition: DNA_listBase.h:47
struct Tex * tex
Definition: BKE_main.h:116
ListBase actions
Definition: BKE_main.h:169
TreeElement * select_element
TreeElement * parent_element
struct Material ** mat
short totcol
short totcol
struct Material ** mat
struct Collection * instance_collection
struct Material ** mat
struct Object * proxy
struct Object * parent
struct Material ** mat
struct StructRNA * type
Definition: RNA_types.h:51
void * data
Definition: RNA_types.h:52
struct Collection * master_collection
struct World * world
struct TreeElement * parent
ListBase subtree
TreeStoreElem * store_elem
void * directdata
PointerRNA rnaptr
const char * name
ListBase object_bases
short totcol
struct Material ** mat
struct Bone * bone
int mval[2]
Definition: WM_types.h:583
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
PropertyRNA * prop
Definition: WM_types.h:814
struct ReportList * reports
struct PointerRNA * ptr
void WM_menu_name_call(bContext *C, const char *menu_name, short context)
int WM_operator_name_call(bContext *C, const char *opstring, short context, PointerRNA *properties)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition: wm_files.c:3157
wmOperatorType * ot
Definition: wm_files.c:3156
#define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_)
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
const char * WM_operatortype_name(struct wmOperatorType *ot, struct PointerRNA *properties)
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: wm_operators.c:982
int WM_enum_search_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
void WM_window_set_active_scene(Main *bmain, bContext *C, wmWindow *win, Scene *scene)
Definition: wm_window.c:2257