向项目资源管理器上下文菜单提供自定义删除处理程序

Contributing a custom delete handler to the project explorer context menu

在 Eclipse 插件中,我有一个自定义 org.eclipse.ui.navigator.navigatorContent 扩展。我正在尝试提供自定义删除处理程序。以前我使用 org.eclipse.ui.popupMenus 扩展点和 objectContribution/action,但由于 Eclipse bug #329979: [Key Bindings] Support keybinding of objectContributions.

不支持键绑定

我尝试了几种方法:

正在为删除命令定义处理程序

<extension
    point="org.eclipse.ui.handlers">
    <handler
       commandId="org.eclipse.ui.edit.delete"
       class="org.apache.sling.ide.eclipse.ui.actions.JcrNodeDeleteHandler">
       <activeWhen>
           <adapt type="org.apache.sling.ide.eclipse.ui.nav.model.JcrNode"/>
       </activeWhen>
    </handler>
</extension>

正在我的 actionProvider 中注册自定义删除操作

我已经为我的自定义 navigatorContent 注册了一个 actionProvider。

<actionProvider
      class="org.apache.sling.ide.eclipse.ui.nav.PackageExplorerOpenActionProvider"
      id="org.apache.sling.ide.eclipse.ui.nav.actions.OpenActions"
      overrides="org.eclipse.jdt.ui.navigator.actions.OpenActions">
    <enablement>
        <instanceof value="org.apache.sling.ide.eclipse.ui.nav.model.JcrNode"/>
    </enablement>
</actionProvider>

然后在那个 ActionProvider 中我注册了动作

@Override
public void fillActionBars(IActionBars actionBars) {

    actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId() ,deleteAction);
}

None 个产生了预期的效果,所以现在我卡住了。

如何为我的自定义导航器提供删除命令的自定义实现,该导航器也对键绑定做出反应?

更新

我已经能够使用以下方法注册删除命令:

<extension
    point="org.eclipse.ui.menus">
    <menuContribution
       locationURI="popup:org.eclipse.ui.popup.any?after=additions">
       <command
             commandId="org.eclipse.ui.edit.delete"
             icon="icons/ovr16/delete_obj.gif"
             mnemonic="D"
             label="Delete">
             <visibleWhen
                   checkEnabled="false">
                 <iterate ifEmpty="false">
                     <adapt
                           type="org.apache.sling.ide.eclipse.ui.nav.model.JcrNode">
                     </adapt>    
                 </iterate>
             </visibleWhen>
       </command>
    </menuContribution>
</extension>

请务必注意 visibleWhen 条件必须与 handler 声明中的条件匹配。

但是,它并不位于我期望的 'delete' 操作所在的位置,而是位于 'general' 区域,其中有 运行 As contributions 等。这可能是由于popup:org.eclipse.ui.popup.any?after=additionsmenuLocation 值,但我不确定正确的值是多少。

以编程方式注册命令的正确方法是覆盖 fillContextMenu 方法:

@Override
public void fillContextMenu(IMenuManager menu) {

    super.fillContextMenu(menu);
    if ( deleteAction != null ) {
        menu.appendToGroup(ICommonMenuConstants.GROUP_EDIT, renameAction);
    }
}

要以声明方式注册命令,除了删除命令的 handler 之外,还必须注册 menuContribution/command

<extension
    point="org.eclipse.ui.menus">
    <menuContribution
       locationURI="popup:org.eclipse.ui.popup.any?after=group.edit">
       <command
             commandId="org.eclipse.ui.edit.delete"
             icon="icons/ovr16/delete_obj.gif"
             mnemonic="D"
             label="Delete">
             <visibleWhen
                   checkEnabled="false">
                 <iterate ifEmpty="false">
                     <adapt
                           type="org.apache.sling.ide.eclipse.ui.nav.model.JcrNode">
                     </adapt>    
                 </iterate>
             </visibleWhen>
       </command>

    </menuContribution>
</extension>

注意事项:

  1. locationURI 指定 ?after=group.edit。这部分很重要,因为 group.edit 是菜单的 ID,通常包含 delete/copy/paste 操作
  2. visibleWhen 必须与命令中声明的内容完全匹配。我错误地只使用了 adapt 标签,但它必须包含在 iterate 标签内。我似乎记得这是因为 IStructuredSelection 根据标准
  3. 进行了验证

感谢 Rüdiger Herrmann for guiding me towards the right answer. Also see How to add items in popup menu?,它提供了有价值的信息。