在Common Navigator Framework 实践(二)菜单扩展中实现了对自定义导航菜单,菜单中基本使用了自定义菜单项,对于一个面向文件资源管理的导航,资源的新建、复制、粘贴、删除等操作是很常见的,但是现在的导航却没有。
目标
给自定义导航添加新建、复制、粘贴、删除等常见操作。
分析
Eclipse 原本是支持这些操作的,也就是它以前已经做了实现,因此可以直接引用那些实现。
引用有多种方式,可以按需使用
- 在自定义的ActionProvider 中引用类,通过代码的方式使用已实现功能。这种方式比较灵活,也比较容易实现,也容易个性化扩展。
- 在plugin.xml 中引用,这种引用是指重新定义一个ActionProvider,其class属性值填Eclipse中已实现的类的全路径,ID写一个自己项目的全新唯一ID。这种方式适合与业务需求与Eclipse实现完全一致的情况,比较少。
- 在plugin.xml中重新定义一个ActionProvider,通过复制精简、继承、属性引用等方式创造一个新的类,并以这个类作为class属性。这种方式适合对Eclipse提供的功能需要增减的情况,目的就是为了少造轮子。
以下将采用后面的两种方式实现本文目标。
实现
一、编辑组(复制、粘贴、删除)
在Eclipse中有一个group.edit
组,包含复制、粘贴、删除操作,其实现类是org.eclipse.ui.internal.navigator.resources.actions.EditActionProvider
。
使用第二种方式实现该功能。
1 在popupMenu
中添加组<insertionPoint name="group.edit" separator="true"/>
2 在扩展点org.eclipse.ui.navigator.navigatorContent
下新建actionProvider
,其class属性使用org.eclipse.ui.internal.navigator.resources.actions.EditActionProvider
,id取值为com.xzbd.actions.EditActions
<!-- 编辑按钮组 -->
<actionProvider
class="org.eclipse.ui.internal.navigator.resources.actions.EditActionProvider"
id="com.xzbd.actions.EditActions">
<enablement>
<or>
<instanceof value="org.eclipse.core.resources.IResource" />
<instanceof value="org.eclipse.core.resources.IFolder" />
<instanceof value="org.eclipse.core.resources.IFile" />
</or>
</enablement>
</actionProvider>
二、新建组
Eclipse 原生新建组包含Project、File、Folder、Example、Other…等子菜单。
现设定新建组只需要File和Folder。
这种情况适合第三种扩展方法。Eclipse 提供的新建组内容比较多,因此需要精简。可以通过复制这个类的副本,并去掉其中不要的内容,只保留文件夹和文件的新建功能即可。
1 在popupMenu
中添加组<insertionPoint name="group.new" separator="true"/>
2 在扩展点org.eclipse.ui.navigator.navigatorContent
下新建actionProvider
,其内容如下。
<!-- 新建按钮组 -->
<actionProvider
class="com.xzbd.navigator.provider.NewActionProvider"
id="com.xzbd.actions.NewActions">
<enablement>
<or>
<adapt type="org.eclipse.core.resources.IResource" />
<adapt type="java.util.Collection">
<count value="0" />
</adapt>
</or>
</enablement>
</actionProvider>
3 类com.xzbd.navigator.provider.NewActionProvider
的代码
package com.xzbd.navigator.provider;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.navigator.resources.plugin.WorkbenchNavigatorMessages;
import org.eclipse.ui.navigator.CommonActionProvider;
import org.eclipse.ui.navigator.ICommonActionExtensionSite;
import org.eclipse.ui.navigator.ICommonMenuConstants;
import org.eclipse.ui.navigator.ICommonViewerWorkbenchSite;
import org.eclipse.ui.navigator.WizardActionGroup;
/**
* Provides the new (artifact creation) menu options for a context menu.
*
* <p>
* The added submenu has the following structure
* </p>
*
* <ul>
* <li>a new generic project wizard shortcut action, </li>
* <li>a separator, </li>
* <li>a set of context senstive wizard shortcuts (as defined by
* <b>org.eclipse.ui.navigator.commonWizard</b>), </li>
* <li>another separator, </li>
* <li>a generic examples wizard shortcut action, and finally </li>
* <li>a generic "Other" new wizard shortcut action</li>
* </ul>
*
* @since 3.2
*
*/
@SuppressWarnings("restriction")
public class NewActionProvider extends CommonActionProvider {
private static final String NEW_MENU_NAME = "common.new.menu";//$NON-NLS-1$
private WizardActionGroup newWizardActionGroup;
private boolean contribute = false;
@Override
public void init(ICommonActionExtensionSite anExtensionSite) {
if (anExtensionSite.getViewSite() instanceof ICommonViewerWorkbenchSite) {
IWorkbenchWindow window = ((ICommonViewerWorkbenchSite) anExtensionSite.getViewSite()).getWorkbenchWindow();
newWizardActionGroup = new WizardActionGroup(window, PlatformUI.getWorkbench().getNewWizardRegistry(), WizardActionGroup.TYPE_NEW, anExtensionSite.getContentService());
contribute = true;
}
}
/**
* Adds a submenu to the given menu with the name "group.new" see
* {@link ICommonMenuConstants#GROUP_NEW}). The submenu contains the following structure:
*
* <ul>
* <li>a new generic project wizard shortcut action, </li>
* <li>a separator, </li>
* <li>a set of context senstive wizard shortcuts (as defined by
* <b>org.eclipse.ui.navigator.commonWizard</b>), </li>
* <li>another separator, </li>
* <li>a generic examples wizard shortcut action, and finally </li>
* <li>a generic "Other" new wizard shortcut action</li>
* </ul>
*/
@Override
public void fillContextMenu(IMenuManager menu) {
IMenuManager submenu = new MenuManager(
WorkbenchNavigatorMessages.NewActionProvider_NewMenu_label,
NEW_MENU_NAME);
if(!contribute) {
return;
}
// fill the menu from the commonWizard contributions
newWizardActionGroup.setContext(getContext());
newWizardActionGroup.fillContextMenu(submenu);
submenu.add(new Separator(ICommonMenuConstants.GROUP_ADDITIONS));
// append the submenu after the GROUP_NEW group.
menu.insertAfter(ICommonMenuConstants.GROUP_NEW, submenu);
}
}
4 定义文件、文件夹新建向导
<commonWizard
type="new"
wizardId="org.eclipse.ui.wizards.new.folder">
<enablement>
<or>
<adapt type="org.eclipse.core.resources.IFile" />
<adapt type="org.eclipse.core.resources.IFolder" />
<adapt type="org.eclipse.core.resources.IProject" />
<adapt type="org.eclipse.core.resources.IWorkspaceRoot" />
</or>
</enablement>
</commonWizard>
<commonWizard
type="new"
wizardId="org.eclipse.ui.wizards.new.file">
<enablement>
<or>
<adapt type="org.eclipse.core.resources.IFile" />
<adapt type="org.eclipse.core.resources.IFolder" />
<adapt type="org.eclipse.core.resources.IProject" />
<adapt type="org.eclipse.core.resources.IWorkspaceRoot" />
</or>
</enablement>
</commonWizard>
注意
- 以上依然拷贝自Eclipse的实现。
- 这属性
commonWizard
功能实现,如果业务需要其他新建向导功能加到group.new
组,可以仿照以上两个实现。 - 如果
viewerContentBinding
中包含了org.eclipse.ui.navigator.resourceContent
,则以上定义可以不用重写。
因为刚定义的两个ActionProvider的ID刚好都满足 com.xzbd.actions.*
表达式,因此它们其实已经绑定到 导航视图。
效果展示
启动运行,效果如下
上图中增加了新建菜单组New(File、Folder),及编辑组(Copy、Paste、Delete)。可以发现新建组中没有 Project、Examples 、Other等子菜单项。
系列文章
CNF系列汇总
Common Navigator Framework 实践(一)自定义导航
Common Navigator Framework 实践(二)菜单扩展
Common Navigator Framework 实践(三)文件拖拽控制
Common Navigator Framework 实践(四)文件过滤
Common Navigator Framework 实践(五)菜单及工具条定制