【问题标题】:Toolbar undo redo Eclipse RCP工具栏撤消重做 Eclipse RCP
【发布时间】:2018-02-27 13:29:49
【问题描述】:

我基本上有以下几点:

<menuContribution locationURI="menu:com.myprog.menus.edit?after=undo">
<command commandId="org.eclipse.ui.edit.undo" label="Undo" style="push">
</command>
<command commandId="org.eclipse.ui.edit.redo" label="Redo" style="push">
</command>
</menuContribution>

=================================

<menuContribution locationURI="toolbar:org.eclipse.ui.main.toolbar">     
     <toolbar id="com.myprog.ui.undo">
        <command commandId="org.eclipse.ui.edit.undo" label="Undo" style="push">
        </command>
        <command commandId="org.eclipse.ui.edit.redo" label="Redo" style="push">
        </command>
     </toolbar>
</menuContribution>

这是使用 Eclipse 4 上的兼容层运行的 Eclipse 3.X RCP。

问题是,当我打开任何文本编辑器时,撤消/重做工具栏按钮不会正确启用或禁用,除非我使用鼠标选择多行或单击任何其他选项卡(项目资源管理器示例),然后单击返回编辑器。

知道会发生这种情况,我预计编辑菜单的撤消/重做也会搞砸,但我发现它们根据我在编辑器中所做的操作正确启用和禁用。

另外需要注意的是,无论工具栏撤消/重做按钮的状态如何,键盘快捷键Ctrl+ZCtrl+Y 按预期工作。

什么可能导致这种情况?让工具栏按钮不起作用真是太奇怪了。如果所有撤消/重做机制都不起作用,我会感觉更好。

【问题讨论】:

    标签: eclipse eclipse-rcp e4


    【解决方案1】:

    对于菜单项,Eclipse 会在每次显示菜单时检查启用,但对于工具栏,您必须告诉 Eclipse 何时更新启用。

    您可以使用事件代理来执行此操作。在 3.x 兼容性 RCP 中使用:

    IEventBroker eventBroker = (IEventBroker)PlatformUI.getWorkbench().getService(IEventBroker.class);
    
    eventBroker.send(UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC, UIEvents.ALL_ELEMENT_ID);
    

    【讨论】:

    • 是否应该在创建工作台时进行?
    • 每次操作的启用状态发生变化时,您都需要执行此操作。
    • @AymanSalah 请注意您的编辑 - 如果您想提供替代方案,请写下您自己的答案。不要对别人的回答做大的改动。
    • 我相信我添加的内容会对面临与我相同问题的人有所帮助。我认为我的添加使它更加完整。我也不认为我应该自己写一个答案,因为你启发了我的解决方案,我不应该把解决方案归功于自己。但是,是的,这是一个巨大的编辑,我会按照你的建议添加一个答案。感谢您一直帮助我。
    • 编辑应该是对答案的小修正,而不是大的补充。使用您的附加信息添加另一个答案绝对没有问题。
    【解决方案2】:

    使用greg-449的回答:

    IEventBroker eventBroker = (IEventBroker)PlatformUI.getWorkbench().getService(IEventBroker.class);

    eventBroker.send(UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC, UIEvents.ALL_ELEMENT_ID);

    我通过执行以下操作在documentChanged 侦听器中使用了它:

        try {
           TextEditor editor = (TextEditor)((IEditorReference) editorReference).getEditor(false);
           if(editor != null) {
              editor.getDocumentProvider().getDocument(editor.getEditorInput()).addDocumentListener(new IDocumentListener() {
                 @Override
                 public void documentChanged(DocumentEvent event) {
                    IEventBroker eventBroker = (IEventBroker)PlatformUI.getWorkbench().getService(IEventBroker.class);
                    eventBroker.post(UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC, UIEvents.ALL_ELEMENT_ID);
                 }
    
                 @Override
                 public void documentAboutToBeChanged(DocumentEvent event) {
                 }
              });
           }  
        }
        catch (ClassCastException e) {
        }
    

    然而,我遇到了一个问题。问题是,如果编辑恰好是一个字符,则不会启用撤消按钮。但是,如果编辑超出一个字符,它就可以完美地工作。

    进一步调试时,我注意到另一个我没有实现并且撤销/重做工作正常的编辑器的调用堆栈从selectionChanged 事件而不是documentChanged 开始。

    我在我的问题中提到,如果我使用鼠标选择多行,撤消/重做将启用,这显然是selectionChanged

    所以基本上,我已经找到了这个解决方案:

           try {
               final TextEditor editor = (TextEditor)((IEditorReference) partRef).getEditor(false);
               editor.getDocumentProvider().getDocument(editor.getEditorInput()).addDocumentListener(new IDocumentListener() {
                  
                  @Override
                  public void documentChanged(DocumentEvent event) {
                     editor.getSelectionProvider().setSelection(editor.getSelectionProvider().getSelection());
                  }
                  
                  @Override
                  public void documentAboutToBeChanged(DocumentEvent event) {
                  }
               });
            }
            catch (ClassCastException e) {
            }
    

    我现在所做的基本上是触发selectionChanged 事件,该事件从一开始就正确更新撤消/重做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-15
      • 1970-01-01
      • 2019-07-02
      • 1970-01-01
      • 2013-11-04
      • 1970-01-01
      • 2019-08-19
      • 2010-09-14
      相关资源
      最近更新 更多