Относится к вопросу "Пользовательское сообщение при закрытии части в Eclipse RCP 4" У меня также есть приложение Eclipse RCP 4 с несколькими частями редактора (реализующими MDirtyable и @Persist).
Части закрываются. Когда пользователь закрывает часть, должно появиться специальное всплывающее окно, которое спрашивает пользователя, действительно ли он хочет сохранить часть или нет.
Также, когда пользователь закрывает приложение, всплывающее окно должно предлагать пользователю закрыть/сохранить грязные части. В основном он предназначен для удаления диалогов закрытия eclipse e4 по умолчанию.
Я реализовал пользовательские ISaveHandler и IWindowCloseHandler, подписанные на событие завершения запуска приложения UIEvents.UILifeCycle.APP_STARTUP_COMPLETE в классе жизненного цикла.
Пользовательский IWindowCloseHandler отлично работает (с точки зрения диалогов), а пользовательский ISaveHandler — нет.
ISaveHandler.save возвращает ошибку stackoverflow, если определено следующим образом:
@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