2017-08-30 10 views
0

質問に関連する "Custom message when closing a part in Eclipse RCP 4" 私はEclipse RCP 4アプリケーションに複数のエディタパーツ(MDirtyableと@Persistを実装しています)もあります。Eclipse e4テキストエディタアプリケーションのカスタムISaveHandlerとIWindowCloseHandler

部品は閉鎖可能です。ユーザーが部品を閉じるときに、部品を実際に保存したいかどうかをユーザーに尋ねるカスタムポップアップが必要です。

また、ユーザーがアプリケーションを終了すると、ポップアップはユーザーに汚れた部品を閉じたり保存したりするよう促すはずです。 基本的には、デフォルトのクローズドeclipse e4ダイアログを削除することを意図しています。

ライフサイクルクラスのアプリケーション起動完了イベントUIEvents.UILifeCycle.APP_STARTUP_COMPLETEを購読してカスタムISaveHandlerとIWindowCloseHandlerを実装しました。

カスタムIWindowCloseHandlerは(ダイアログの点で)うまく動作しますが、カスタムISaveHandlerは機能しません。 ISaveHandlersave方法はEPartService内から呼び出され

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

@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); 

} 

Iは、完全LifeCycleManagerクラスを添付した:定義された場合、次のように

ISaveHandler.save戻ってエラーをstackoverflowの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; 
} 
関連する問題