如何设置 Eclipse 操作贡献的初始状态
我想要实现的目标是向 IProject 弹出菜单贡献一个操作。 该操作在我的plugin.xml 中是这样定义的:
<extension
point="org.eclipse.ui.popupMenus">
<objectContribution
adaptable="true"
objectClass="org.eclipse.core.resources.IProject"
nameFilter="*"
id="RemoteSync.contribution1">
<action
label="Enable RemoteSync"
class="remotesync.builder.ToggleNatureAction"
menubarPath="additions"
enablesFor="1"
id="RemoteSync.addRemoveNatureAction"
style="toggle">
</action>
</objectContribution>
</extension>
在 run() 上,我执行 setPersistentProperty() 来保存菜单切换状态,并且我想稍后在插件启动时或每当弹出菜单显示时恢复该状态setActivePart()。
以下是相关的代码片段:
public void run(IAction action) {
if (selection instanceof IStructuredSelection) {
for (Iterator it = ((IStructuredSelection) selection).iterator(); it
.hasNext();) {
Object element = it.next();
IProject project = null;
if (element instanceof IProject) {
project = (IProject) element;
} else if (element instanceof IAdaptable) {
project = (IProject) ((IAdaptable) element)
.getAdapter(IProject.class);
}
if (project != null) {
toggleNature(project);
try {
((IResource) project).setPersistentProperty(
new QualifiedName("", ENABLED_PROPERTY), new Boolean(action.isChecked()).toString());
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
if (selection instanceof IStructuredSelection) {
for (Iterator it = ((IStructuredSelection) selection).iterator(); it
.hasNext();) {
Object element = it.next();
IProject project = null;
if (element instanceof IProject) {
project = (IProject) element;
} else if (element instanceof IAdaptable) {
project = (IProject) ((IAdaptable) element)
.getAdapter(IProject.class);
}
if (project != null) {
toggleNature(project);
try {
String status = ((IResource) project).getPersistentProperty(
new QualifiedName("", ENABLED_PROPERTY));
action.setChecked(new Boolean(status));
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
一切都按预期工作,但有一件事 - 首次激活 IProject 上下文菜单时,它不会反映保存的状态,但如果我再次调出菜单,它会按预期显示保存的状态。然后,如果我调出另一个项目的菜单,它会再次显示错误的状态,但第二次工作正常。
What I'm trying to achieve is to contribute an action to the IProject pop up menu.
The action is defined like this in my plugin.xml:
<extension
point="org.eclipse.ui.popupMenus">
<objectContribution
adaptable="true"
objectClass="org.eclipse.core.resources.IProject"
nameFilter="*"
id="RemoteSync.contribution1">
<action
label="Enable RemoteSync"
class="remotesync.builder.ToggleNatureAction"
menubarPath="additions"
enablesFor="1"
id="RemoteSync.addRemoveNatureAction"
style="toggle">
</action>
</objectContribution>
</extension>
On run() I do setPersistentProperty() in order to save the menu toggle state and I want to restore that later when the plug in starts or whenever the pop up menu is displayed on setActivePart().
Here are the relevant pieces of code:
public void run(IAction action) {
if (selection instanceof IStructuredSelection) {
for (Iterator it = ((IStructuredSelection) selection).iterator(); it
.hasNext();) {
Object element = it.next();
IProject project = null;
if (element instanceof IProject) {
project = (IProject) element;
} else if (element instanceof IAdaptable) {
project = (IProject) ((IAdaptable) element)
.getAdapter(IProject.class);
}
if (project != null) {
toggleNature(project);
try {
((IResource) project).setPersistentProperty(
new QualifiedName("", ENABLED_PROPERTY), new Boolean(action.isChecked()).toString());
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
if (selection instanceof IStructuredSelection) {
for (Iterator it = ((IStructuredSelection) selection).iterator(); it
.hasNext();) {
Object element = it.next();
IProject project = null;
if (element instanceof IProject) {
project = (IProject) element;
} else if (element instanceof IAdaptable) {
project = (IProject) ((IAdaptable) element)
.getAdapter(IProject.class);
}
if (project != null) {
toggleNature(project);
try {
String status = ((IResource) project).getPersistentProperty(
new QualifiedName("", ENABLED_PROPERTY));
action.setChecked(new Boolean(status));
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Everything works as expected but one thing - when the IProject context menu is first activated it does not reflect the saved state, but if I bring the menu up again it shows the saved state as expected. Then if I bring the menu up for another project it once again shows with incorrect state, but the second time works fine.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,看看这些
行变量“project”指向所选项目,因此状态仅存储在其元数据中。如果您想存储独立于项目的状态,解决方案可能是将它们存储在工作区元数据中。
well, take a look at these lines
The variable 'project' points to the selected project and therefore the state is only stored in its meta data. if you want to store the state independant of the project, a solution might be storing them in the workspace metadata.
好吧,似乎我的代码或 Eclipse 3.6 I20100608-0911 中的错误/功能存在问题,这会阻止您第一次单击资源(在我的情况下为 IProject)时正确触发选择更改():
正如我发现的事件是第一次调出上下文菜单时按以下顺序触发:
第一次传递给 SelectionChanged() 的 ISelection 始终是“空选择”。
第一次之后,引入上下文菜单会产生以下事件触发顺序:
这就是为什么我们每次在 setActivePart() 内都应该触发 SelectionChanged() 以确保我们获得最新的选择:
我希望对某人有帮助;)
Well, it seems there is either a problem with my code or bug/feature in Eclipse 3.6 I20100608-0911 which prevents selectionChanged() from firing properly the first time you click on resource (IProject in my case):
As I found out events are fired in this order when bringing up the context menu for the first time:
The ISelection passed to selectionChanged() the first time is always "empty selection".
After the first time, bringing the context menu yields the following order in which events are fired:
That's why we should fire selectionChanged() every time inside setActivePart() in order to make sure we get the most recent selection:
I hope that helps someone ;)