Eclipse编辑器零件保存在零件上已停用

时间:2018-07-05 13:39:01

标签: eclipse focus eclipse-rcp

我的问题是我有一个使用EditorParts的自定义应用程序,该应用程序保留在数据库中。用户可以打开多个编辑器,并在它们之间切换。我需要让用户在切换到下一个编辑器之前将所有未保存的更改保存在编辑器中(否则将其关闭)。

我创建了一个IPartListener2,并且收到partDeactivated通知。如果isDirty()== true,我弹出一个MessageDialog询问是否保存;因为我想调用editor.doSave()。

我的问题是那行不通。我再也看不到MessageDialog,因为会触发另一个partDeactivated。我想这是由编辑器上的MessageDialog引起的。

我已经研究过How to listen to lose focus event of a part in Eclipse E4 RCP?,但这并没有帮助我。

感谢帮助e4初学者

public class DatasetAttachmentEditor {
        ... // code here
    @Override
    public void init(IEditorSite site, IEditorInput input)  throws PartInitException {
        ... // code here
        site.getPage().addPartListener(new EditorsPartListener(this));
    }
}

public class EditorsPartListener implements IPartListener2 {

    private IEditorPart editor;

    public EditorsPartListener(IEditorPart editor) {
        this.editor = editor;
    }

    @Override
    public void partClosed(IWorkbenchPartReference partRef) {
        if (partRef.getPage().getActiveEditor().getClass().getName().equals(editor.getClass().getName())) {
            partRef.getPage().removePartListener(this);
        }
    }

    @Override
    public void partDeactivated(IWorkbenchPartReference partRef) {

        if (!partRef.getClass().getName().equals("org.eclipse.ui.internal.EditorReference")) {
            System.out.println("partDeactivated: not a Editor="+partRef.getClass().getName());
            return;
        }

        if (!editor.isDirty()) {
            // if the editor is not dirty - do nothing
            return;
        }

        // ask if to save
        int choice = EditorPartSaveDialog(partRef.getPage().getActiveEditor());
        if(choice == MessageDialog.OK) {
            // save the Editor
            try {
                ProgressMonitorDialog progress = new ProgressMonitorDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());                
                progress.setCancelable(false);
                progress.run(false, false, new IRunnableWithProgress() {
                    @Override
                    public void run(IProgressMonitor monitor) {
                        // do the save
                        editor.doSave(monitor);
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        else {
            // don't save: just close it
            partRef.getPage().closeEditor(editor, false);
        }
    }

    @Override
    public void partActivated(IWorkbenchPartReference partRef) {
    }

    @Override
    public void partBroughtToTop(IWorkbenchPartReference partRef) {
    }

    @Override
    public void partOpened(IWorkbenchPartReference partRef) {
    }

    @Override
    public void partHidden(IWorkbenchPartReference partRef) {
    }

    @Override
    public void partVisible(IWorkbenchPartReference partRef) {
    }

    @Override
    public void partInputChanged(IWorkbenchPartReference partRef) {
    }

    /**
     * Asks the user to Save changes
     * @param editor
     * @return MessageDialog.OK to save, MessageDialog.CANCEL otherwise
     */
    private int EditorPartSaveDialog(IEditorPart editor) {

        // If save confirmation is required ..
        String message = NLS.bind("''{0}'' has been modified. Save changes?", LegacyActionTools.escapeMnemonics(editor.getTitle()));

        // Show a dialog.
        MessageDialog d = new MessageDialog(
                            Display.getCurrent().getActiveShell(),
                            "Save Editor", null, message,
                            MessageDialog.QUESTION,
                            0,
                            "Save",// MessageDialog 0x0 (OK)
                            "Don't Save: close"// MessageDialog 0x1 (CANCEL)
                        )
        return d.open();
    }
}

2 个答案:

答案 0 :(得分:1)

您可能需要在deactivate事件结束后运行代码。您可以使用Display.asyncExec来做到这一点。

类似的东西:

@Override
public void partDeactivated(IWorkbenchPartReference partRef) {

    if (!partRef.getClass().getName().equals("org.eclipse.ui.internal.EditorReference")) {
        System.out.println("partDeactivated: not a Editor="+partRef.getClass().getName());
        return;
    }

    if (!editor.isDirty()) {
        // if the editor is not dirty - do nothing
        return;
    }

    Display.getDefault().asyncExec(() ->
      {
        // TODO the rest of your deactivate code goes here
      });
}

(以上代码假定您使用的是Java 8或更高版本)

这是3.x兼容模式代码,而不是e4。

答案 1 :(得分:0)

使用上述建议和Enumerating all my Eclipse editors?,我找到了一个很好的解决方案 我先检查所有编辑器,然后检查所有持久性编辑器-跳过自身和持久性对象。

感谢您的评论!

public class ConceptAcronymValidator implements IValidator { 

    private ConceptInstanceEditor myEditor;

    public ConceptAcronymValidator(ConceptInstanceEditor editor) {
        super();
        this.myEditor = editor;
    }

    @Override
    public IStatus validate(Object value) {


        // check all Editors
        for (IEditorReference editorRef: PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences()) {
            IEditorPart editor = editorRef.getEditor(false);
            if (editor != null) {
                // don't check our own Editor
                if (!editor.equals(myEditor)) {
                    ConceptInstanceEditor conceptEditor = (ConceptInstanceEditor)editor;
                    if (conceptEditor.getTxtAcronym().equals(value.toString())) {
                        return ValidationStatus.error("This Concept is already used by Editor <"+
                                conceptEditor.getConceptModel().getName().getValue(MultilingualString.EN)+
                                ">");
                    }
                }
            }
        }

        // check all persisted Concepts
        List<Concept> concepts = ReferenceServiceFactory.getService().getConcepts();
        for (Concept concept: concepts) {
            Concept myConcept = (Concept) myEditor.getConceptModel().getInstance();
            // check if a new Editor
            if (myConcept == null) {
                if (concept.getAcronym().equals(value.toString())) {
                    return ValidationStatus.error("This Concept is already used by <"+
                            concept.getName().getValue(MultilingualString.EN)+
                            ">");
                }
            }
            else {
                // don't check own Instance
                if (!concept.equals(myConcept)) {
                    if (concept.getAcronym().equals(value.toString())) {
                        return ValidationStatus.error("This Concept is already used by <"+
                                concept.getName().getValue(MultilingualString.EN)+
                                ">");
                    }   
                }
            }
        }

        return Status.OK_STATUS;
    }
}