2017-08-30 68 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; 
} 
相關問題