如何设置 Eclipse 操作贡献的初始状态

发布于 2024-09-13 09:44:35 字数 3069 浏览 2 评论 0原文

我想要实现的目标是向 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

貪欢 2024-09-20 09:44:35

好吧,看看这些

            String status = ((IResource) project).getPersistentProperty(
                        new QualifiedName("", ENABLED_PROPERTY));

      ((IResource) project).setPersistentProperty(
                        new QualifiedName("", ENABLED_PROPERTY), new Boolean(action.isChecked()).toString());

行变量“project”指向所选项目,因此状态仅存储在其元数据中。如果您想存储独立于项目的状态,解决方案可能是将它们存储在工作区元数据中。

well, take a look at these lines

            String status = ((IResource) project).getPersistentProperty(
                        new QualifiedName("", ENABLED_PROPERTY));

      ((IResource) project).setPersistentProperty(
                        new QualifiedName("", ENABLED_PROPERTY), new Boolean(action.isChecked()).toString());

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.

彩虹直至黑白 2024-09-20 09:44:35

好吧,似乎我的代码或 Eclipse 3.6 I20100608-0911 中的错误/功能存在问题,这会阻止您第一次单击资源(在我的情况下为 IProject)时正确触发选择更改():

public void selectionChanged(IAction action, ISelection selection) {
    this.selection = selection;
}

正如我发现的事件是第一次调出上下文菜单时按以下顺序触发:

  1. SelectionChanged()
  2. setActivePart()
  3. SelectionChanged()

第一次传递给 SelectionChanged() 的 ISelection 始终是“空选择”。

第一次之后,引入上下文菜单会产生以下事件触发顺序:

  1. setActivePart()
  2. SelectionChanged()

这就是为什么我们每次在 setActivePart() 内都应该触发 SelectionChanged() 以确保我们获得最新的选择:

public void setActivePart(IAction action, IWorkbenchPart targetPart) {
    selectionChanged(action, targetPart.getSite().getPage().getSelection());
    ...
}

我希望对某人有帮助;)

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):

public void selectionChanged(IAction action, ISelection selection) {
    this.selection = selection;
}

As I found out events are fired in this order when bringing up the context menu for the first time:

  1. selectionChanged()
  2. setActivePart()
  3. selectionChanged()

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:

  1. setActivePart()
  2. selectionChanged()

That's why we should fire selectionChanged() every time inside setActivePart() in order to make sure we get the most recent selection:

public void setActivePart(IAction action, IWorkbenchPart targetPart) {
    selectionChanged(action, targetPart.getSite().getPage().getSelection());
    ...
}

I hope that helps someone ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文