Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'core/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/SashMultiDiagramEditor.java')
-rw-r--r--core/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/SashMultiDiagramEditor.java523
1 files changed, 523 insertions, 0 deletions
diff --git a/core/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/SashMultiDiagramEditor.java b/core/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/SashMultiDiagramEditor.java
new file mode 100644
index 00000000000..03e853e6fac
--- /dev/null
+++ b/core/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/SashMultiDiagramEditor.java
@@ -0,0 +1,523 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.core.editor;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.EventObject;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.gef.commands.CommandStackListener;
+import org.eclipse.gef.ui.actions.ActionRegistry;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditDomain;
+import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor;
+import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramGraphicalViewer;
+import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.papyrus.core.Activator;
+import org.eclipse.papyrus.core.contentoutline.ContentOutlineRegistry;
+import org.eclipse.papyrus.core.extension.diagrameditor.EditorFactoryRegistry;
+import org.eclipse.papyrus.core.extension.diagrameditor.IEditorFactoryRegistry;
+import org.eclipse.papyrus.core.extension.editorcontext.EditorContextRegistry;
+import org.eclipse.papyrus.core.extension.editorcontext.IEditorContextRegistry;
+import org.eclipse.papyrus.core.multidiagram.SashDiagramModelManager;
+import org.eclipse.papyrus.core.multidiagram.SashWindowModelManagerWrapper;
+import org.eclipse.papyrus.sasheditor.gef.EditorNotFoundException;
+import org.eclipse.papyrus.sasheditor.gef.MultiDiagramEditorGefDelegate;
+import org.eclipse.papyrus.sasheditor.gef.MultiDiagramException;
+import org.eclipse.papyrus.sasheditor.gef.SelectionSynchronizer;
+import org.eclipse.papyrus.sasheditor.sash.ISashWindowsModelManager;
+import org.eclipse.papyrus.sasheditor.sash.SashMultiPageEditorPart;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.dialogs.SaveAsDialog;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+import org.eclipse.ui.views.properties.IPropertySheetPage;
+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * Multi diagram editor allowing to plug various kind of editors. Editors are registered with the help of the Eclipse extension mechanism. This implementation allows to register editors and context
+ * separately. An editor should specify which context it need to run. This multi diagram editor allows to show editor side by side in one or more sash windows.
+ *
+ * @author dumoulin
+ * @author <a href="mailto:jerome.benois@obeo.fr">Jerome Benois</a>
+ */
+public class SashMultiDiagramEditor extends SashMultiPageEditorPart implements IMultiDiagramEditor, ITabbedPropertySheetPageContributor, IDiagramWorkbenchPart {
+
+ /** Gef adapter */
+ private MultiDiagramEditorGefDelegate gefAdaptorDelegate;
+
+ /** Registry to store editor factories */
+ private IEditorFactoryRegistry editorRegistry;
+
+ /** Registry for editor contexts */
+ private IEditorContextRegistry editorContextRegistry;
+
+ /** ContentOutline registry */
+ private ContentOutlineRegistry contentOutlineRegistry;
+
+ /**
+ * Context associated to this backbone editor.
+ */
+ private BackboneContext defaultContext;
+
+ /**
+ * Diagram notifier notifying diagram CRUD events.
+ */
+ private DiagramNotifier diagramNotifier;
+
+ /**
+ *
+ */
+ private TabbedPropertySheetPage tabbedPropertySheetPage = null;
+
+ /** Flag reflecting the editor state. The flag is set by listeners on model changes */
+ private boolean toSave = false;
+
+ /** gef editing domain shared among all editors in this multi diagram editor */
+ private DiagramEditDomain diagramEditDomain;
+
+ /**
+ * Listening on diagram changes. Only listen on diagram add/delete
+ */
+ private PropertyChangeListener diagramChangeListener = new PropertyChangeListener() {
+
+ public void propertyChange(PropertyChangeEvent evt) {
+ // refresh tabs.
+ refreshTabs();
+ }
+
+ };
+
+ /**
+ * Listen on change on commandStack. Mark editor as dirty if needed.
+ */
+ private CommandStackListener commandStackListener = new CommandStackListener() {
+
+ public void commandStackChanged(EventObject event) {
+ firePropertyChange(IEditorPart.PROP_DIRTY);
+ markDirty();
+ }
+
+ };
+
+ /**
+ * Constructor.
+ */
+ public SashMultiDiagramEditor() {
+ super();
+ setDiagramEditDomain(new DiagramEditDomain(this));
+ }
+
+ /**
+ * Create a PageEditor for the specified model. Default implementation delegates to pageEditorFactory.createPageEditorFor(model); Not intended for external use.
+ *
+ * @param model
+ * the diagram to be displayed
+ * @return the Graphical Editor that displays the specified diagram
+ * @throws EditorNotFoundException
+ * No editor handling the model can be found.
+ */
+ public IEditorPart createPageEditor(Object model) throws MultiDiagramException {
+ IEditorPart part = getEditorRegistry().createEditorFor(getContextRegistry(), model);
+ return part;
+ }
+
+ /**
+ * Get the contextRegistry
+ *
+ * @return
+ */
+ public IEditorContextRegistry getContextRegistry() {
+ return editorContextRegistry;
+ }
+
+ /**
+ * Create the IEditorContextRegistry containing registered contexts. Subclass should implements this method in order to return the registry associated to the extension point namespace.
+ *
+ * @param defaultContext
+ * @param input
+ * @param site
+ * @param input
+ * @param site
+ * @return the IEditorContextRegistry for nested editor descriptors
+ */
+ protected IEditorContextRegistry createEditorContextRegistry() {
+ IEditorContextRegistry registry = new EditorContextRegistry(this, Activator.PLUGIN_ID);
+ return registry;
+ }
+
+ /**
+ * Get the contentOutlineRegistry. Create it if needed.
+ *
+ * @return the contentOutlineRegistry
+ */
+ protected ContentOutlineRegistry getContentOutlineRegistry() {
+ if (contentOutlineRegistry == null)
+ createContentOutlineRegistry();
+
+ return contentOutlineRegistry;
+ }
+
+ /**
+ * Create the contentOutlineRegistry.
+ */
+ private void createContentOutlineRegistry() {
+ contentOutlineRegistry = new ContentOutlineRegistry(this, Activator.PLUGIN_ID);
+ }
+
+ /**
+ * Get the EditorRegistry used to create editor instances. This default implementation return the singleton eINSTANCE. This method can be subclassed to return another registry.
+ *
+ * @return the singleton eINSTANCE of editor registry
+ */
+ protected IEditorFactoryRegistry getEditorRegistry() {
+ if (editorRegistry == null) {
+ editorRegistry = createEditorRegistry();
+ }
+ return editorRegistry;
+ }
+
+ /**
+ * Return the EditorRegistry for nested editor descriptors. Subclass should implements this method in order to return the registry associated to the extension point namespace.
+ *
+ * @return the EditorRegistry for nested editor descriptors
+ */
+ protected IEditorFactoryRegistry createEditorRegistry() {
+ return new EditorFactoryRegistry(Activator.PLUGIN_ID);
+ }
+
+ /**
+ *
+ *
+ * @param adapter
+ *
+ * @return
+ */
+ @Override
+ public Object getAdapter(Class adapter) {
+ if (IPropertySheetPage.class == adapter) {
+ // Do not test if tabbedPropertySheetPage is null before calling new
+ // this is managed by Eclipse which only call current method when necessary
+ tabbedPropertySheetPage = new TabbedPropertySheetPage(this);
+
+ return tabbedPropertySheetPage;
+ }
+
+ // Add a viewer
+ if (IContentOutlinePage.class == adapter) {
+ try {
+ IContentOutlinePage contentOutline = getContentOutlineRegistry().getContentOutline();
+ if (contentOutline != null)
+ return contentOutline;
+ } catch (BackboneException e) {
+ // TODO change next exception to more appropriate one
+ throw new RuntimeException(e);
+ }
+ }
+
+ if (BackboneContext.class == adapter) {
+ return defaultContext;
+ }
+
+ if (EditingDomain.class == adapter) {
+ return defaultContext.getTransactionalEditingDomain();
+ }
+
+ // GEF diagram requirements
+ if (adapter == ActionRegistry.class) {
+ return gefAdaptorDelegate.getActionRegistry();
+ }
+
+ // GEF diagram requirements
+ if (adapter == SelectionSynchronizer.class) {
+ return gefAdaptorDelegate.getSelectionSynchronizer();
+ }
+
+ // TODO : following code is GMF dependant. It should be moved to adapter
+ // Do we really need it? Who use it ?
+ if (adapter == IDiagramGraphicalViewer.class) {
+ IEditorPart activeEditor = getActiveEditor();
+ if (activeEditor instanceof DiagramEditor) {
+ return ((DiagramEditor) activeEditor).getDiagramGraphicalViewer();
+ }
+ return null;
+ }
+
+ return super.getAdapter(adapter);
+ }
+
+ /**
+ * Init the editor.
+ */
+ @Override
+ public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+
+ // Init super
+ super.init(site, input);
+
+ // Init this class
+ try {
+ defaultContext = createDefaultContext(site, input);
+ } catch (BackboneException e) {
+ throw new PartInitException("Can't create default context.", e);
+ }
+
+ // configureDiagramEditDomain();
+ EditingDomainService editingDomainService = new EditingDomainService(defaultContext);
+ editingDomainService.addCommandStackListener(commandStackListener);
+
+ // Load resources
+ IFile file = ((IFileEditorInput) input).getFile();
+ defaultContext.getResourceSet().loadResources(file);
+ diagramNotifier = defaultContext.createDiagramNotifier();
+
+ // Create Gef adaptor
+ gefAdaptorDelegate = new MultiDiagramEditorGefDelegate();
+
+ // Create registries
+ // editorContextRegistry should be created after site, input and defaultContext are created.
+ editorContextRegistry = createEditorContextRegistry();
+ editorContextRegistry.registerContext("defaultContext", defaultContext);
+ editorRegistry = createEditorRegistry();
+
+ // Set editor name
+ setPartName(file.getName());
+
+ }
+
+ /**
+ *
+ */
+ @Override
+ protected void activate() {
+ super.activate();
+ // Start listening on diagram CRUD
+ diagramNotifier.addListener(diagramChangeListener);
+ }
+
+ @Override
+ protected void deactivate() {
+ // Stop listening on diagrams CRUD
+ diagramNotifier.removeListener(diagramChangeListener);
+ super.deactivate();
+ }
+
+ /**
+ * Create the default context used to control models life cycles.
+ *
+ * @param site
+ * @param input
+ * @throws BackboneException
+ */
+ private BackboneContext createDefaultContext(IEditorSite site, IEditorInput input) throws BackboneException {
+ BackboneContext defaultContext = new BackboneContext();
+ defaultContext.init(this);
+
+ return defaultContext;
+ }
+
+ @Override
+ public void doSave(IProgressMonitor monitor) {
+ try {
+ // Save each associated resource
+ defaultContext.save(monitor);
+ markSaveLocation();
+ } catch (IOException ioe) {
+ }
+
+ }
+
+ /**
+ * Mark the command stack of all sub-editors. Default implementation do nothing.
+ */
+ protected void markSaveLocation() {
+ toSave = false;
+ getDiagramEditDomain().getCommandStack().markSaveLocation();
+ firePropertyChange(PROP_DIRTY);
+ }
+
+ /**
+ * Mark the editor as dirty, and fire appropriate event.
+ */
+ protected void markDirty() {
+ toSave = true;
+ firePropertyChange(PROP_DIRTY);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isDirty() {
+ return toSave;
+ // return getDiagramEditDomain().getDiagramCommandStack().isDirty();
+ }
+
+ @Override
+ public void doSaveAs() {
+ // Show a SaveAs dialog
+ toSave = false;
+ super.firePropertyChange(PROP_DIRTY);
+ Shell shell = getEditorSite().getWorkbenchWindow().getShell();
+ SaveAsDialog dialog = new SaveAsDialog(shell);
+ dialog.setOriginalFile(((IFileEditorInput) getEditorInput()).getFile());
+ dialog.open();
+ final IPath path = dialog.getResult();
+ if (path != null) {
+ // try to save the editor's contents under a different file name
+ final IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
+ try {
+ new ProgressMonitorDialog(shell).run(false, // don't fork
+ false, // not cancelable
+ new WorkspaceModifyOperation() { // run this operation
+
+ @Override
+ public void execute(final IProgressMonitor monitor) {
+ try {
+ defaultContext.saveAs(path);
+ } catch (IOException ioe) {
+ // Debug.log(ioe);
+ }
+ }
+ });
+ // set input to the new file
+ setInput(new FileEditorInput(file));
+ markSaveLocation();
+ } catch (InterruptedException ie) {
+ // should not happen, since the monitor dialog is not cancelable
+ ie.printStackTrace();
+ } catch (InvocationTargetException ite) {
+ ite.printStackTrace();
+ }
+ }
+
+ }
+
+ @Override
+ public boolean isSaveAsAllowed() {
+ return defaultContext.isSaveAsAllowed();
+ }
+
+ /**
+ * @see org.eclipse.papyrus.core.editor.IMultiDiagramEditor#getDefaultContext()
+ */
+ public BackboneContext getDefaultContext() {
+ return defaultContext;
+ }
+
+ public String getContributorId() {
+ // return Activator.PLUGIN_ID;
+ return "TreeOutlinePage";
+
+ }
+
+ // FIXME: Pour C�dric modif
+ public IEditorPart getActiveEditor() {
+ return super.getActiveEditor();
+ }
+
+ /**
+ * @TODO To be removed
+ */
+ // public class Test {
+ // MultiEditor mEditor;
+ // WorkbenchPage wpage;
+ // org.eclipse.ui.internal.EditorAreaHelper areaHelper;
+ // org.eclipse.ui.internal.EditorSashContainer sashContainer;
+ //
+ // TabbedStackPresentation tStackPresentation;
+ // }
+ /**
+ *
+ * @see org.eclipse.papyrus.sasheditor.sash.SashMultiPageEditorPart#createTilePartContainerModel()
+ */
+ @Override
+ protected ISashWindowsModelManager createTilePartContainerModel() {
+ SashDiagramModelManager mngr = new SashDiagramModelManager(getDefaultContext().getTransactionalEditingDomain(), getDefaultContext().getResourceSet().getDiResource());
+ return new SashWindowModelManagerWrapper(mngr);
+ }
+
+ /**
+ * Sets the default edit domain, shared among all editors
+ *
+ * @param diagramEditDomain
+ * the diagramEditDomain to set
+ */
+ public void setDiagramEditDomain(DiagramEditDomain diagramEditDomain) {
+ this.diagramEditDomain = diagramEditDomain;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public DiagramEditDomain getDiagramEditDomain() {
+ return diagramEditDomain;
+ }
+
+ // implements IDiagramWorkbenchPart to restore GMF standard behavior
+ // and delegate to the activeEditor
+ /**
+ * {@inheritDoc}
+ */
+ public Diagram getDiagram() {
+ IEditorPart activeEditor = getActiveEditor();
+ if (activeEditor instanceof DiagramEditor) {
+ return ((DiagramEditor) activeEditor).getDiagram();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public DiagramEditPart getDiagramEditPart() {
+ IEditorPart activeEditor = getActiveEditor();
+ if (activeEditor instanceof DiagramEditor) {
+ return ((DiagramEditor) activeEditor).getDiagramEditPart();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IDiagramGraphicalViewer getDiagramGraphicalViewer() {
+ IEditorPart activeEditor = getActiveEditor();
+ if (activeEditor instanceof DiagramEditor) {
+ return ((DiagramEditor) activeEditor).getDiagramGraphicalViewer();
+ } else {
+ return null;
+ }
+ }
+
+}

Back to the top