启用“显示在”>“系统资源管理器”的条件是什么?
What are the conditions for Show In > System Explorer to be enabled?
我们正在开发一个 eclipse 插件来帮助管理客户站点的产品套件。
此插件包含多个视图,我们通过 'Show In' 菜单在它们之间建立了链接机制。由于客户站点可能有多个许可证在使用,我们有一个实现 IShowInTarget
的 LicenseDetail
视图,因此我们可以利用 'Show In' 菜单快速识别软件实例的许可证并获得它的信息。
除生成的 'Show In' 菜单还包含禁用的 'System Explorer' 条目外,所有这些都很好用。在大多数情况下,这很好,但 InstanceExplorer
视图还包含实例主目录的项目,尽管有人可能认为它应该可用,但仍未启用该条目。
首先我假设它是禁用的,因为我们的InstanceExplorer
提供的ShowInContext
在其选择中有专有接口不适用于IResource
。然而,一些调试显示尝试在这样的文件夹源上执行 'Show In (License Detail)' 最终会导致 LicenseDetail#show
返回 false
,但 'Show In' 菜单中的条目仍处于启用状态。查看底层实现证实了这一点。
// excerpt of 'org.eclipse.ui.internal.ShowInHandler#execute'
try {
IViewPart view = page.showView(targetId);
IShowInTarget target = getShowInTarget(view);
if (!(target != null && target.show(context)) {
// this is the only location where the return value of 'ShowInTarget#show' is used
page.getWorkbenchWindow().getShell().getDisplay().beep();
}
((WorkbenchPage) page).performedShowIn(targetId);
} catch (PartInitException e) {
throw new ExecutionException("Failed to show in", e);
}
因此我看不出有什么办法可以通过ShowInContext
的内容来判断菜单项的启用状态。那么 'System Explorer' 的菜单条目如何确定这一点,我该如何利用它?
工作观点摘录类
除其他外,该插件包含一个视图,用于跟踪系统上可用的实例,类似于 egit 的 'Repostitory View'。此视图实现 IShowInSource
并将 'Show In' 菜单添加到其弹出菜单。
public class InstanceExplorer extends ViewPart implements IShowInSource {
@Override
public void createPartControl(Composite parent) {
mMainViewer = InstanceExplorerViewerFactory.createViewer(parent);
// omitted further viewer customization
MenuManager contextMenu = new MenuManager();
contextMenu.setRemoveAllWhenShown(true);
contextMenu.addMenuListener(this::fillContextMenu);
mMainViewer.getControl().setMenu(contextMenu.createContextMenu(mMainViewer.getControl());
getSite().registerContextMenu(contextMenu, mMainViewer);
}
private void fillContextMenu(IMenuManager menu) {
// omitted other context menu entries
MenuManager showInMenu = new MenuManager("Show In");
showInMenu.setActionDefinitionId("org.eclipse.ui.navigate.showInQuickMenu");
menu.add(showInMenu);
showInMenu.add(ContributionItemFactory.VIEWS_SHOW_IN.create(getSite().getWorkbenchWindow()));
}
@Override
public void setFocus() {
mMainViewer.getControl().setFocus();
}
@Override
public ShowInContext getShowInContext() {
return new ShowInContext(mMainViewer.getInput(), mMainViewer.getSelection());
}
private TreeViewer mMainViewer;
}
此外,它还包含一个显示有关产品许可证信息的视图。由于客户站点可能有多个许可证在使用,它实现了IShowInTarget
,因此我们可以利用'Show In'菜单快速识别实例的许可证并获取其信息。
public class LicenseDetail extends ViewPart implements IShowInTarget {
@Override
public void createPartControl(Composite parent) {
mMainViewer = LicenseDetailViewerFactory.createViewer(parent);
// omitted further viewer customization
}
@Override
public void setFocus() {
mMainViewer.getControl().setFocus();
}
@Override
public boolean show(ShowInContext context) {
// LicenseInfo is a proprietary interface, modelling a license of our product
LicenseInfo input = null;
if (context.getSelection() instanceof IStructuredSelection) {
input = findInput(((IStructuredSelection)context.getSelection()).getFirstElement());
}
if (null == input) {
input = findInput(context.getInput());
}
if (null != input) {
setInput(LicenseDetailViewerFactory.getInputs(input));
return true;
}
return false;
}
private void setInput(Object input) {
mMainViewer.setInput(input);
// omitted: determines enabled states for actions and controls based on the new input
validate();
}
private TreeViewer mMainViewer;
}
最后,LicenseDetail
视图在我们的透视工厂中被声明为 'Show In' 目标。
public class PerspectiveFactory implements IPerspectiveFactory {
@Override
public void createInitialLayout(IPageLayout layout) {
// omitted page layout and shortcuts and more
layout.addShowInPart("com.spell.moreen.suite.licenseDetail");
}
}
为了完成,plugin.xml
文件。
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<!-- omitted other extensions provided by the plugin -->
<extension point="org.eclipse.ui.perspectives">
<perspective
class="com.spell.moreen.suite.gui.PerspectiveFactory"
id="com.spell.moreen.suite.main"
name="moreen Suite" />
</extension>
<extension point="org.eclipse.ui.views">
<view
class="com.spell.moreen.suite.gui.part.InstanceExplorer"
id="com.spell.moreen.suite.instanceExplorer"
name="Instance Explorer"
restorable="true" />
<view
class="com.spell.moreen.suite.gui.part.LicenseDetail"
id="com.spell.moreen.suite.licenseDetail"
name="License Detail"
restorable="true" />
</extension>
</plugin>
在系统资源管理器中显示在 org.eclipse.ui.ide
plugin.xml 中定义,并受此表达式控制:
<extension
point="org.eclipse.core.expressions.definitions">
<definition
id="org.eclipse.ui.ide.showInDefinition">
<or>
<with variable="selection">
<count value="1" />
<iterate ifEmpty="false">
<adapt type="org.eclipse.core.resources.IResource" />
</iterate>
</with>
<with
variable="activePart">
<test
property="org.eclipse.ui.ide.editor.input">
</test>
</with>
<with
variable="activeShell">
<test
property="org.eclipse.ui.ide.page.activePreferencePage"
value="org.eclipse.ui.internal.ide.dialogs.ResourceInfoPage">
</test>
</with>
</or>
</definition>
</extension>
这允许三种可能性:
当前选择是一个IResource
或者可以“适应”一个(文件、文件夹、项目)
活动部分org.eclipse.ui.ide.editor.input
测试returns正确。此测试器 returns 适用于具有 IFileEditorInput
或其他可以“适应”IResource
的编辑器
资源信息 属性 页面处于活动状态(由该页面上的按钮使用)
代码中实际显示的是org.eclipse.ui.internal.ide.handlers.ShowInSystemExplorerHandler
。查看源代码,它只有在找到 IResource
.
时才会起作用
我们正在开发一个 eclipse 插件来帮助管理客户站点的产品套件。
此插件包含多个视图,我们通过 'Show In' 菜单在它们之间建立了链接机制。由于客户站点可能有多个许可证在使用,我们有一个实现 IShowInTarget
的 LicenseDetail
视图,因此我们可以利用 'Show In' 菜单快速识别软件实例的许可证并获得它的信息。
除生成的 'Show In' 菜单还包含禁用的 'System Explorer' 条目外,所有这些都很好用。在大多数情况下,这很好,但 InstanceExplorer
视图还包含实例主目录的项目,尽管有人可能认为它应该可用,但仍未启用该条目。
首先我假设它是禁用的,因为我们的InstanceExplorer
提供的ShowInContext
在其选择中有专有接口不适用于IResource
。然而,一些调试显示尝试在这样的文件夹源上执行 'Show In (License Detail)' 最终会导致 LicenseDetail#show
返回 false
,但 'Show In' 菜单中的条目仍处于启用状态。查看底层实现证实了这一点。
// excerpt of 'org.eclipse.ui.internal.ShowInHandler#execute'
try {
IViewPart view = page.showView(targetId);
IShowInTarget target = getShowInTarget(view);
if (!(target != null && target.show(context)) {
// this is the only location where the return value of 'ShowInTarget#show' is used
page.getWorkbenchWindow().getShell().getDisplay().beep();
}
((WorkbenchPage) page).performedShowIn(targetId);
} catch (PartInitException e) {
throw new ExecutionException("Failed to show in", e);
}
因此我看不出有什么办法可以通过ShowInContext
的内容来判断菜单项的启用状态。那么 'System Explorer' 的菜单条目如何确定这一点,我该如何利用它?
工作观点摘录类
除其他外,该插件包含一个视图,用于跟踪系统上可用的实例,类似于 egit 的 'Repostitory View'。此视图实现 IShowInSource
并将 'Show In' 菜单添加到其弹出菜单。
public class InstanceExplorer extends ViewPart implements IShowInSource {
@Override
public void createPartControl(Composite parent) {
mMainViewer = InstanceExplorerViewerFactory.createViewer(parent);
// omitted further viewer customization
MenuManager contextMenu = new MenuManager();
contextMenu.setRemoveAllWhenShown(true);
contextMenu.addMenuListener(this::fillContextMenu);
mMainViewer.getControl().setMenu(contextMenu.createContextMenu(mMainViewer.getControl());
getSite().registerContextMenu(contextMenu, mMainViewer);
}
private void fillContextMenu(IMenuManager menu) {
// omitted other context menu entries
MenuManager showInMenu = new MenuManager("Show In");
showInMenu.setActionDefinitionId("org.eclipse.ui.navigate.showInQuickMenu");
menu.add(showInMenu);
showInMenu.add(ContributionItemFactory.VIEWS_SHOW_IN.create(getSite().getWorkbenchWindow()));
}
@Override
public void setFocus() {
mMainViewer.getControl().setFocus();
}
@Override
public ShowInContext getShowInContext() {
return new ShowInContext(mMainViewer.getInput(), mMainViewer.getSelection());
}
private TreeViewer mMainViewer;
}
此外,它还包含一个显示有关产品许可证信息的视图。由于客户站点可能有多个许可证在使用,它实现了IShowInTarget
,因此我们可以利用'Show In'菜单快速识别实例的许可证并获取其信息。
public class LicenseDetail extends ViewPart implements IShowInTarget {
@Override
public void createPartControl(Composite parent) {
mMainViewer = LicenseDetailViewerFactory.createViewer(parent);
// omitted further viewer customization
}
@Override
public void setFocus() {
mMainViewer.getControl().setFocus();
}
@Override
public boolean show(ShowInContext context) {
// LicenseInfo is a proprietary interface, modelling a license of our product
LicenseInfo input = null;
if (context.getSelection() instanceof IStructuredSelection) {
input = findInput(((IStructuredSelection)context.getSelection()).getFirstElement());
}
if (null == input) {
input = findInput(context.getInput());
}
if (null != input) {
setInput(LicenseDetailViewerFactory.getInputs(input));
return true;
}
return false;
}
private void setInput(Object input) {
mMainViewer.setInput(input);
// omitted: determines enabled states for actions and controls based on the new input
validate();
}
private TreeViewer mMainViewer;
}
最后,LicenseDetail
视图在我们的透视工厂中被声明为 'Show In' 目标。
public class PerspectiveFactory implements IPerspectiveFactory {
@Override
public void createInitialLayout(IPageLayout layout) {
// omitted page layout and shortcuts and more
layout.addShowInPart("com.spell.moreen.suite.licenseDetail");
}
}
为了完成,plugin.xml
文件。
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<!-- omitted other extensions provided by the plugin -->
<extension point="org.eclipse.ui.perspectives">
<perspective
class="com.spell.moreen.suite.gui.PerspectiveFactory"
id="com.spell.moreen.suite.main"
name="moreen Suite" />
</extension>
<extension point="org.eclipse.ui.views">
<view
class="com.spell.moreen.suite.gui.part.InstanceExplorer"
id="com.spell.moreen.suite.instanceExplorer"
name="Instance Explorer"
restorable="true" />
<view
class="com.spell.moreen.suite.gui.part.LicenseDetail"
id="com.spell.moreen.suite.licenseDetail"
name="License Detail"
restorable="true" />
</extension>
</plugin>
在系统资源管理器中显示在 org.eclipse.ui.ide
plugin.xml 中定义,并受此表达式控制:
<extension
point="org.eclipse.core.expressions.definitions">
<definition
id="org.eclipse.ui.ide.showInDefinition">
<or>
<with variable="selection">
<count value="1" />
<iterate ifEmpty="false">
<adapt type="org.eclipse.core.resources.IResource" />
</iterate>
</with>
<with
variable="activePart">
<test
property="org.eclipse.ui.ide.editor.input">
</test>
</with>
<with
variable="activeShell">
<test
property="org.eclipse.ui.ide.page.activePreferencePage"
value="org.eclipse.ui.internal.ide.dialogs.ResourceInfoPage">
</test>
</with>
</or>
</definition>
</extension>
这允许三种可能性:
当前选择是一个
IResource
或者可以“适应”一个(文件、文件夹、项目)活动部分
的编辑器org.eclipse.ui.ide.editor.input
测试returns正确。此测试器 returns 适用于具有IFileEditorInput
或其他可以“适应”IResource
资源信息 属性 页面处于活动状态(由该页面上的按钮使用)
代码中实际显示的是org.eclipse.ui.internal.ide.handlers.ShowInSystemExplorerHandler
。查看源代码,它只有在找到 IResource
.