How can I retrieve the currently selected or active item in the Outliner?

I’m adding custom entries to the Outliner’s context menu. Now I’d like to operate on the collection that is selected in the outliner underneath the cursor, but I’m struggling to find something like context.selected_items. context.collection gives me the active collection, but if the collection I have clicked on is excluded from the scene, context.collection will give me a completely different collection instead (the last active one or the master collection). Also I can not distinguish via Python if the context menu was opened with an object selected or a collection selected.

Is there something implemented in the Python API like this?

1 Like

https://docs.blender.org/api/master/bpy.context.html#bpy.context.selected_objects
This should be it.

Thanks for pointing towards the documentation. This partially revealed that what I am looking for does not exist in the Python API. I’d like to get the selected item in the outliner window, not in the scene.

Digging further in the source code of Blender, I found that outliner_tools.c from within source/blender/editors/space_outliner is calling the various Python menus defined in release/scripts/startup/bl_ui/space_outliner.py. So the checking of the selected data type in the outliner is done in C code, which then calls different Python context menus, like this:

if (scenelevel) {
  if (objectlevel || datalevel || idlevel) {
    BKE_report(reports, RPT_WARNING, "Mixed selection");
    return OPERATOR_CANCELLED;
  }
  else {
    return outliner_operator_menu(C, "OUTLINER_OT_scene_operation");
  }
}
else if (objectlevel) {
  WM_menu_name_call(C, "OUTLINER_MT_object", WM_OP_INVOKE_REGION_WIN);
  return OPERATOR_FINISHED;
}
else if (idlevel) {
  if (idlevel == -1 || datalevel) {
    BKE_report(reports, RPT_WARNING, "Mixed selection");
    return OPERATOR_CANCELLED;
  }
  else {
    switch (idlevel) {
      case ID_GR:
        WM_menu_name_call(C, "OUTLINER_MT_collection", WM_OP_INVOKE_REGION_WIN);
        return OPERATOR_FINISHED;
        break;
      case ID_LI:
        return outliner_operator_menu(C, "OUTLINER_OT_lib_operation");
        break;
      default:
        return outliner_operator_menu(C, "OUTLINER_OT_id_operation");
        break;
    }
  }
}

This leads me to the idea to append my draw function to the corresponding Outliner menu types instead (so if I want to operate on a collection, I append my operator to the draw function of OUTLINER_MT_collection, if I want to work on an object, I append to OUTLINER_MT_object instead). That should do what I want.

The outliner is being worked afaik. I think there were ideas floating around where outliner and viewport selection become the same thing or are linked in some way. But at least 2.81 or later.

More info here:

1 Like

Correct, linking selections between the viewport and the outliner, as well as other features for the outliner are currently in development.

The link you have provided is for the active discussion and development of the GSoC: 2019 Outliner.

Hi there!
Is it still impossible to retrieve the selected item?
How are we supposed to add our custom context menu action then?

Thanks!

2 Likes