2017-08-30 40 views
0

与问题“Custom message when closing a part in Eclipse RCP 4” 相关我还有一个带有多个编辑器部件(实现MDirtyable和@Persist)的Eclipse RCP 4应用程序。用于Eclipse e4文本编辑器应用程序的自定义ISaveHandler和IWindowCloseHandler

零件是可闭合的。当用户关闭零件时,应该有一个自定义弹出窗口,询问用户他是否真的想要保存零件。

另外,当用户关闭应用程序时,弹出窗口应提示用户关闭/保存脏部件。基本上它打算去除默认的关闭eclipse e4对话框。

我已经实现了自定义的ISaveHandler和IWindowCloseHandler,订阅了生命周期类中的应用程序启动完成事件UIEvents.UILifeCycle.APP_STARTUP_COMPLETE。

自定义IWindowCloseHandler工作正常(在对话框方面),但自定义ISaveHandler不是。定义当

ISaveHandler.save返回计算器误差如下:

@Override 
public boolean save(MPart dirtyPart, boolean confirm) { 
    EPartService partService = dirtyPart.getContext().get(EPartService.class); 
    //Try to close the part and save the document to disc by 
    //calling the @Persist method 
    return partService.savePart(dirtyPart, confirm); 

} 

我已附加了完整LifeCycleManager类:

public class LifeCycleManager { 
@Inject IEventBroker eventBroker; 

@ProcessAdditions 
public void processAdditions(MApplication application, EModelService modelService){ 
    MWindow window =(MWindow)modelService.find("application-trimmedwindow", application); 
    eventBroker.subscribe(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE, 
          new AppStartupCompleteEventHandler(window, modelService, application)); 
} 
public class AppStartupCompleteEventHandler implements EventHandler { 
    private MWindow theWindow; 
    private MApplication app; 
    private ISaveHandler saveHandler; 

    AppStartupCompleteEventHandler(MWindow window, EModelService modelService, MApplication application){ 
     theWindow = window; 
     app = application; 
    } 

    @Override 
    public void handleEvent(Event event) { 
     theWindow.getContext().set(ISaveHandler.class, new ISaveHandler() { 
      @Override 
      public boolean save(MPart dirtyPart, boolean confirm) { 
       System.out.println("PARTE PARA SALVAR..." + dirtyPart.getLabel()); 
       EPartService partService = dirtyPart.getContext().get(EPartService.class); 
       //partService.hidePart(dirtyPart,true); 
       return partService.savePart(dirtyPart, confirm); 
       //return true; 
      } 

      @Override 
      public boolean saveParts(Collection<MPart> dirtyParts, boolean confirm) { 
       return false; 
      } 
      @Override 
      public Save promptToSave(MPart dirtyPart) { 
       return promptToSaveDialog(dirtyPart); 
      } 
      @Override 
      public Save[] promptToSave(Collection<MPart> dirtyParts) { 
       return null; 
      } 
     }); 
     saveHandler = (ISaveHandler)theWindow.getContext().get(ISaveHandler.class); 
     theWindow.getContext().set(IWindowCloseHandler.class, new IWindowCloseHandler() { 
      @Override 
      public boolean close(MWindow window) { 
       List<MHandler> listHandlers = window.getHandlers(); 
       System.out.println(listHandlers.size()); 
       Shell shell = (Shell) window.getWidget(); 
       if (MessageDialog.openConfirm(shell, "Close Nastran Editor", "Do you really want to close the entire application?")) { 
        Collection<EPartService> allPartServices = getAllPartServices(app); 
        if (containsDirtyParts(allPartServices)) { 
         return iterateOverDirtyParts(allPartServices); 
        } 
       else { 
        return true; 
       } 
      } 
      return false; 
     }}); 
} 
private Collection<EPartService> getAllPartServices(MApplication application) { 
    List<EPartService> partServices = new ArrayList<EPartService>(); 
    EModelService modelService = application.getContext().get(EModelService.class); 
    List<MWindow> elements = modelService.findElements(application, MWindow.class, EModelService.IN_ACTIVE_PERSPECTIVE, 
      new ElementMatcher(null, MWindow.class, (List<String>) null)); 
    for (MWindow w : elements) { 
     if (w.isVisible() && w.isToBeRendered()) { 
      EPartService partService = w.getContext().get(EPartService.class); 
      if (partService != null) { 
       partServices.add(partService); 
      } 
     } 
    } 
    return partServices; 
} 
private boolean containsDirtyParts(Collection<EPartService> partServices) { 
    for (EPartService partService : partServices) { 
     if (!partService.getDirtyParts().isEmpty()) return true; 
    } 
    return false; 
} 
private boolean iterateOverDirtyParts(Collection<EPartService> allPartServices) { 
    for (EPartService partService : allPartServices) { 
     Collection<MPart> dirtyParts = partService.getDirtyParts(); 
     for(MPart dirtyPart : dirtyParts) { 
      switch(saveHandler.promptToSave(dirtyPart)) { 
       case NO: break; 
       case YES: 
        saveHandler.save(dirtyPart, false); 
        break; 
       case CANCEL:return false; 
      } 
     } 
    } 
    return true; 
} 
private Save promptToSaveDialog(MPart dirtyPart) { 
    MessageDialog dialog = new MessageDialog((Shell)theWindow.getWidget(), "Save file", null, 
      "'"+dirtyPart.getLabel()+"' has been modified. Save changes?", MessageDialog.QUESTION, new String[] { "YES", "NO", "CANCEL" }, 0); 
     switch (dialog.open()){ 
      case 0: return Save.YES; 
      case 1: return Save.NO; 
      case 2: return Save.CANCEL; 
      default:return Save.CANCEL; 
     } 
} 
} 
}///END of LifeCycleManager 

回答

1

ISaveHandlersave方法从EPartService内调用savePart方法,所以你不能再次调用savePart

相反,您应该只需调用零件的@Persist方法。所以像这样:

@Override 
public boolean save(final MPart dirtyPart, final boolean confirm) 
{ 
    if (confirm) 
    { 
    switch (promptToSave(dirtyPart)) 
    { 
     default: 
     case NO: 
     return true; 
     case CANCEL: 
     return false; 
     case YES: 
     break; 
    } 
    } 

    try 
    { 
    ContextInjectionFactory.invoke(dirtyPart.getObject(), Persist.class, dirtyPart.getContext()); 
    } 
    catch (final InjectionException ex) 
    { 
    // TODO ignore or log error 
    } 

    return true; 
} 
相关问题