diff options
author | Juergen Haug | 2015-05-12 09:17:51 +0000 |
---|---|---|
committer | Juergen Haug | 2015-05-15 09:39:24 +0000 |
commit | a275e1550e63272c2a1b08d3b6dd0c636f644529 (patch) | |
tree | eb4efac1f17aa347fb9eb21402d192ebd699fa32 /plugins | |
parent | 67b28cc72505b6de7429807de5e131c045cba0b8 (diff) | |
download | org.eclipse.etrice-a275e1550e63272c2a1b08d3b6dd0c636f644529.tar.gz org.eclipse.etrice-a275e1550e63272c2a1b08d3b6dd0c636f644529.tar.xz org.eclipse.etrice-a275e1550e63272c2a1b08d3b6dd0c636f644529.zip |
Bug 467379 - [ui] diagram auto save fixes
Change-Id: I20364a426eb0c1960627f0f107790eb322518f8a
Diffstat (limited to 'plugins')
4 files changed, 140 insertions, 87 deletions
diff --git a/plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/DiagramEditorBase.java b/plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/DiagramEditorBase.java index 87fb2ff0b..364b388f9 100644 --- a/plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/DiagramEditorBase.java +++ b/plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/DiagramEditorBase.java @@ -30,6 +30,9 @@ import org.eclipse.emf.ecore.EStructuralFeature.Setting; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.transaction.RunnableWithResult; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.eclipse.emf.transaction.util.TransactionUtil; import org.eclipse.etrice.core.fsm.fSM.ModelComponent; import org.eclipse.etrice.core.fsm.ui.FSMUiModule; import org.eclipse.etrice.ui.common.base.UIBaseActivator; @@ -57,6 +60,7 @@ import org.eclipse.xtext.validation.CheckMode; import org.eclipse.xtext.validation.IResourceValidator; import org.eclipse.xtext.validation.Issue; +import com.google.common.collect.Lists; import com.google.inject.Inject; import com.google.inject.Injector; @@ -114,63 +118,101 @@ public abstract class DiagramEditorBase extends DiagramEditor implements IInputU @Override public void doSave(final IProgressMonitor monitor) { - ResourceSet rs = getEditingDomain().getResourceSet(); - for (Resource res : rs.getResources()) { - if (res instanceof XtextResource) { - if (!res.isLoaded()) { - try { - res.load(Collections.EMPTY_MAP); - } catch (IOException e) { - MessageDialog.openError(Display.getDefault().getActiveShell(), "ERROR", "Internal error: couldn't load referenced resource "+res.getURI()); + boolean isValid = validateResourcesBeforeSave(monitor); + if(isValid) + super.doSave(monitor); + // deactivate saveOnFocus for better usability + // avoid retrigger loop from message box + saveOnFocusListener.setActive(isValid); + } + + protected boolean validateResourcesBeforeSave(final IProgressMonitor monitor){ + final TransactionalEditingDomain editingDomain = getEditingDomain(); + + final RunnableWithResult<Boolean> runnable = new RunnableWithResult.Impl<Boolean>() { + + @Override + public void run() { + // copy list to avoid ConcurrentModification during serialize and validation + final List<Resource> resources = Lists.newArrayList(editingDomain.getResourceSet().getResources()); + setResult(false); + for(Resource res : resources){ + if(!validateResource(res, monitor)) return; - } } - if (res.isModified()) { + + setResult(true); + } + + }; + + try { + return TransactionUtil.runExclusive(editingDomain, runnable); + } + catch (InterruptedException e) { + MessageDialog.openError(Display.getDefault().getActiveShell(), "ERROR", "Internal error: could not save model:\n\n"+e.getMessage()); + UIBaseActivator.getDefault().getLog().log(new Status(Status.ERROR, UIBaseActivator.PLUGIN_ID, e.getMessage(), e)); - XtextResource xres = (XtextResource) res; - ISerializer serializer = xres.getSerializer(); - - if (xres.getContents().isEmpty()) { - MessageDialog.openError(Display.getDefault().getActiveShell(), "ERROR", "Internal error: part of textual model is empty, can't save"); - return; - } + return false; + } + } - try { - // HOWTO: call serializer to validate the concrete syntax - // this throws an exception which is caught further up the stack - // and a dialog will be displayed - serializer.serialize(xres.getContents().get(0)); - - List<Issue> result = resourceValidator.validate(res, CheckMode.NORMAL_AND_FAST, new CancelIndicator() { - public boolean isCanceled() { - return monitor.isCanceled(); - } - }); - if (!result.isEmpty()) { - boolean error = false; - MultiStatus ms = new MultiStatus(UIBaseActivator.PLUGIN_ID, Status.ERROR, "validation errors during diagram save", null); - for (Issue issue : result) { - if (issue.isSyntaxError() || issue.getSeverity()==Severity.ERROR) { - ms.add(new Status(Status.ERROR, UIBaseActivator.PLUGIN_ID, issue.getMessage())); - error = true; - } - } - if (error) { - MessageDialog.openError(Display.getDefault().getActiveShell(), "ERROR", "Internal error: model is invalid, can't save"); - UIBaseActivator.getDefault().getLog().log(ms); - return; + protected boolean validateResource(Resource res, final IProgressMonitor monitor){ + if (res instanceof XtextResource) { + if (!res.isLoaded()) { + try { + res.load(Collections.EMPTY_MAP); + } catch (IOException e) { + MessageDialog.openError(Display.getDefault().getActiveShell(), "ERROR", "Internal error: couldn't load referenced resource "+res.getURI()); + return false; + } + } + if (res.isModified()) { + + XtextResource xres = (XtextResource) res; + ISerializer serializer = xres.getSerializer(); + + if (xres.getContents().isEmpty()) { + MessageDialog.openError(Display.getDefault().getActiveShell(), "ERROR", "Internal error: part of textual model is empty, can't save"); + return false; + } + + try { + // HOWTO: call serializer to validate the concrete syntax + // this throws an exception which is caught further up the stack + // and a dialog will be displayed + serializer.serialize(xres.getContents().get(0)); + + List<Issue> result = resourceValidator.validate(res, CheckMode.NORMAL_AND_FAST, new CancelIndicator() { + public boolean isCanceled() { + return monitor.isCanceled(); + } + }); + if (!result.isEmpty()) { + boolean error = false; + MultiStatus ms = new MultiStatus(UIBaseActivator.PLUGIN_ID, Status.ERROR, "validation errors during diagram save", null); + for (Issue issue : result) { + if (issue.isSyntaxError() || issue.getSeverity()==Severity.ERROR) { + ms.add(new Status(Status.ERROR, UIBaseActivator.PLUGIN_ID, issue.getMessage())); + error = true; } } + if (error) { + MessageDialog.openError(Display.getDefault().getActiveShell(), "ERROR", "Internal error: model is invalid, can't save"); + UIBaseActivator.getDefault().getLog().log(ms); + return false; + } } - catch (RuntimeException e) { - MessageDialog.openError(Display.getDefault().getActiveShell(), "ERROR", "Internal error: model is invalid, can't save:\n\n"+e.getMessage()); - UIBaseActivator.getDefault().getLog().log(new Status(Status.ERROR, UIBaseActivator.PLUGIN_ID, e.getMessage())); - return; - } + } + catch (RuntimeException e) { + MessageDialog.openError(Display.getDefault().getActiveShell(), "ERROR", "Internal error: model is invalid, can't save:\n\n"+e.getMessage()); + UIBaseActivator.getDefault().getLog().log(new Status(Status.ERROR, UIBaseActivator.PLUGIN_ID, e.getMessage(),e)); + return false; } } } - super.doSave(monitor); + + return true; } /* (non-Javadoc) diff --git a/plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/SaveOnFocusLostListener.java b/plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/SaveOnFocusLostListener.java index e9da548ea..75e91bde4 100644 --- a/plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/SaveOnFocusLostListener.java +++ b/plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/SaveOnFocusLostListener.java @@ -12,11 +12,7 @@ package org.eclipse.etrice.ui.common.base.editor; -import java.util.EventObject; - import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.emf.common.command.CommandStackListener; -import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl; import org.eclipse.etrice.ui.common.base.UIBaseActivator; import org.eclipse.etrice.ui.common.base.preferences.UIBasePreferenceConstants; import org.eclipse.graphiti.ui.editor.DiagramEditor; @@ -28,16 +24,20 @@ import org.eclipse.ui.IWorkbenchPart; * @author Henrik Rentz-Reichert * */ -public class SaveOnFocusLostListener implements IPartListener, CommandStackListener { +public class SaveOnFocusLostListener implements IPartListener/*, CommandStackListener*/ { private DiagramEditor editor; private IPreferenceStore store; + + private boolean isActive = true; + + @SuppressWarnings("unused") private boolean saveAfterCurrentCommand = false; public SaveOnFocusLostListener(DiagramEditor editor) { this.editor = editor; this.store = UIBaseActivator.getDefault().getPreferenceStore(); - editor.getEditingDomain().getCommandStack().addCommandStackListener(this); + //editor.getEditingDomain().getCommandStack().addCommandStackListener(this); } /* (non-Javadoc) @@ -65,17 +65,20 @@ public class SaveOnFocusLostListener implements IPartListener, CommandStackListe * @see org.eclipse.ui.IPartListener#partDeactivated(org.eclipse.ui.IWorkbenchPart) */ @Override - public void partDeactivated(IWorkbenchPart part) { - boolean save = store.getBoolean(UIBasePreferenceConstants.SAVE_DIAG_ON_FOCUS_LOST); - if (save && editor.isDirty()) { - if (editor.getEditingDomain() instanceof TransactionalEditingDomainImpl) { - TransactionalEditingDomainImpl ted = (TransactionalEditingDomainImpl) editor.getEditingDomain(); - if (ted.getActiveTransaction()!=null) { - // avoid to run into dead-lock - saveAfterCurrentCommand = true; - return; - } - } + public void partDeactivated(IWorkbenchPart part) { + if(part != editor) + return; + + boolean isSaveOnFocus = store.getBoolean(UIBasePreferenceConstants.SAVE_DIAG_ON_FOCUS_LOST); + if (isActive && isSaveOnFocus && editor.isDirty()) { +// if (editor.getEditingDomain() instanceof TransactionalEditingDomainImpl) { +// TransactionalEditingDomainImpl ted = (TransactionalEditingDomainImpl) editor.getEditingDomain(); +// if (ted.getActiveTransaction()!=null) { +// // avoid to run into dead-lock +// saveAfterCurrentCommand = true; +// return; +// } +// } editor.doSave(new NullProgressMonitor()); } } @@ -90,13 +93,17 @@ public class SaveOnFocusLostListener implements IPartListener, CommandStackListe /* (non-Javadoc) * @see org.eclipse.emf.common.command.CommandStackListener#commandStackChanged(java.util.EventObject) */ - @Override - public void commandStackChanged(EventObject event) { - - if (saveAfterCurrentCommand) { - saveAfterCurrentCommand = false; - editor.doSave(new NullProgressMonitor()); - } +// @Override +// public void commandStackChanged(EventObject event) { +// +// if (saveAfterCurrentCommand) { +// saveAfterCurrentCommand = false; +// editor.doSave(new NullProgressMonitor()); +// } +// } + + public void setActive(boolean isActive){ + this.isActive = isActive; } } diff --git a/plugins/org.eclipse.etrice.ui.structure/src/org/eclipse/etrice/ui/structure/support/ActorContainerRefSupport.java b/plugins/org.eclipse.etrice.ui.structure/src/org/eclipse/etrice/ui/structure/support/ActorContainerRefSupport.java index 6eeb3da29..4ed33ca3e 100644 --- a/plugins/org.eclipse.etrice.ui.structure/src/org/eclipse/etrice/ui/structure/support/ActorContainerRefSupport.java +++ b/plugins/org.eclipse.etrice.ui.structure/src/org/eclipse/etrice/ui/structure/support/ActorContainerRefSupport.java @@ -40,6 +40,7 @@ import org.eclipse.etrice.ui.common.base.support.ChangeAwareCreateFeature; import org.eclipse.etrice.ui.common.base.support.ChangeAwareCustomFeature; import org.eclipse.etrice.ui.common.base.support.CommonSupportUtil; import org.eclipse.etrice.ui.common.base.support.DeleteWithoutConfirmFeature; +import org.eclipse.etrice.ui.common.base.support.DiagramAccessBase; import org.eclipse.etrice.ui.structure.DiagramAccess; import org.eclipse.etrice.ui.structure.DiagramTypeProvider; import org.eclipse.etrice.ui.structure.ImageProvider; @@ -661,18 +662,13 @@ public class ActorContainerRefSupport { if (pes != null && pes.length == 1) { Object bo = getBusinessObjectForPictogramElement(pes[0]); if (bo instanceof ActorContainerRef) { - final ActorContainerRef ref = (ActorContainerRef) bo; + final StructureClass sc = ((ActorContainerRef)bo).getStructureClass(); Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); shell.getDisplay().asyncExec(new Runnable() { @Override public void run() { - DiagramAccess diagramAccess = new DiagramAccess(); - if (ref instanceof ActorRef) { - diagramAccess.openDiagramEditor(((ActorRef) ref).getType()); - } - else if (ref instanceof SubSystemRef) { - diagramAccess.openDiagramEditor(((SubSystemRef) ref).getType()); - } + DiagramAccessBase diagramAccess = new DiagramAccess(); + diagramAccess.openDiagramEditor(sc); } }); } @@ -716,16 +712,14 @@ public class ActorContainerRefSupport { PictogramElement[] pes = context.getPictogramElements(); if (pes != null && pes.length == 1) { Object bo = getBusinessObjectForPictogramElement(pes[0]); - if (bo instanceof ActorContainerRef) { - final ActorContainerRef ref = (ActorContainerRef) bo; + if (bo instanceof ActorRef) { + final ActorClass ac = ((ActorRef)bo).getType(); Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); shell.getDisplay().asyncExec(new Runnable() { @Override public void run() { - org.eclipse.etrice.ui.behavior.DiagramAccess diagramAccess = new org.eclipse.etrice.ui.behavior.DiagramAccess(); - if (ref instanceof ActorRef) { - diagramAccess.openDiagramEditor(((ActorRef) ref).getType()); - } + DiagramAccessBase diagramAccess = new org.eclipse.etrice.ui.behavior.DiagramAccess(); + diagramAccess.openDiagramEditor(ac); } }); } diff --git a/plugins/org.eclipse.etrice.ui.structure/src/org/eclipse/etrice/ui/structure/support/StructureClassSupport.java b/plugins/org.eclipse.etrice.ui.structure/src/org/eclipse/etrice/ui/structure/support/StructureClassSupport.java index 729a3d380..518be89b8 100644 --- a/plugins/org.eclipse.etrice.ui.structure/src/org/eclipse/etrice/ui/structure/support/StructureClassSupport.java +++ b/plugins/org.eclipse.etrice.ui.structure/src/org/eclipse/etrice/ui/structure/support/StructureClassSupport.java @@ -22,6 +22,7 @@ import org.eclipse.etrice.core.room.StructureClass; import org.eclipse.etrice.ui.common.base.editor.DiagramEditorBase; import org.eclipse.etrice.ui.common.base.support.CantRemoveFeature; import org.eclipse.etrice.ui.common.base.support.DeleteWithoutConfirmFeature; +import org.eclipse.etrice.ui.common.base.support.DiagramAccessBase; import org.eclipse.etrice.ui.common.commands.ChangeDiagramInputJob; import org.eclipse.graphiti.dt.IDiagramTypeProvider; import org.eclipse.graphiti.features.IAddFeature; @@ -64,6 +65,8 @@ import org.eclipse.graphiti.tb.IToolBehaviorProvider; import org.eclipse.graphiti.ui.features.DefaultFeatureProvider; import org.eclipse.graphiti.util.ColorConstant; import org.eclipse.graphiti.util.IColorConstant; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; public class StructureClassSupport { @@ -241,8 +244,15 @@ public class StructureClassSupport { if (pes != null && pes.length == 1) { Object bo = getBusinessObjectForPictogramElement(pes[0]); if (bo instanceof ActorClass) { - org.eclipse.etrice.ui.behavior.DiagramAccess diagramAccess = new org.eclipse.etrice.ui.behavior.DiagramAccess(); - diagramAccess.openDiagramEditor((ActorClass)bo); + final ActorClass ac = (ActorClass) bo; + Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); + shell.getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + DiagramAccessBase diagramAccess = new org.eclipse.etrice.ui.behavior.DiagramAccess(); + diagramAccess.openDiagramEditor(ac); + } + }); } } } |