diff --git a/fr.centralesupelec.edf.riseclipse.editor/.classpath b/fr.centralesupelec.edf.riseclipse.editor/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..01836c4842f6560398b775d8fe0696fc95387dd7 --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.editor/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/fr.centralesupelec.edf.riseclipse.editor/.project b/fr.centralesupelec.edf.riseclipse.editor/.project new file mode 100644 index 0000000000000000000000000000000000000000..07d2f1c9bdb269a45c2e9344610fff5e74ca0770 --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.editor/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>fr.centralesupelec.edf.riseclipse.editor</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.pde.PluginNature</nature> + </natures> +</projectDescription> diff --git a/fr.centralesupelec.edf.riseclipse.editor/.settings/org.eclipse.jdt.core.prefs b/fr.centralesupelec.edf.riseclipse.editor/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..0c68a61dca867ceb49e79d2402935261ec3e3809 --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.editor/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/fr.centralesupelec.edf.riseclipse.editor/META-INF/MANIFEST.MF b/fr.centralesupelec.edf.riseclipse.editor/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..b935373ca784450f120200e47b6442586fe68d0e --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.editor/META-INF/MANIFEST.MF @@ -0,0 +1,19 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: fr.centralesupelec.edf.riseclipse.editor;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-ClassPath: . +Bundle-Activator: fr.centralesupelec.edf.riseclipse.ui.RiseClipseEditorPlugin$Implementation +Bundle-Vendor: %providerName +Bundle-Localization: plugin +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Export-Package: fr.centralesupelec.edf.riseclipse.ui +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.core.resources;visibility:=reexport, + org.eclipse.emf.edit.ui;visibility:=reexport, + org.eclipse.ui.ide;visibility:=reexport, + org.eclipse.ui.console, + fr.centralesupelec.edf.riseclipse.main, + org.eclipse.emf.ecore.xmi +Bundle-ActivationPolicy: lazy diff --git a/fr.centralesupelec.edf.riseclipse.editor/build.properties b/fr.centralesupelec.edf.riseclipse.editor/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..2ef34fd6c403cecad6499a511471c594d2b16074 --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.editor/build.properties @@ -0,0 +1,24 @@ +# +# Copyright (c) 2017 CentraleSupélec & EDF. +# 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 +# +# This file is part of the RiseClipse tool +# +# Contributors: +# Computer Science Department, CentraleSupélec : initial implementation +# Contacts: +# Dominique.Marcadet@centralesupelec.fr +# + +bin.includes = .,\ + icons/,\ + META-INF/,\ + plugin.xml,\ + plugin.properties +jars.compile.order = . +source.. = src/ +output.. = bin + diff --git a/fr.centralesupelec.edf.riseclipse.editor/icons/full/obj16/RiseClipseModelFile.gif b/fr.centralesupelec.edf.riseclipse.editor/icons/full/obj16/RiseClipseModelFile.gif new file mode 100644 index 0000000000000000000000000000000000000000..82d83d1334fc2f01a377e4a8a5c10a019bb10ff5 Binary files /dev/null and b/fr.centralesupelec.edf.riseclipse.editor/icons/full/obj16/RiseClipseModelFile.gif differ diff --git a/fr.centralesupelec.edf.riseclipse.editor/plugin.properties b/fr.centralesupelec.edf.riseclipse.editor/plugin.properties new file mode 100644 index 0000000000000000000000000000000000000000..5879d510e7df03d70ddfc7079243ec20bbd4662e --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.editor/plugin.properties @@ -0,0 +1,60 @@ +# +# Copyright (c) 2017 CentraleSupélec & EDF. +# 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 +# +# This file is part of the RiseClipse tool +# +# Contributors: +# Computer Science Department, CentraleSupélec : initial implementation +# Contacts: +# Dominique.Marcadet@centralesupelec.fr +# + + +pluginName = RiseClipse Editor +providerName = CentraleSupélec & EDF + +_UI_RiseClipseEditor_menu = &RiseClipse Editor + +_UI_CreateChild_menu_item = &New Child +_UI_CreateSibling_menu_item = N&ew Sibling + +_UI_ShowPropertiesView_menu_item = Show &Properties View +_UI_RefreshViewer_menu_item = &Refresh + +_UI_SelectionPage_label = Selection +_UI_ParentPage_label = Parent +_UI_ListPage_label = List +_UI_TreePage_label = Tree +_UI_TablePage_label = Table +_UI_TreeWithColumnsPage_label = Tree with Columns +_UI_ObjectColumn_label = Object +_UI_SelfColumn_label = Self + +_UI_NoObjectSelected = Selected Nothing +_UI_SingleObjectSelected = Selected Object: {0} +_UI_MultiObjectSelected = Selected {0} Objects + +_UI_OpenEditorError_label = Open Editor + +_UI_CreateModelError_message = Problems encountered in file "{0}" + +_UI_RiseClipseEditor_label = RiseClipse Model Editor + +_UI_RiseClipseEditorFilenameDefaultBase = model +_UI_RiseClipseEditorFilenameExtensions = xml + +_WARN_FilenameExtension = The file name must end in ''.{0}'' +_WARN_FilenameExtensions = The file name must have one of the following extensions: {0} + +_UI_ModelObject = &Model Object +_UI_XMLEncoding = &XML Encoding +_UI_XMLEncodingChoices = UTF-8 ASCII UTF-16 UTF-16BE UTF-16LE ISO-8859-1 +_UI_Wizard_initial_object_description = Select a model object to create + +_UI_FileConflict_label = File Conflict +_WARN_FileConflict = There are unsaved changes that conflict with changes made outside the editor. Do you wish to discard this editor's changes? + diff --git a/fr.centralesupelec.edf.riseclipse.editor/plugin.xml b/fr.centralesupelec.edf.riseclipse.editor/plugin.xml new file mode 100644 index 0000000000000000000000000000000000000000..4a3c723bd7672533c5f8a50cddcfeb93f59dca79 --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.editor/plugin.xml @@ -0,0 +1,109 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.0"?> + +<!-- +Copyright (c) 2017 CentraleSupélec & EDF. +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 +This file is part of the RiseClipse tool + +Contributors: + Computer Science Department, CentraleSupélec : initial implementation +Contacts: + Dominique.Marcadet@centralesupelec.fr +--> + +<plugin> + <extension point="org.eclipse.ui.editors"> + <editor + id="fr.centralesupelec.edf.riseclipse.editor.RiseClipseEditorID" + name="%_UI_RiseClipseEditor_label" + icon="icons/full/obj16/RiseClipseModelFile.gif" + extensions="xml" + class="fr.centralesupelec.edf.riseclipse.ui.RiseClipseEditor" + contributorClass="fr.centralesupelec.edf.riseclipse.ui.RiseClipseActionBarContributor"> + </editor> + </extension> + <extension + point="org.eclipse.ui.commands"> + <category + id="fr.centralesupelec.edf.riseclipse.editor.commands.category" + name="RiseClipse Category"> + </category> + <command + categoryId="fr.centralesupelec.edf.riseclipse.editor.commands.category" + id="fr.centralesupelec.edf.riseclipse.editor.commands.navigateTo" + name="Navigate to"> + </command> + <command + id="fr.centralesupelec.edf.riseclipse.editor.commands.displayStatistics" + name="Display Statistics"> + </command> + </extension> + <extension + point="org.eclipse.ui.handlers"> + <handler + class="fr.centralesupelec.edf.riseclipse.editor.handlers.NavigateToHandler" + commandId="fr.centralesupelec.edf.riseclipse.editor.commands.navigateTo"> + </handler> + <handler + class="fr.centralesupelec.edf.riseclipse.editor.handlers.displayStatisticsHandler" + commandId="fr.centralesupelec.edf.riseclipse.editor.commands.displayStatistics"> + </handler> + </extension> + <extension + point="org.eclipse.ui.menus"> + <menuContribution + locationURI="popup:org.eclipse.ui.popup.any?before=additions"> + <menu + id="fr.centralesupelec.edf.riseclipse.editor.popup.navigateToID" + label="Selected object"> + <dynamic + class="fr.centralesupelec.edf.riseclipse.editor.handlers.NavigateToMenuBuilder" + id="fr.centralesupelec.edf.riseclipse.editor.commands.navigateTo.dynamic"> + <visibleWhen> + <with + variable="activeMenuSelection"> + <iterate> + <adapt + type="org.eclipse.emf.ecore.EObject"> + </adapt> + </iterate> + </with> + </visibleWhen> + </dynamic> + <visibleWhen> + <with + variable="activeMenuSelection"> + <iterate> + <adapt + type="org.eclipse.emf.ecore.EObject"> + </adapt> + </iterate> + </with> + </visibleWhen> + </menu> + </menuContribution> + <menuContribution + locationURI="menu:org.eclipse.ui.main.menu?after=additions"> + <menu + id="fr.centralesupelec.edf.riseclipse.editor.riseclipseMenuID" + label="RiseClipse"> + <separator + name="tools"> + </separator> + </menu> + </menuContribution> + <menuContribution + locationURI="menu:fr.centralesupelec.edf.riseclipse.editor.riseclipseMenuID?after=tools"> + <command + commandId="fr.centralesupelec.edf.riseclipse.editor.commands.displayStatistics" + label="Display Statistics" + style="push"> + </command> + </menuContribution> + </extension> + +</plugin> diff --git a/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/editor/handlers/NavigateToHandler.java b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/editor/handlers/NavigateToHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..ea8b0b89302fb15e0f59c764cba47ba553fea388 --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/editor/handlers/NavigateToHandler.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2017 CentraleSupélec & EDF. + * 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 + * + * This file is part of the RiseClipse tool + * + * Contributors: + * Computer Science Department, CentraleSupélec : initial implementation + * Contacts: + * Dominique.Marcadet@centralesupelec.fr + */ +package fr.centralesupelec.edf.riseclipse.editor.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.swt.widgets.Event; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.menus.CommandContributionItem; + +import fr.centralesupelec.edf.riseclipse.ui.RiseClipseEditor; + +public class NavigateToHandler extends AbstractHandler { + + public NavigateToHandler() { + } + + @Override + public Object execute( ExecutionEvent event ) throws ExecutionException { + RiseClipseEditor e = ( RiseClipseEditor ) HandlerUtil.getActiveEditor( event ); + Event v = ( Event ) event.getTrigger(); + CommandContributionItem c = ( CommandContributionItem ) v.widget.getData(); + e.navigateTo( c ); + return null; + } + + +} diff --git a/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/editor/handlers/NavigateToMenuBuilder.java b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/editor/handlers/NavigateToMenuBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..fa56f6218c848f900f7d3f031397332c52e049e0 --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/editor/handlers/NavigateToMenuBuilder.java @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2017 CentraleSupélec & EDF. + * 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 + * + * This file is part of the RiseClipse tool + * + * Contributors: + * Computer Science Department, CentraleSupélec : initial implementation + * Contacts: + * Dominique.Marcadet@centralesupelec.fr + */ +package fr.centralesupelec.edf.riseclipse.editor.handlers; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.edit.provider.IItemLabelProvider; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.CompoundContributionItem; +import org.eclipse.ui.menus.CommandContributionItem; +import org.eclipse.ui.menus.CommandContributionItemParameter; +import org.eclipse.ui.menus.IWorkbenchContribution; +import org.eclipse.ui.services.IServiceLocator; + +import fr.centralesupelec.edf.riseclipse.ui.RiseClipseEditor; + +public class NavigateToMenuBuilder extends CompoundContributionItem implements IWorkbenchContribution { + + private IServiceLocator serviceLocator; + + public NavigateToMenuBuilder() { + } + + // from CompoundContributionItem + @Override + protected IContributionItem[] getContributionItems() { + + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if( ! ( window.getActivePage().getActiveEditor() instanceof RiseClipseEditor )) return null; + RiseClipseEditor editor = ( RiseClipseEditor ) window.getActivePage().getActiveEditor(); + + ISelection selection = window.getActivePage().getSelection(); + if( ! ( selection instanceof TreeSelection )) return null; + + TreeSelection tree = ( TreeSelection ) selection; + if( ! ( tree.getFirstElement() instanceof EObject )) return null; + + IContributionItem[] items = new IContributionItem[1]; + MenuManager navigateTo = new MenuManager( "Navigate to" ); + items[0] = navigateTo; + + EObject o = ( EObject ) tree.getFirstElement(); + AdapterFactory adapter = editor.getAdapterFactory( o.eClass().getEPackage().getNsURI() ); + EList< EReference > refs = o.eClass().getEAllReferences(); + ArrayList< EReference > usedRefs = new ArrayList< EReference >(); + ArrayList< Object > values = new ArrayList< Object >(); + for( EReference r : refs ) { + Object v = o.eGet( r ); + if( v != null ) { + usedRefs.add( r ); + values.add( v ); + } + } + IContributionItem[] list = new IContributionItem[usedRefs.size()]; + // We need to get back the referenced eObject when the command is executed. + // As it seems that there is no way to associate an arbitrary object to + // the command, we build a map and give it to the editor + Map< CommandContributionItem, Object > map = new HashMap< CommandContributionItem, Object >(); + for( int i = 0; i < list.length; ++i ) { + MenuManager ref = new MenuManager( usedRefs.get( i ).getName() ); + int numberOfRefs = 1; + if( values.get( i ) instanceof EList ) { + numberOfRefs = (( EList< ? > ) values.get( i )).size(); + } + for( int j = 0; j < numberOfRefs; ++j ) { + CommandContributionItemParameter contributionParameters = new CommandContributionItemParameter( + serviceLocator, null, "fr.centralesupelec.edf.riseclipse.editor.commands.navigateTo", + CommandContributionItem.STYLE_PUSH ); + Object val; + if( values.get( i ) instanceof EList ) { + val = (( EList< ? > ) values.get( i )).get( j ); + } + else { + val = values.get( i ); + } + IItemLabelProvider labelProvider = ( IItemLabelProvider ) adapter.adapt( val, IItemLabelProvider.class ); + contributionParameters.label = labelProvider.getText( val ); + CommandContributionItem c = new CommandContributionItem( contributionParameters ); + map.put( c, val ); + ref.add( c ); + + } + navigateTo.add( ref ); + } + + editor.setNavigateToMap( map ); + return items; + } + + // from IWorkbenchContribution + @Override + public void initialize( IServiceLocator serviceLocator ) { + this.serviceLocator = serviceLocator; + } + +} diff --git a/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/editor/handlers/displayStatisticsHandler.java b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/editor/handlers/displayStatisticsHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..9d5b2bcbe0dfcdfcfb60fa9edfd0d41458e57fd7 --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/editor/handlers/displayStatisticsHandler.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2017 CentraleSupélec & EDF. + * 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 + * + * This file is part of the RiseClipse tool + * + * Contributors: + * Computer Science Department, CentraleSupélec : initial implementation + * Contacts: + * Dominique.Marcadet@centralesupelec.fr + */ +package fr.centralesupelec.edf.riseclipse.editor.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.ui.handlers.HandlerUtil; + +import fr.centralesupelec.edf.riseclipse.ui.RiseClipseEditor; +import fr.centralesupelec.edf.riseclipse.util.AbstractRiseClipseConsole; +import fr.centralesupelec.edf.riseclipse.util.IRiseClipseResource; + +public class displayStatisticsHandler extends AbstractHandler { + + @Override + public Object execute( ExecutionEvent event ) throws ExecutionException { + RiseClipseEditor e = ( RiseClipseEditor ) HandlerUtil.getActiveEditor( event ); + ResourceSet r = e.getEditingDomain().getResourceSet(); + for( int i = 0; i < r.getResources().size(); ++i ) { + Resource c = r.getResources().get( i ); + if( c instanceof IRiseClipseResource ) { + (( IRiseClipseResource ) c ).printStatistics( AbstractRiseClipseConsole.getConsole() ); + } + } + + return null; + } + +} diff --git a/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/EclipseRiseClipseConsole.java b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/EclipseRiseClipseConsole.java new file mode 100644 index 0000000000000000000000000000000000000000..4c8e7ebc9bbd8e226ec0a40c4f1fbe6fae160bf4 --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/EclipseRiseClipseConsole.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2017 CentraleSupélec & EDF. + * 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 + * + * This file is part of the RiseClipse tool + * + * Contributors: + * Computer Science Department, CentraleSupélec : initial implementation + * Contacts: + * Dominique.Marcadet@centralesupelec.fr + */ +package fr.centralesupelec.edf.riseclipse.ui; + +import java.io.IOException; +import java.io.PrintStream; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.ui.console.ConsolePlugin; +import org.eclipse.ui.console.IConsole; +import org.eclipse.ui.console.IConsoleManager; +import org.eclipse.ui.console.MessageConsole; +import org.eclipse.ui.console.MessageConsoleStream; + +import fr.centralesupelec.edf.riseclipse.util.AbstractRiseClipseConsole; +import fr.centralesupelec.edf.riseclipse.util.IRiseClipseConsole; + +public class EclipseRiseClipseConsole extends AbstractRiseClipseConsole { + + public static final IRiseClipseConsole INSTANCE = new EclipseRiseClipseConsole(); + + private static final String ConsoleName = "RiseClipseConsole"; + + private MessageConsole findConsole() { + if( !Platform.isRunning() ) return null; + + ConsolePlugin plugin = ConsolePlugin.getDefault(); + // Got null if running as Java instead of running as Eclipse + if( plugin == null ) return null; + IConsoleManager conMan = plugin.getConsoleManager(); + IConsole[] existing = conMan.getConsoles(); + for( int i = 0; i < existing.length; i++ ) { + if( ConsoleName.equals( existing[i].getName() )) { + return ( MessageConsole ) existing[i]; + } + } + // no console found, so create a new one + MessageConsole myConsole = new MessageConsole( ConsoleName, null ); + conMan.addConsoles( new IConsole[] { myConsole } ); + return myConsole; + } + + private void out( String message, PrintStream std ) { + MessageConsole myConsole = findConsole(); + if( myConsole == null ) { + std.println( message ); + std.flush(); + return; + } + MessageConsoleStream stream = myConsole.newMessageStream(); + stream.println( message ); + try { + stream.flush(); + } + catch( IOException e ) { + } + } + + @Override + protected void doOutputMessage( String m ) { + out( m, System.out ); + } +} diff --git a/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/RiseClipseActionBarContributor.java b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/RiseClipseActionBarContributor.java new file mode 100644 index 0000000000000000000000000000000000000000..5be84eec9a9c007137a19adf3ad7639aa279aefc --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/RiseClipseActionBarContributor.java @@ -0,0 +1,387 @@ +/** + * Copyright (c) 2017 CentraleSupélec & EDF. + * 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 + * + * This file is part of the RiseClipse tool + * + * Contributors: + * Computer Science Department, CentraleSupélec : initial implementation + * Contacts: + * Dominique.Marcadet@centralesupelec.fr + */ +package fr.centralesupelec.edf.riseclipse.ui; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.emf.common.ui.viewer.IViewerProvider; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.emf.edit.domain.IEditingDomainProvider; +import org.eclipse.emf.edit.ui.action.ControlAction; +import org.eclipse.emf.edit.ui.action.CreateChildAction; +import org.eclipse.emf.edit.ui.action.CreateSiblingAction; +import org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor; +import org.eclipse.emf.edit.ui.action.LoadResourceAction; +import org.eclipse.emf.edit.ui.action.ValidateAction; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IContributionManager; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.action.SubContributionItem; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.PartInitException; + +/** + * This is the action bar contributor for the RiseClipse editor. + */ +public class RiseClipseActionBarContributor extends EditingDomainActionBarContributor implements + ISelectionChangedListener { + /** + * This keeps track of the active editor. + */ + protected IEditorPart activeEditorPart; + + /** + * This keeps track of the current selection provider. + */ + protected ISelectionProvider selectionProvider; + + /** + * This action opens the Properties view. + */ + protected IAction showPropertiesViewAction = new Action( + RiseClipseEditorPlugin.INSTANCE.getString( "_UI_ShowPropertiesView_menu_item" ) ) { + @Override + public void run() { + try { + getPage().showView( "org.eclipse.ui.views.PropertySheet" ); + } + catch( PartInitException exception ) { + RiseClipseEditorPlugin.INSTANCE.log( exception ); + } + } + }; + + /** + * This action refreshes the viewer of the current editor if the editor + * implements {@link org.eclipse.emf.common.ui.viewer.IViewerProvider}. + */ + protected IAction refreshViewerAction = new Action( + RiseClipseEditorPlugin.INSTANCE.getString( "_UI_RefreshViewer_menu_item" ) ) { + @Override + public boolean isEnabled() { + return activeEditorPart instanceof IViewerProvider; + } + + @Override + public void run() { + if( activeEditorPart instanceof IViewerProvider ) { + Viewer viewer = ( ( IViewerProvider ) activeEditorPart ).getViewer(); + if( viewer != null ) { + viewer.refresh(); + } + } + } + }; + + /** + * This will contain one + * {@link org.eclipse.emf.edit.ui.action.CreateChildAction} corresponding to + * each descriptor generated for the current selection by the item provider. + */ + protected Collection< IAction > createChildActions; + + /** + * This is the menu manager into which menu contribution items should be + * added for CreateChild actions. + */ + protected IMenuManager createChildMenuManager; + + /** + * This will contain one + * {@link org.eclipse.emf.edit.ui.action.CreateSiblingAction} corresponding + * to each descriptor generated for the current selection by the item + * provider. + */ + protected Collection< IAction > createSiblingActions; + + /** + * This is the menu manager into which menu contribution items should be + * added for CreateSibling actions. + */ + protected IMenuManager createSiblingMenuManager; + + /** + * This creates an instance of the contributor. + */ + public RiseClipseActionBarContributor() { + super( ADDITIONS_LAST_STYLE ); + loadResourceAction = new LoadResourceAction(); + validateAction = new ValidateAction(); + controlAction = new ControlAction(); + } + + /** + * This adds Separators for editor additions to the tool bar. + */ + @Override + public void contributeToToolBar( IToolBarManager toolBarManager ) { + toolBarManager.add( new Separator( "riseclipse-settings" ) ); + toolBarManager.add( new Separator( "riseclipse-additions" ) ); + } + + /** + * This adds to the menu bar a menu and some separators for editor + * additions, as well as the sub-menus for object creation items. + */ + @Override + public void contributeToMenu( IMenuManager menuManager ) { + super.contributeToMenu( menuManager ); + + // RiseClipseSpecific: we do our own menu + // +// IMenuManager submenuManager = new MenuManager( +// RiseClipseEditorPlugin.INSTANCE.getString( "_UI_RiseClipseEditor_menu" ), +// "fr.centralesupelec.edf.riseclipse.editor.riseclipseMenuID" ); +// menuManager.insertAfter( "additions", submenuManager ); +// submenuManager.add( new Separator( "settings" ) ); +// submenuManager.add( new Separator( "actions" ) ); +// submenuManager.add( new Separator( "additions" ) ); +// submenuManager.add( new Separator( "additions-end" ) ); +// +// // Prepare for CreateChild item addition or removal. +// // +// createChildMenuManager = new MenuManager( +// RiseClipseEditorPlugin.INSTANCE.getString( "_UI_CreateChild_menu_item" ) ); +// submenuManager.insertBefore( "additions", createChildMenuManager ); +// +// // Prepare for CreateSibling item addition or removal. +// // +// createSiblingMenuManager = new MenuManager( +// RiseClipseEditorPlugin.INSTANCE.getString( "_UI_CreateSibling_menu_item" ) ); +// submenuManager.insertBefore( "additions", createSiblingMenuManager ); +// +// // Force an update because Eclipse hides empty menus now. +// // +// submenuManager.addMenuListener( new IMenuListener() { +// public void menuAboutToShow( IMenuManager menuManager ) { +// menuManager.updateAll( true ); +// } +// } ); +// +// addGlobalActions( submenuManager ); + } + + /** + * When the active editor changes, this remembers the change and registers + * with it as a selection provider. + */ + @Override + public void setActiveEditor( IEditorPart part ) { + super.setActiveEditor( part ); + activeEditorPart = part; + + // Switch to the new selection provider. + // + if( selectionProvider != null ) { + selectionProvider.removeSelectionChangedListener( this ); + } + if( part == null ) { + selectionProvider = null; + } + else { + selectionProvider = part.getSite().getSelectionProvider(); + selectionProvider.addSelectionChangedListener( this ); + + // Fake a selection changed event to update the menus. + // + if( selectionProvider.getSelection() != null ) { + selectionChanged( new SelectionChangedEvent( selectionProvider, selectionProvider.getSelection() ) ); + } + } + } + + /** + * This implements + * {@link org.eclipse.jface.viewers.ISelectionChangedListener}, handling + * {@link org.eclipse.jface.viewers.SelectionChangedEvent}s by querying for + * the children and siblings that can be added to the selected object and + * updating the menus accordingly. + */ + public void selectionChanged( SelectionChangedEvent event ) { + // Remove any menu items for old selection. + // + if( createChildMenuManager != null ) { + depopulateManager( createChildMenuManager, createChildActions ); + } + if( createSiblingMenuManager != null ) { + depopulateManager( createSiblingMenuManager, createSiblingActions ); + } + + // Query the new selection for appropriate new child/sibling descriptors + // + Collection< ? > newChildDescriptors = null; + Collection< ? > newSiblingDescriptors = null; + + ISelection selection = event.getSelection(); + if( selection instanceof IStructuredSelection && ( ( IStructuredSelection ) selection ).size() == 1 ) { + Object object = ( ( IStructuredSelection ) selection ).getFirstElement(); + + EditingDomain domain = ( ( IEditingDomainProvider ) activeEditorPart ).getEditingDomain(); + + newChildDescriptors = domain.getNewChildDescriptors( object, null ); + newSiblingDescriptors = domain.getNewChildDescriptors( null, object ); + } + + // Generate actions for selection; populate and redraw the menus. + // + createChildActions = generateCreateChildActions( newChildDescriptors, selection ); + createSiblingActions = generateCreateSiblingActions( newSiblingDescriptors, selection ); + + if( createChildMenuManager != null ) { + populateManager( createChildMenuManager, createChildActions, null ); + createChildMenuManager.update( true ); + } + if( createSiblingMenuManager != null ) { + populateManager( createSiblingMenuManager, createSiblingActions, null ); + createSiblingMenuManager.update( true ); + } + } + + /** + * This generates a {@link org.eclipse.emf.edit.ui.action.CreateChildAction} + * for each object in <code>descriptors</code>, and returns the collection + * of these actions. + */ + protected Collection< IAction > generateCreateChildActions( Collection< ? > descriptors, ISelection selection ) { + Collection< IAction > actions = new ArrayList< IAction >(); + if( descriptors != null ) { + for( Object descriptor : descriptors ) { + actions.add( new CreateChildAction( activeEditorPart, selection, descriptor ) ); + } + } + return actions; + } + + /** + * This generates a + * {@link org.eclipse.emf.edit.ui.action.CreateSiblingAction} for each + * object in <code>descriptors</code>, and returns the collection of these + * actions. + */ + protected Collection< IAction > generateCreateSiblingActions( Collection< ? > descriptors, ISelection selection ) { + Collection< IAction > actions = new ArrayList< IAction >(); + if( descriptors != null ) { + for( Object descriptor : descriptors ) { + actions.add( new CreateSiblingAction( activeEditorPart, selection, descriptor ) ); + } + } + return actions; + } + + /** + * This populates the specified <code>manager</code> with + * {@link org.eclipse.jface.action.ActionContributionItem}s based on the + * {@link org.eclipse.jface.action.IAction}s contained in the + * <code>actions</code> collection, by inserting them before the specified + * contribution item <code>contributionID</code>. If + * <code>contributionID</code> is <code>null</code>, they are simply added. + */ + protected void populateManager( IContributionManager manager, Collection< ? extends IAction > actions, + String contributionID ) { + if( actions != null ) { + for( IAction action : actions ) { + if( contributionID != null ) { + manager.insertBefore( contributionID, action ); + } + else { + manager.add( action ); + } + } + } + } + + /** + * This removes from the specified <code>manager</code> all + * {@link org.eclipse.jface.action.ActionContributionItem}s based on the + * {@link org.eclipse.jface.action.IAction}s contained in the + * <code>actions</code> collection. + */ + protected void depopulateManager( IContributionManager manager, Collection< ? extends IAction > actions ) { + if( actions != null ) { + IContributionItem[] items = manager.getItems(); + for( int i = 0; i < items.length; i++ ) { + // Look into SubContributionItems + // + IContributionItem contributionItem = items[i]; + while( contributionItem instanceof SubContributionItem ) { + contributionItem = ( ( SubContributionItem ) contributionItem ).getInnerItem(); + } + + // Delete the ActionContributionItems with matching action. + // + if( contributionItem instanceof ActionContributionItem ) { + IAction action = ( ( ActionContributionItem ) contributionItem ).getAction(); + if( actions.contains( action ) ) { + manager.remove( contributionItem ); + } + } + } + } + } + + /** + * This populates the pop-up menu before it appears. + */ + @Override + public void menuAboutToShow( IMenuManager menuManager ) { + super.menuAboutToShow( menuManager ); + MenuManager submenuManager = null; + + submenuManager = new MenuManager( RiseClipseEditorPlugin.INSTANCE.getString( "_UI_CreateChild_menu_item" ) ); + populateManager( submenuManager, createChildActions, null ); + menuManager.insertBefore( "edit", submenuManager ); + + submenuManager = new MenuManager( RiseClipseEditorPlugin.INSTANCE.getString( "_UI_CreateSibling_menu_item" ) ); + populateManager( submenuManager, createSiblingActions, null ); + menuManager.insertBefore( "edit", submenuManager ); + } + + /** + * This inserts global actions before the "additions-end" separator. + */ + @Override + protected void addGlobalActions( IMenuManager menuManager ) { + menuManager.insertAfter( "additions-end", new Separator( "ui-actions" ) ); + menuManager.insertAfter( "ui-actions", showPropertiesViewAction ); + + refreshViewerAction.setEnabled( refreshViewerAction.isEnabled() ); + menuManager.insertAfter( "ui-actions", refreshViewerAction ); + + super.addGlobalActions( menuManager ); + } + + /** + * This ensures that a delete action will clean up all references to deleted + * objects. + */ + @Override + protected boolean removeAllReferencesOnDelete() { + return true; + } + +} diff --git a/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/RiseClipseAdapterFactoryEditingDomain.java b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/RiseClipseAdapterFactoryEditingDomain.java new file mode 100644 index 0000000000000000000000000000000000000000..8dbad2d418b9a9f76f84a8e67e78985e0504ae3d --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/RiseClipseAdapterFactoryEditingDomain.java @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2017 CentraleSupélec & EDF. + * 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 + * + * This file is part of the RiseClipse tool + * + * Contributors: + * Computer Science Department, CentraleSupélec : initial implementation + * Contacts: + * Dominique.Marcadet@centralesupelec.fr + */ +package fr.centralesupelec.edf.riseclipse.ui; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.emf.common.command.BasicCommandStack; +import org.eclipse.emf.common.command.CommandStack; +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.Resource.Factory; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.emf.edit.domain.IEditingDomainProvider; +import org.eclipse.emf.edit.provider.ComposedAdapterFactory; +import fr.centralesupelec.edf.riseclipse.util.RiseClipseResourceSet; + +public class RiseClipseAdapterFactoryEditingDomain extends AdapterFactoryEditingDomain { + + public RiseClipseAdapterFactoryEditingDomain( AdapterFactory adapterFactory, CommandStack commandStack, + Map< Resource, Boolean > resourceToReadOnlyMap, HashMap< String, Resource.Factory > factories ) { + super( adapterFactory, commandStack, resourceToReadOnlyMap ); + // We use RiseClipse specific ResourceSet + this.resourceSet = new LocalResourceSet( factories ); + } + + public RiseClipseAdapterFactoryEditingDomain( AdapterFactory adapterFactory, CommandStack commandStack, + ResourceSet resourceSet, HashMap< String, Resource.Factory > factories ) { + super( adapterFactory, commandStack, resourceSet ); + // TODO: ?? + throw new RuntimeException( "RiseClipseAdapterFactoryEditingDomain got a resourceSet" ); + } + + public RiseClipseAdapterFactoryEditingDomain( AdapterFactory adapterFactory, CommandStack commandStack, + HashMap< String, Resource.Factory > factories ) { + super( adapterFactory, commandStack ); + + // We use RiseClipse specific ResourceSet + this.resourceSet = new LocalResourceSet( factories ); + } + + public RiseClipseAdapterFactoryEditingDomain( ComposedAdapterFactory adapterFactory, + BasicCommandStack commandStack, HashMap< Resource, Boolean > hashMap, + HashMap< String, Resource.Factory > factories ) { + super( adapterFactory, commandStack, hashMap ); + + // We use RiseClipse specific ResourceSet + this.resourceSet = new LocalResourceSet( factories ); + } + + // From + // org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain.AdapterFactoryEditingDomainResourceSet + protected class LocalResourceSet extends RiseClipseResourceSet implements IEditingDomainProvider { + + LocalResourceSet( HashMap< String, Factory > resourceFactories ) { + super( resourceFactories ); + } + + public EditingDomain getEditingDomain() { + return RiseClipseAdapterFactoryEditingDomain.this; + } + + } + +} diff --git a/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/RiseClipseEditor.java b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/RiseClipseEditor.java new file mode 100644 index 0000000000000000000000000000000000000000..eaf6d42a8712d948f4531199c24c7d15badce791 --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/RiseClipseEditor.java @@ -0,0 +1,1655 @@ +/** + * Copyright (c) 2017 CentraleSupélec & EDF. + * 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 + * + * This file is part of the RiseClipse tool + * + * Contributors: + * Computer Science Department, CentraleSupélec : initial implementation + * Contacts: + * Dominique.Marcadet@centralesupelec.fr + */ +package fr.centralesupelec.edf.riseclipse.ui; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.EventObject; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceDeltaVisitor; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.util.LocalSelectionTransfer; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ListViewer; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.FileTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.dialogs.SaveAsDialog; +import org.eclipse.ui.ide.IGotoMarker; +import org.eclipse.ui.menus.CommandContributionItem; +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.part.MultiPageEditorPart; +import org.eclipse.ui.views.contentoutline.ContentOutline; +import org.eclipse.ui.views.contentoutline.ContentOutlinePage; +import org.eclipse.ui.views.contentoutline.IContentOutlinePage; +import org.eclipse.ui.views.properties.IPropertySheetPage; +import org.eclipse.ui.views.properties.PropertySheet; +import org.eclipse.ui.views.properties.PropertySheetPage; +import org.eclipse.emf.common.command.BasicCommandStack; +import org.eclipse.emf.common.command.Command; +import org.eclipse.emf.common.command.CommandStack; +import org.eclipse.emf.common.command.CommandStackListener; +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.ui.MarkerHelper; +import org.eclipse.emf.common.ui.ViewerPane; +import org.eclipse.emf.common.ui.editor.ProblemEditorPart; +import org.eclipse.emf.common.ui.viewer.IViewerProvider; +import org.eclipse.emf.common.util.BasicDiagnostic; +import org.eclipse.emf.common.util.Diagnostic; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.Resource.Factory; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.util.EContentAdapter; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.xmi.IllegalValueException; +import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.emf.edit.domain.IEditingDomainProvider; +import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator; +import org.eclipse.emf.edit.provider.ComposedAdapterFactory; +import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory; +import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory; +import org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor; +import org.eclipse.emf.edit.ui.celleditor.AdapterFactoryTreeEditor; +import org.eclipse.emf.edit.ui.dnd.EditingDomainViewerDropAdapter; +import org.eclipse.emf.edit.ui.dnd.LocalTransfer; +import org.eclipse.emf.edit.ui.dnd.ViewerDragAdapter; +import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider; +import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; +import org.eclipse.emf.edit.ui.provider.UnwrappingSelectionProvider; +import org.eclipse.emf.edit.ui.util.EditUIMarkerHelper; +import org.eclipse.emf.edit.ui.util.EditUIUtil; +import org.eclipse.emf.edit.ui.view.ExtendedPropertySheetPage; +import org.eclipse.ui.actions.WorkspaceModifyOperation; + +import fr.centralesupelec.edf.riseclipse.util.IRiseClipseConsole; +import fr.centralesupelec.edf.riseclipse.util.IRiseClipseResource; + +/** + * The base is the EMF generated editor + */ +public class RiseClipseEditor extends MultiPageEditorPart implements IEditingDomainProvider, ISelectionProvider, + IMenuListener, IViewerProvider, IGotoMarker { + /** + * This keeps track of the editing domain that is used to track all changes + * to the model. + */ + protected AdapterFactoryEditingDomain editingDomain; + + /** + * This is the one adapter factory used for providing views of the model. + */ + protected ComposedAdapterFactory adapterFactory; + + /** + * This is the content outline page. + */ + protected IContentOutlinePage contentOutlinePage; + + /** + * This is a kludge... + */ + protected IStatusLineManager contentOutlineStatusLineManager; + + /** + * This is the content outline page's viewer. + */ + protected TreeViewer contentOutlineViewer; + + /** + * This is the property sheet page. + */ + protected List< PropertySheetPage > propertySheetPages = new ArrayList< PropertySheetPage >(); + + /** + * This is the viewer that shadows the selection in the content outline. The + * parent relation must be correctly defined for this to work. + */ + protected TreeViewer selectionViewer; + + /** + * This inverts the roll of parent and child in the content provider and + * show parents as a tree. + */ + protected TreeViewer parentViewer; + + /** + * This shows how a tree view works. + */ + protected TreeViewer treeViewer; + + /** + * This shows how a list view works. A list viewer doesn't support icons. + */ + protected ListViewer listViewer; + + /** + * This shows how a table view works. A table can be used as a list with + * icons. + */ + protected TableViewer tableViewer; + + /** + * This shows how a tree view with columns works. + */ + protected TreeViewer treeViewerWithColumns; + + /** + * This keeps track of the active viewer pane, in the book. + */ + protected ViewerPane currentViewerPane; + + /** + * This keeps track of the active content viewer, which may be either one of + * the viewers in the pages or the content outline viewer. + */ + protected Viewer currentViewer; + + /** + * This listens to which ever viewer is active. + */ + protected ISelectionChangedListener selectionChangedListener; + + /** + * This keeps track of all the + * {@link org.eclipse.jface.viewers.ISelectionChangedListener}s that are + * listening to this editor. + */ + protected Collection< ISelectionChangedListener > selectionChangedListeners = new ArrayList< ISelectionChangedListener >(); + + /** + * This keeps track of the selection of the editor as a whole. + */ + protected ISelection editorSelection = StructuredSelection.EMPTY; + + /** + * The MarkerHelper is responsible for creating workspace resource markers + * presented in Eclipse's Problems View. + */ + protected MarkerHelper markerHelper = new EditUIMarkerHelper(); + + /** + * This listens for when the outline becomes active + */ + protected IPartListener partListener = new IPartListener() { + public void partActivated( IWorkbenchPart p ) { + if( p instanceof ContentOutline ) { + if( ( ( ContentOutline ) p ).getCurrentPage() == contentOutlinePage ) { + getActionBarContributor().setActiveEditor( RiseClipseEditor.this ); + + setCurrentViewer( contentOutlineViewer ); + } + } + else if( p instanceof PropertySheet ) { + if( propertySheetPages.contains( ( ( PropertySheet ) p ).getCurrentPage() ) ) { + getActionBarContributor().setActiveEditor( RiseClipseEditor.this ); + handleActivate(); + } + } + else if( p == RiseClipseEditor.this ) { + handleActivate(); + } + } + + public void partBroughtToTop( IWorkbenchPart p ) { + // Ignore. + } + + public void partClosed( IWorkbenchPart p ) { + // Ignore. + } + + public void partDeactivated( IWorkbenchPart p ) { + // Ignore. + } + + public void partOpened( IWorkbenchPart p ) { + // Ignore. + } + }; + + /** + * Resources that have been removed since last activation. + */ + protected Collection< Resource > removedResources = new ArrayList< Resource >(); + + /** + * Resources that have been changed since last activation. + */ + protected Collection< Resource > changedResources = new ArrayList< Resource >(); + + /** + * Resources that have been saved. + */ + protected Collection< Resource > savedResources = new ArrayList< Resource >(); + + /** + * Map to store the diagnostic associated with a resource. + */ + protected Map< Resource, Diagnostic > resourceToDiagnosticMap = new LinkedHashMap< Resource, Diagnostic >(); + + /** + * Controls whether the problem indication should be updated. + */ + protected boolean updateProblemIndication = true; + + + /* + * RiseClipseSpecific begin + */ + private static class RiseClipseMetaModel { + private String name; + private AdapterFactory adapterFactory; + private Resource.Factory resourceFactory; + private ViewerFilter viewerFilter; + + public RiseClipseMetaModel( String name, AdapterFactory adapterFactory, + Factory resourceFactory, ViewerFilter filter ) { + super(); + this.name = name; + this.adapterFactory = adapterFactory; + this.resourceFactory = resourceFactory; + this.viewerFilter = filter; + } + + @SuppressWarnings( "unused" ) + public String getName() { + return name; + } + + public AdapterFactory getAdapterFactory() { + return adapterFactory; + } + + public Resource.Factory getResourceFactory() { + return resourceFactory; + } + + public ViewerFilter getViewerFilter() { + return viewerFilter; + } + + } + protected HashMap< String, RiseClipseMetaModel > knownMetamodels = new HashMap< String, RiseClipseMetaModel >(); + + public AdapterFactory getAdapterFactory( String uri ) { + RiseClipseMetaModel mm = knownMetamodels.get( uri ); + if( mm == null ) mm = knownMetamodels.get( uri + '#' ); + if( mm == null ) return null; + return mm.getAdapterFactory(); + } + + public ViewerFilter getViewerFilter( String uri ) { + RiseClipseMetaModel mm = knownMetamodels.get( uri ); + if( mm == null ) mm = knownMetamodels.get( uri + '#' ); + if( mm == null ) return null; + return mm.getViewerFilter(); + } + + private Map< CommandContributionItem, Object > navigateToMap = null; + + public void setNavigateToMap( Map< CommandContributionItem, Object > map ) { + navigateToMap = map; + } + + public void navigateTo( CommandContributionItem command ) { + navigateTo( navigateToMap.get( command )); + } + + public void navigateTo( Object o ) { + if( o == null ) return; + // reveal will work only if the parent is itself revealed. + // if the parent is o.eContainer(), it's OK. + // Otherwise, getParent() in the appropriate subclass of ItemProviderAdapter + // must be correctly defined. + selectionViewer.reveal( o ); + selectionViewer.setSelection( + new TreeSelection( new TreePath( new Object[]{ o })), + true ); + } + + /* + * RiseClipseSpecific end + */ + + /** + * Adapter used to update the problem indication when resources are demanded + * loaded. + */ + protected EContentAdapter problemIndicationAdapter = new EContentAdapter() { + @Override + public void notifyChanged( Notification notification ) { + if( notification.getNotifier() instanceof Resource ) { + switch( notification.getFeatureID( Resource.class ) ) { + case Resource.RESOURCE__IS_LOADED: + case Resource.RESOURCE__ERRORS: + case Resource.RESOURCE__WARNINGS: { + Resource resource = ( Resource ) notification.getNotifier(); + Diagnostic diagnostic = analyzeResourceProblems( resource, null ); + if( diagnostic.getSeverity() != Diagnostic.OK ) { + resourceToDiagnosticMap.put( resource, diagnostic ); + } + else { + resourceToDiagnosticMap.remove( resource ); + } + + if( updateProblemIndication ) { + getSite().getShell().getDisplay().asyncExec( new Runnable() { + public void run() { + updateProblemIndication(); + } + } ); + } + break; + } + } + } + else { + super.notifyChanged( notification ); + } + } + + @Override + protected void setTarget( Resource target ) { + basicSetTarget( target ); + } + + @Override + protected void unsetTarget( Resource target ) { + basicUnsetTarget( target ); + resourceToDiagnosticMap.remove( target ); + if( updateProblemIndication ) { + getSite().getShell().getDisplay().asyncExec( new Runnable() { + public void run() { + updateProblemIndication(); + } + } ); + } + } + }; + + /** + * This listens for workspace changes. + */ + protected IResourceChangeListener resourceChangeListener = new IResourceChangeListener() { + public void resourceChanged( IResourceChangeEvent event ) { + IResourceDelta delta = event.getDelta(); + try { + class ResourceDeltaVisitor implements IResourceDeltaVisitor { + protected ResourceSet resourceSet = editingDomain.getResourceSet(); + protected Collection< Resource > changedResources = new ArrayList< Resource >(); + protected Collection< Resource > removedResources = new ArrayList< Resource >(); + + public boolean visit( IResourceDelta delta ) { + if( delta.getResource().getType() == IResource.FILE ) { + if( delta.getKind() == IResourceDelta.REMOVED || delta.getKind() == IResourceDelta.CHANGED + && delta.getFlags() != IResourceDelta.MARKERS ) { + Resource resource = resourceSet.getResource( + URI.createPlatformResourceURI( delta.getFullPath().toString(), true ), false ); + if( resource != null ) { + if( delta.getKind() == IResourceDelta.REMOVED ) { + removedResources.add( resource ); + } + else if( !savedResources.remove( resource ) ) { + changedResources.add( resource ); + } + } + } + return false; + } + + return true; + } + + public Collection< Resource > getChangedResources() { + return changedResources; + } + + public Collection< Resource > getRemovedResources() { + return removedResources; + } + } + + final ResourceDeltaVisitor visitor = new ResourceDeltaVisitor(); + delta.accept( visitor ); + + if( !visitor.getRemovedResources().isEmpty() ) { + getSite().getShell().getDisplay().asyncExec( new Runnable() { + public void run() { + removedResources.addAll( visitor.getRemovedResources() ); + if( !isDirty() ) { + getSite().getPage().closeEditor( RiseClipseEditor.this, false ); + } + } + } ); + } + + if( !visitor.getChangedResources().isEmpty() ) { + getSite().getShell().getDisplay().asyncExec( new Runnable() { + public void run() { + changedResources.addAll( visitor.getChangedResources() ); + if( getSite().getPage().getActiveEditor() == RiseClipseEditor.this ) { + handleActivate(); + } + } + } ); + } + } + catch( CoreException exception ) { + RiseClipseEditorPlugin.INSTANCE.log( exception ); + } + } + }; + + private IRiseClipseConsole console; + + /** + * Handles activation of the editor or it's associated views. + */ + protected void handleActivate() { + // Recompute the read only state. + // + if( editingDomain.getResourceToReadOnlyMap() != null ) { + editingDomain.getResourceToReadOnlyMap().clear(); + + // Refresh any actions that may become enabled or disabled. + // + setSelection( getSelection() ); + } + + if( !removedResources.isEmpty() ) { + if( handleDirtyConflict() ) { + getSite().getPage().closeEditor( RiseClipseEditor.this, false ); + } + else { + removedResources.clear(); + changedResources.clear(); + savedResources.clear(); + } + } + else if( !changedResources.isEmpty() ) { + changedResources.removeAll( savedResources ); + handleChangedResources(); + changedResources.clear(); + savedResources.clear(); + } + } + + /** + * Handles what to do with changed resources on activation. + */ + protected void handleChangedResources() { + if( !changedResources.isEmpty() && ( !isDirty() || handleDirtyConflict() ) ) { + if( isDirty() ) { + changedResources.addAll( editingDomain.getResourceSet().getResources() ); + } + editingDomain.getCommandStack().flush(); + + updateProblemIndication = false; + for( Resource resource : changedResources ) { + if( resource.isLoaded() ) { + resource.unload(); + try { + resource.load( Collections.EMPTY_MAP ); + } + catch( IOException exception ) { + if( !resourceToDiagnosticMap.containsKey( resource ) ) { + resourceToDiagnosticMap.put( resource, analyzeResourceProblems( resource, exception ) ); + } + } + } + } + + if( AdapterFactoryEditingDomain.isStale( editorSelection ) ) { + setSelection( StructuredSelection.EMPTY ); + } + + updateProblemIndication = true; + updateProblemIndication(); + } + } + + /** + * Updates the problems indication with the information described in the + * specified diagnostic. + */ + protected void updateProblemIndication() { + if( updateProblemIndication ) { + BasicDiagnostic diagnostic = new BasicDiagnostic( Diagnostic.OK, + "fr.centralesupelec.edf.riseclipse.editor", 0, null, + new Object[] { editingDomain.getResourceSet() } ); + for( Diagnostic childDiagnostic : resourceToDiagnosticMap.values() ) { + if( childDiagnostic.getSeverity() != Diagnostic.OK ) { + diagnostic.add( childDiagnostic ); + } + } + + int lastEditorPage = getPageCount() - 1; + if( lastEditorPage >= 0 && getEditor( lastEditorPage ) instanceof ProblemEditorPart ) { + ( ( ProblemEditorPart ) getEditor( lastEditorPage ) ).setDiagnostic( diagnostic ); + if( diagnostic.getSeverity() != Diagnostic.OK ) { + setActivePage( lastEditorPage ); + } + } + else if( diagnostic.getSeverity() != Diagnostic.OK ) { + ProblemEditorPart problemEditorPart = new ProblemEditorPart(); + problemEditorPart.setDiagnostic( diagnostic ); + problemEditorPart.setMarkerHelper( markerHelper ); + try { + addPage( ++lastEditorPage, problemEditorPart, getEditorInput() ); + setPageText( lastEditorPage, problemEditorPart.getPartName() ); + setActivePage( lastEditorPage ); + showTabs(); + } + catch( PartInitException exception ) { + RiseClipseEditorPlugin.INSTANCE.log( exception ); + } + } + + if( markerHelper.hasMarkers( editingDomain.getResourceSet() ) ) { + markerHelper.deleteMarkers( editingDomain.getResourceSet() ); + if( diagnostic.getSeverity() != Diagnostic.OK ) { + try { + markerHelper.createMarkers( diagnostic ); + } + catch( CoreException exception ) { + RiseClipseEditorPlugin.INSTANCE.log( exception ); + } + } + } + } + } + + /** + * Shows a dialog that asks if conflicting changes should be discarded. + */ + protected boolean handleDirtyConflict() { + return MessageDialog.openQuestion( getSite().getShell(), getString( "_UI_FileConflict_label" ), + getString( "_WARN_FileConflict" ) ); + } + + /** + * This creates a model editor. + */ + public RiseClipseEditor() { + super(); + + this.console = new EclipseRiseClipseConsole(); + initializeEditingDomain(); + } + + /** + * This sets up the editing domain for the model editor. + */ + protected void initializeEditingDomain() { + // Create an adapter factory that yields item providers. + // + adapterFactory = new ComposedAdapterFactory( ComposedAdapterFactory.Descriptor.Registry.INSTANCE ); + + // TODO: do we need it ? + adapterFactory.addAdapterFactory( new ResourceItemProviderAdapterFactory() ); + + /* + * RiseClipseSpecific begin + */ + /* + * We don't need/want that our editor read any model : that's why + * we use a specific extension point. + * What we need: + * - the uri of known models: it will be the key + * - a human readable name + * - the adapter factory for the editor: we could get it with the + * itemProviderAdapterFactories extension point + * - the resource factory: it is available in the extension_parser + * extension point, but with no link to the uri except that the same + * plugin.xml file should contain the generated_package extension point + * which has the uri + * + * TODO: how to allow for several kind of serialization for the same uri ? + */ + HashMap< String, Resource.Factory > resourceFactories = new HashMap< String, Resource.Factory >(); + IConfigurationElement[] contributions = Platform.getExtensionRegistry().getConfigurationElementsFor( + "fr.centralesupelec.edf.riseclipse.main.meta_models" ); + for( int i = 0; i < contributions.length; i++ ) { + String uri = contributions[i].getAttribute( "uri" ); + String name = contributions[i].getAttribute( "name" ); + String adapterFactoryName = contributions[i].getAttribute( "adapterFactory" ); + String resourceFactoryName = contributions[i].getAttribute( "resourceFactory" ); + String viewerFilterName = contributions[i].getAttribute( "viewerFilter" ); + //if(( uri == null ) || ( name == null ) || ( adapterFactoryName == null ) || ( resourceFactoryName == null )) { + if(( uri == null ) || ( name == null )) { + console.error( "Invalid metamodel for RiseClispse" ); + continue; + } + AdapterFactory newAdapterFactory = null; + Resource.Factory resourceFactory = null; + ViewerFilter viewerFilter = null; + if( knownMetamodels.get( uri ) != null ) { + // We allow for extension point in several plugin (one in the main, another in the edit) + newAdapterFactory = knownMetamodels.get( uri ).getAdapterFactory(); + resourceFactory = knownMetamodels.get( uri ).getResourceFactory(); + viewerFilter = knownMetamodels.get( uri ).getViewerFilter(); + } + try { + if(( adapterFactoryName != null ) && ! adapterFactoryName.isEmpty() ) { + newAdapterFactory = ( AdapterFactory ) contributions[i].createExecutableExtension( "adapterFactory" ); + } + if(( resourceFactoryName != null ) && ! resourceFactoryName.isEmpty() ) { + resourceFactory = ( Resource.Factory ) contributions[i].createExecutableExtension( "resourceFactory" ); + } + if(( viewerFilterName != null ) && ! viewerFilterName.isEmpty() ) { + viewerFilter = ( ViewerFilter ) contributions[i].createExecutableExtension( "viewerFilter" ); + } + } + catch( CoreException e ) { + console.error( "Metamodel with uri " + uri + " has invalid factories."); + continue; + } + if( knownMetamodels.get( uri ) == null ) { + console.info( "Added metamodel " + name + " for URI " + uri ); + } + knownMetamodels.put( uri, new RiseClipseMetaModel( name, newAdapterFactory, + resourceFactory, viewerFilter )); + + if( resourceFactory != null ) { + resourceFactories.put( uri, resourceFactory ); + // trailing sharp which is present in some XML namespace (CIM !) + // is removed in URIs for RiseClipse + if( ! uri.endsWith( "#" )) { + resourceFactories.put( uri + '#', resourceFactory ); + } + } + if( newAdapterFactory != null ) { + adapterFactory.addAdapterFactory( newAdapterFactory ); + } + } + + /* + * RiseClipseSpecific end + */ + + // TODO: do we need it ? + adapterFactory.addAdapterFactory( new ReflectiveItemProviderAdapterFactory() ); + + // Create the command stack that will notify this editor as commands are + // executed. + // + BasicCommandStack commandStack = new BasicCommandStack(); + + // Add a listener to set the most recent command's affected objects to + // be the selection of the viewer with focus. + // + commandStack.addCommandStackListener( new CommandStackListener() { + public void commandStackChanged( final EventObject event ) { + getContainer().getDisplay().asyncExec( new Runnable() { + public void run() { + firePropertyChange( IEditorPart.PROP_DIRTY ); + + // Try to select the affected objects. + // + Command mostRecentCommand = ( ( CommandStack ) event.getSource() ).getMostRecentCommand(); + if( mostRecentCommand != null ) { + setSelectionToViewer( mostRecentCommand.getAffectedObjects() ); + } + for( Iterator< PropertySheetPage > i = propertySheetPages.iterator(); i.hasNext(); ) { + PropertySheetPage propertySheetPage = i.next(); + if( propertySheetPage.getControl().isDisposed() ) { + i.remove(); + } + else { + propertySheetPage.refresh(); + } + } + } + } ); + } + } ); + + // Create the editing domain with a special command stack. + // + /* + * RiseClipseSpecific begin + */ + editingDomain = new RiseClipseAdapterFactoryEditingDomain( adapterFactory, commandStack, + new HashMap< Resource, Boolean >(), resourceFactories ); + /* + * RiseClipseSpecific end + */ + } + + /** + * This is here for the listener to be able to call it. + */ + @Override + protected void firePropertyChange( int action ) { + super.firePropertyChange( action ); + } + + /** + * This sets the selection into whichever viewer is active. + */ + public void setSelectionToViewer( Collection< ? > collection ) { + final Collection< ? > theSelection = collection; + // Make sure it's okay. + // + if( theSelection != null && !theSelection.isEmpty() ) { + Runnable runnable = new Runnable() { + public void run() { + // Try to select the items in the current content viewer of + // the editor. + // + if( currentViewer != null ) { + currentViewer.setSelection( new StructuredSelection( theSelection.toArray() ), true ); + } + } + }; + getSite().getShell().getDisplay().asyncExec( runnable ); + } + } + + /** + * This returns the editing domain as required by the + * {@link IEditingDomainProvider} interface. This is important for + * implementing the static methods of {@link AdapterFactoryEditingDomain} + * and for supporting {@link org.eclipse.emf.edit.ui.action.CommandAction}. + */ + public EditingDomain getEditingDomain() { + return editingDomain; + } + + /** + * + */ + public class ReverseAdapterFactoryContentProvider extends AdapterFactoryContentProvider { + /** + * + */ + public ReverseAdapterFactoryContentProvider( AdapterFactory adapterFactory ) { + super( adapterFactory ); + } + + /** + * + */ + @Override + public Object[] getElements( Object object ) { + Object parent = super.getParent( object ); + return ( parent == null ? Collections.EMPTY_SET : Collections.singleton( parent ) ).toArray(); + } + + /** + * + */ + @Override + public Object[] getChildren( Object object ) { + Object parent = super.getParent( object ); + return ( parent == null ? Collections.EMPTY_SET : Collections.singleton( parent ) ).toArray(); + } + + /** + * + */ + @Override + public boolean hasChildren( Object object ) { + Object parent = super.getParent( object ); + return parent != null; + } + + /** + * + */ + @Override + public Object getParent( Object object ) { + return null; + } + } + + /** + * + */ + public void setCurrentViewerPane( ViewerPane viewerPane ) { + if( currentViewerPane != viewerPane ) { + if( currentViewerPane != null ) { + currentViewerPane.showFocus( false ); + } + currentViewerPane = viewerPane; + } + setCurrentViewer( currentViewerPane.getViewer() ); + } + + /** + * This makes sure that one content viewer, either for the current page or + * the outline view, if it has focus, is the current one. + */ + public void setCurrentViewer( Viewer viewer ) { + // If it is changing... + // + if( currentViewer != viewer ) { + if( selectionChangedListener == null ) { + // Create the listener on demand. + // + selectionChangedListener = new ISelectionChangedListener() { + // This just notifies those things that are affected by the + // section. + // + public void selectionChanged( SelectionChangedEvent selectionChangedEvent ) { + setSelection( selectionChangedEvent.getSelection() ); + } + }; + } + + // Stop listening to the old one. + // + if( currentViewer != null ) { + currentViewer.removeSelectionChangedListener( selectionChangedListener ); + } + + // Start listening to the new one. + // + if( viewer != null ) { + viewer.addSelectionChangedListener( selectionChangedListener ); + } + + // Remember it. + // + currentViewer = viewer; + + // Set the editors selection based on the current viewer's + // selection. + // + setSelection( currentViewer == null ? StructuredSelection.EMPTY : currentViewer.getSelection() ); + } + } + + /** + * This returns the viewer as required by the {@link IViewerProvider} + * interface. + */ + public Viewer getViewer() { + return currentViewer; + } + + /** + * This creates a context menu for the viewer and adds a listener as well + * registering the menu for extension. + */ + protected void createContextMenuFor( StructuredViewer viewer ) { + MenuManager contextMenu = new MenuManager( "#PopUp" ); + contextMenu.add( new Separator( "additions" ) ); + contextMenu.setRemoveAllWhenShown( true ); + contextMenu.addMenuListener( this ); + Menu menu = contextMenu.createContextMenu( viewer.getControl() ); + viewer.getControl().setMenu( menu ); + getSite().registerContextMenu( contextMenu, new UnwrappingSelectionProvider( viewer ) ); + + int dndOperations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK; + Transfer[] transfers = new Transfer[] { LocalTransfer.getInstance(), LocalSelectionTransfer.getTransfer(), + FileTransfer.getInstance() }; + viewer.addDragSupport( dndOperations, transfers, new ViewerDragAdapter( viewer ) ); + viewer.addDropSupport( dndOperations, transfers, new EditingDomainViewerDropAdapter( editingDomain, viewer ) ); + } + + /** + * This is the method called to load a resource into the editing domain's + * resource set based on the editor's input. + */ + public void createModel() { + ArrayList< URI > resourceURIs = new ArrayList< URI >(); + resourceURIs.add( EditUIUtil.getURI( getEditorInput() )); + + try { + ZipInputStream in = new ZipInputStream( editingDomain.getResourceSet().getURIConverter().createInputStream( resourceURIs.get( 0 ))); + ZipEntry entry = in.getNextEntry(); + if( entry != null ) { + String zipURI = resourceURIs.get( 0 ).toString(); + resourceURIs.clear(); + while( entry != null ) { + // Must use "archive:" and not "zip:" to be recognized by ArchiveURIHandlerImpl + resourceURIs.add( URI.createURI( "archive:" + zipURI + "!/" + entry.getName() )); + entry = in.getNextEntry(); + } + } + in.close(); + } + catch( IOException e ) { + // Will be handled later + } + + for( URI resourceURI : resourceURIs ) { + try { + // Load the resource through the editing domain. + // + @SuppressWarnings("unused") + Resource resource = editingDomain.getResourceSet().getResource( resourceURI, true ); + } + // This is done by RiseClipseModelLoader in the command line tool + catch( RuntimeException re ) { + Throwable cause = re.getCause(); + if( cause instanceof IllegalValueException ) { + IllegalValueException e = ( IllegalValueException ) cause; + console.error( "value " + e.getValue() + " is not legal at line " + e.getLine() + " for feature " + + e.getFeature().getName() + ", it should be " + e.getFeature().getEType().getInstanceTypeName() ); + } + else { + console.error( "Problem loading " + resourceURI + " : " + cause ); + } + } + catch( Exception e ) { + console.error( "Problem loading " + resourceURI + " : " + e ); + } + + // This is the original code generated by EMF: not sure what must be kept +// catch( Exception e ) { +// exception = e; +// resource = editingDomain.getResourceSet().getResource( resourceURI, false ); +// } +// +// Diagnostic diagnostic = analyzeResourceProblems( resource, exception ); +// if( diagnostic.getSeverity() != Diagnostic.OK ) { +// resourceToDiagnosticMap.put( resource, analyzeResourceProblems( resource, exception ) ); +// } +// editingDomain.getResourceSet().eAdapters().add( problemIndicationAdapter ); + } + + // Let each resource do what it needs after all is loaded + // This is at least needed for CIM with zip files containing several + // resources and links to be set between objects in different resources + + for( Resource resource : editingDomain.getResourceSet().getResources() ) { + if( resource instanceof IRiseClipseResource ) { + (( IRiseClipseResource ) resource ).finalizeLoad( false ); + } + } + } + + /** + * Returns a diagnostic describing the errors and warnings listed in the + * resource and the specified exception (if any). + */ + public Diagnostic analyzeResourceProblems( Resource resource, Exception exception ) { + if( !resource.getErrors().isEmpty() || !resource.getWarnings().isEmpty() ) { + BasicDiagnostic basicDiagnostic = new BasicDiagnostic( Diagnostic.ERROR, + "fr.centralesupelec.edf.riseclipse.editor", 0, getString( "_UI_CreateModelError_message", + resource.getURI() ), new Object[] { exception == null ? ( Object ) resource : exception } ); + basicDiagnostic.merge( EcoreUtil.computeDiagnostic( resource, true ) ); + return basicDiagnostic; + } + else if( exception != null ) { + return new BasicDiagnostic( Diagnostic.ERROR, "fr.centralesupelec.edf.riseclipse.editor", 0, + getString( "_UI_CreateModelError_message", resource.getURI() ), new Object[] { exception } ); + } + else { + return Diagnostic.OK_INSTANCE; + } + } + + /** + * This is the method used by the framework to install your own controls. + */ + @Override + public void createPages() { + // Creates the model from the editor input + // + createModel(); + + // RiseClipseSpecific : only the selection tree view. + + // Only creates the other pages if there is something that can be edited + // + if( !getEditingDomain().getResourceSet().getResources().isEmpty() ) { + // Create a page for the selection tree view. + // + { + ViewerPane viewerPane = new ViewerPane( getSite().getPage(), RiseClipseEditor.this ) { + @Override + public Viewer createViewer( Composite composite ) { + Tree tree = new Tree( composite, SWT.MULTI ); + TreeViewer newTreeViewer = new TreeViewer( tree ); + return newTreeViewer; + } + + @Override + public void requestActivation() { + super.requestActivation(); + setCurrentViewerPane( this ); + } + }; + viewerPane.createControl( getContainer() ); + + selectionViewer = ( TreeViewer ) viewerPane.getViewer(); + selectionViewer.setContentProvider( new AdapterFactoryContentProvider( adapterFactory ) ); + + // RiseClispeSpecific : for navigateTo speedup + // Can only enable the hash look up before input has been set + selectionViewer.setUseHashlookup( true ); + // build all levels for navigateTo + // This takes to much time on big models, see navigateTo() for the new way + //selectionViewer.setAutoExpandLevel( AbstractTreeViewer.ALL_LEVELS ); + + selectionViewer.setLabelProvider( new AdapterFactoryLabelProvider( adapterFactory ) ); + selectionViewer.setInput( editingDomain.getResourceSet() ); + selectionViewer.setSelection( new StructuredSelection( editingDomain.getResourceSet().getResources() + .get( 0 ) ), true ); + viewerPane.setTitle( editingDomain.getResourceSet() ); + + // RiseClispeSpecific : use a filter if given + // TODO: get it more directly ? + String uri = null; + EList< Resource > resources = editingDomain.getResourceSet().getResources(); + if( resources.size() > 0 ) { + EList< EObject > contents = resources.get( 0 ).getContents(); + // The first element may be the model description in CIM files, it is not the right URI + if( contents.size() > 1 ) { + uri = contents.get( 1 ).eClass().getEPackage().getNsURI(); + } + else if( contents.size() > 0 ) { + uri = contents.get( 0 ).eClass().getEPackage().getNsURI(); + } + } + if( uri != null ) { + ViewerFilter filter = getViewerFilter( uri ); + if( filter != null ) { + selectionViewer.addFilter( filter ); + } + } + + new AdapterFactoryTreeEditor( selectionViewer.getTree(), adapterFactory ); + + createContextMenuFor( selectionViewer ); + int pageIndex = addPage( viewerPane.getControl() ); + setPageText( pageIndex, getString( "_UI_SelectionPage_label" ) ); + } + + getSite().getShell().getDisplay().asyncExec( new Runnable() { + public void run() { + setActivePage( 0 ); + } + } ); + } + + // Ensures that this editor will only display the page's tab + // area if there are more than one page + // + getContainer().addControlListener( new ControlAdapter() { + boolean guard = false; + + @Override + public void controlResized( ControlEvent event ) { + if( !guard ) { + guard = true; + hideTabs(); + guard = false; + } + } + } ); + + getSite().getShell().getDisplay().asyncExec( new Runnable() { + public void run() { + updateProblemIndication(); + } + } ); + } + + /** + * If there is just one page in the multi-page editor part, this hides the + * single tab at the bottom. + */ + protected void hideTabs() { + if( getPageCount() <= 1 ) { + setPageText( 0, "" ); + if( getContainer() instanceof CTabFolder ) { + ( ( CTabFolder ) getContainer() ).setTabHeight( 1 ); + Point point = getContainer().getSize(); + getContainer().setSize( point.x, point.y + 6 ); + } + } + } + + /** + * If there is more than one page in the multi-page editor part, this shows + * the tabs at the bottom. + */ + protected void showTabs() { + if( getPageCount() > 1 ) { + setPageText( 0, getString( "_UI_SelectionPage_label" ) ); + if( getContainer() instanceof CTabFolder ) { + ( ( CTabFolder ) getContainer() ).setTabHeight( SWT.DEFAULT ); + Point point = getContainer().getSize(); + getContainer().setSize( point.x, point.y - 6 ); + } + } + } + + /** + * This is used to track the active viewer. + */ + @Override + protected void pageChange( int pageIndex ) { + super.pageChange( pageIndex ); + + if( contentOutlinePage != null ) { + handleContentOutlineSelection( contentOutlinePage.getSelection() ); + } + } + + /** + * This is how the framework determines which interfaces we implement. + */ + @SuppressWarnings( { "rawtypes", "unchecked" } ) + @Override + public Object getAdapter( Class key ) { + if( key.equals( IContentOutlinePage.class ) ) { + return showOutlineView() ? getContentOutlinePage() : null; + } + else if( key.equals( IPropertySheetPage.class ) ) { + return getPropertySheetPage(); + } + else if( key.equals( IGotoMarker.class ) ) { + return this; + } + else { + return super.getAdapter( key ); + } + } + + /** + * This accesses a cached version of the content outliner. + */ + public IContentOutlinePage getContentOutlinePage() { + if( contentOutlinePage == null ) { + // The content outline is just a tree. + // + class MyContentOutlinePage extends ContentOutlinePage { + @Override + public void createControl( Composite parent ) { + super.createControl( parent ); + contentOutlineViewer = getTreeViewer(); + contentOutlineViewer.addSelectionChangedListener( this ); + + // Set up the tree viewer. + // + contentOutlineViewer.setContentProvider( new AdapterFactoryContentProvider( adapterFactory ) ); + contentOutlineViewer.setLabelProvider( new AdapterFactoryLabelProvider( adapterFactory ) ); + contentOutlineViewer.setInput( editingDomain.getResourceSet() ); + + // Make sure our popups work. + // + createContextMenuFor( contentOutlineViewer ); + + if( !editingDomain.getResourceSet().getResources().isEmpty() ) { + // Select the root object in the view. + // + contentOutlineViewer.setSelection( new StructuredSelection( editingDomain.getResourceSet() + .getResources().get( 0 ) ), true ); + } + } + + @Override + public void makeContributions( IMenuManager menuManager, IToolBarManager toolBarManager, + IStatusLineManager statusLineManager ) { + super.makeContributions( menuManager, toolBarManager, statusLineManager ); + contentOutlineStatusLineManager = statusLineManager; + } + + @Override + public void setActionBars( IActionBars actionBars ) { + super.setActionBars( actionBars ); + getActionBarContributor().shareGlobalActions( this, actionBars ); + } + } + + contentOutlinePage = new MyContentOutlinePage(); + + // Listen to selection so that we can handle it is a special way. + // + contentOutlinePage.addSelectionChangedListener( new ISelectionChangedListener() { + // This ensures that we handle selections correctly. + // + public void selectionChanged( SelectionChangedEvent event ) { + handleContentOutlineSelection( event.getSelection() ); + } + } ); + } + + return contentOutlinePage; + } + + /** + * This accesses a cached version of the property sheet. + */ + public IPropertySheetPage getPropertySheetPage() { + PropertySheetPage propertySheetPage = new ExtendedPropertySheetPage( editingDomain ) { + @Override + public void setSelectionToViewer( List< ? > selection ) { + RiseClipseEditor.this.setSelectionToViewer( selection ); + RiseClipseEditor.this.setFocus(); + } + + @Override + public void setActionBars( IActionBars actionBars ) { + super.setActionBars( actionBars ); + getActionBarContributor().shareGlobalActions( this, actionBars ); + } + }; + propertySheetPage.setPropertySourceProvider( new AdapterFactoryContentProvider( adapterFactory ) ); + propertySheetPages.add( propertySheetPage ); + + return propertySheetPage; + } + + /** + * This deals with how we want selection in the outliner to affect the other + * views. + */ + public void handleContentOutlineSelection( ISelection selection ) { + if( currentViewerPane != null && !selection.isEmpty() && selection instanceof IStructuredSelection ) { + Iterator< ? > selectedElements = ( ( IStructuredSelection ) selection ).iterator(); + if( selectedElements.hasNext() ) { + // Get the first selected element. + // + Object selectedElement = selectedElements.next(); + + // If it's the selection viewer, then we want it to select the + // same selection as this selection. + // + if( currentViewerPane.getViewer() == selectionViewer ) { + ArrayList< Object > selectionList = new ArrayList< Object >(); + selectionList.add( selectedElement ); + while( selectedElements.hasNext() ) { + selectionList.add( selectedElements.next() ); + } + + // Set the selection to the widget. + // + selectionViewer.setSelection( new StructuredSelection( selectionList ) ); + } + else { + // Set the input to the widget. + // + if( currentViewerPane.getViewer().getInput() != selectedElement ) { + currentViewerPane.getViewer().setInput( selectedElement ); + currentViewerPane.setTitle( selectedElement ); + } + } + } + } + } + + /** + * This is for implementing {@link IEditorPart} and simply tests the command + * stack. + */ + @Override + public boolean isDirty() { + return ( ( BasicCommandStack ) editingDomain.getCommandStack() ).isSaveNeeded(); + } + + /** + * This is for implementing {@link IEditorPart} and simply saves the model + * file. + */ + @Override + public void doSave( IProgressMonitor progressMonitor ) { + // Save only resources that have actually changed. + // + final Map< Object, Object > saveOptions = new HashMap< Object, Object >(); + saveOptions.put( Resource.OPTION_SAVE_ONLY_IF_CHANGED, Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER ); + saveOptions.put( Resource.OPTION_LINE_DELIMITER, Resource.OPTION_LINE_DELIMITER_UNSPECIFIED ); + + // Do the work within an operation because this is a long running + // activity that modifies the workbench. + // + WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { + // This is the method that gets invoked when the operation runs. + // + @Override + public void execute( IProgressMonitor monitor ) { + // Save the resources to the file system. + // + boolean first = true; + for( Resource resource : editingDomain.getResourceSet().getResources() ) { + if( ( first || !resource.getContents().isEmpty() || isPersisted( resource ) ) + && !editingDomain.isReadOnly( resource ) ) { + try { + long timeStamp = resource.getTimeStamp(); + resource.save( saveOptions ); + if( resource.getTimeStamp() != timeStamp ) { + savedResources.add( resource ); + } + } + catch( Exception exception ) { + resourceToDiagnosticMap.put( resource, analyzeResourceProblems( resource, exception ) ); + } + first = false; + } + } + } + }; + + updateProblemIndication = false; + try { + // This runs the options, and shows progress. + // + new ProgressMonitorDialog( getSite().getShell() ).run( true, false, operation ); + + // Refresh the necessary state. + // + ( ( BasicCommandStack ) editingDomain.getCommandStack() ).saveIsDone(); + firePropertyChange( IEditorPart.PROP_DIRTY ); + } + catch( Exception exception ) { + // Something went wrong that shouldn't. + // + RiseClipseEditorPlugin.INSTANCE.log( exception ); + } + updateProblemIndication = true; + updateProblemIndication(); + } + + /** + * This returns whether something has been persisted to the URI of the + * specified resource. The implementation uses the URI converter from the + * editor's resource set to try to open an input stream. + */ + protected boolean isPersisted( Resource resource ) { + boolean result = false; + try { + InputStream stream = editingDomain.getResourceSet().getURIConverter().createInputStream( resource.getURI() ); + if( stream != null ) { + result = true; + stream.close(); + } + } + catch( IOException e ) { + // Ignore + } + return result; + } + + /** + * This always returns true because it is not currently supported. + */ + @Override + public boolean isSaveAsAllowed() { + return true; + } + + /** + * This also changes the editor's input. + */ + @Override + public void doSaveAs() { + SaveAsDialog saveAsDialog = new SaveAsDialog( getSite().getShell() ); + saveAsDialog.open(); + IPath path = saveAsDialog.getResult(); + if( path != null ) { + IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile( path ); + if( file != null ) { + doSaveAs( URI.createPlatformResourceURI( file.getFullPath().toString(), true ), new FileEditorInput( + file ) ); + } + } + } + + /** + */ + protected void doSaveAs( URI uri, IEditorInput editorInput ) { + ( editingDomain.getResourceSet().getResources().get( 0 ) ).setURI( uri ); + setInputWithNotify( editorInput ); + setPartName( editorInput.getName() ); + IProgressMonitor progressMonitor = getActionBars().getStatusLineManager() != null ? getActionBars() + .getStatusLineManager().getProgressMonitor() : new NullProgressMonitor(); + doSave( progressMonitor ); + } + + /** + */ + public void gotoMarker( IMarker marker ) { + List< ? > targetObjects = markerHelper.getTargetObjects( editingDomain, marker ); + if( !targetObjects.isEmpty() ) { + setSelectionToViewer( targetObjects ); + } + } + + /** + * This is called during startup. + */ + @Override + public void init( IEditorSite site, IEditorInput editorInput ) { + setSite( site ); + setInputWithNotify( editorInput ); + setPartName( editorInput.getName() ); + site.setSelectionProvider( this ); + site.getPage().addPartListener( partListener ); + ResourcesPlugin.getWorkspace().addResourceChangeListener( resourceChangeListener, + IResourceChangeEvent.POST_CHANGE ); + } + + /** + */ + @Override + public void setFocus() { + if( currentViewerPane != null ) { + currentViewerPane.setFocus(); + } + else { + getControl( getActivePage() ).setFocus(); + } + } + + /** + * This implements {@link org.eclipse.jface.viewers.ISelectionProvider}. + */ + public void addSelectionChangedListener( ISelectionChangedListener listener ) { + selectionChangedListeners.add( listener ); + } + + /** + * This implements {@link org.eclipse.jface.viewers.ISelectionProvider}. + */ + public void removeSelectionChangedListener( ISelectionChangedListener listener ) { + selectionChangedListeners.remove( listener ); + } + + /** + * This implements {@link org.eclipse.jface.viewers.ISelectionProvider} to + * return this editor's overall selection. + */ + public ISelection getSelection() { + return editorSelection; + } + + /** + * This implements {@link org.eclipse.jface.viewers.ISelectionProvider} to + * set this editor's overall selection. Calling this result will notify the + * listeners. + */ + public void setSelection( ISelection selection ) { + editorSelection = selection; + + for( ISelectionChangedListener listener : selectionChangedListeners ) { + listener.selectionChanged( new SelectionChangedEvent( this, selection ) ); + } + setStatusLineManager( selection ); + } + + /** + */ + public void setStatusLineManager( ISelection selection ) { + IStatusLineManager statusLineManager = currentViewer != null && currentViewer == contentOutlineViewer ? contentOutlineStatusLineManager + : getActionBars().getStatusLineManager(); + + if( statusLineManager != null ) { + if( selection instanceof IStructuredSelection ) { + Collection< ? > collection = ( ( IStructuredSelection ) selection ).toList(); + switch( collection.size() ) { + case 0: { + statusLineManager.setMessage( getString( "_UI_NoObjectSelected" ) ); + break; + } + case 1: { + String text = new AdapterFactoryItemDelegator( adapterFactory ).getText( collection.iterator() + .next() ); + statusLineManager.setMessage( getString( "_UI_SingleObjectSelected", text ) ); + break; + } + default: { + statusLineManager.setMessage( getString( "_UI_MultiObjectSelected", + Integer.toString( collection.size() ) ) ); + break; + } + } + } + else { + statusLineManager.setMessage( "" ); + } + } + } + + /** + * This looks up a string in the plugin's plugin.properties file. + */ + private static String getString( String key ) { + return RiseClipseEditorPlugin.INSTANCE.getString( key ); + } + + /** + * This looks up a string in plugin.properties, making a substitution. + */ + private static String getString( String key, Object s1 ) { + return RiseClipseEditorPlugin.INSTANCE.getString( key, new Object[] { s1 } ); + } + + /** + * This implements {@link org.eclipse.jface.action.IMenuListener} to help + * fill the context menus with contributions from the Edit menu. + */ + public void menuAboutToShow( IMenuManager menuManager ) { + ( ( IMenuListener ) getEditorSite().getActionBarContributor() ).menuAboutToShow( menuManager ); + } + + /** + */ + public EditingDomainActionBarContributor getActionBarContributor() { + return ( EditingDomainActionBarContributor ) getEditorSite().getActionBarContributor(); + } + + /** + */ + public IActionBars getActionBars() { + return getActionBarContributor().getActionBars(); + } + + /** + */ + public AdapterFactory getAdapterFactory() { + return adapterFactory; + } + + /** + */ + @Override + public void dispose() { + updateProblemIndication = false; + + ResourcesPlugin.getWorkspace().removeResourceChangeListener( resourceChangeListener ); + + getSite().getPage().removePartListener( partListener ); + + adapterFactory.dispose(); + + if( getActionBarContributor().getActiveEditor() == this ) { + getActionBarContributor().setActiveEditor( null ); + } + + for( PropertySheetPage propertySheetPage : propertySheetPages ) { + propertySheetPage.dispose(); + } + + if( contentOutlinePage != null ) { + contentOutlinePage.dispose(); + } + + super.dispose(); + } + + /** + * Returns whether the outline view should be presented to the user. + */ + protected boolean showOutlineView() { + return true; + } +} diff --git a/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/RiseClipseEditorPlugin.java b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/RiseClipseEditorPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..d6534437546ce5e22e0be1ffee4a49dc44de2708 --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/RiseClipseEditorPlugin.java @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2017 CentraleSupélec & EDF. + * 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 + * + * This file is part of the RiseClipse tool + * + * Contributors: + * Computer Science Department, CentraleSupélec : initial implementation + * Contacts: + * Dominique.Marcadet@centralesupelec.fr + */ +package fr.centralesupelec.edf.riseclipse.ui; + +import org.eclipse.emf.common.EMFPlugin; + +import org.eclipse.emf.common.ui.EclipseUIPlugin; + +import org.eclipse.emf.common.util.ResourceLocator; + +/** + * This is the central singleton for the RiseClipse editor plugin. + */ +public final class RiseClipseEditorPlugin extends EMFPlugin { + /** + * Keep track of the singleton. + */ + public static final RiseClipseEditorPlugin INSTANCE = new RiseClipseEditorPlugin(); + + /** + * Keep track of the singleton. + */ + private static Implementation plugin; + + /** + * Create the instance. + */ + public RiseClipseEditorPlugin() { + super( new ResourceLocator[] {} ); + } + + /** + * Returns the singleton instance of the Eclipse plugin. + * + * @return the singleton instance. + */ + @Override + public ResourceLocator getPluginResourceLocator() { + return plugin; + } + + /** + * Returns the singleton instance of the Eclipse plugin. + * + * @return the singleton instance. + */ + public static Implementation getPlugin() { + return plugin; + } + + /** + * The actual implementation of the Eclipse <b>Plugin</b>. + */ + public static class Implementation extends EclipseUIPlugin { + /** + * Creates an instance. + */ + public Implementation() { + super(); + + // Remember the static instance. + // + plugin = this; + } + } + +} diff --git a/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/RiseClipseFatalException.java b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/RiseClipseFatalException.java new file mode 100644 index 0000000000000000000000000000000000000000..10397cad9a4392e2366fca00017037d627fdf9ff --- /dev/null +++ b/fr.centralesupelec.edf.riseclipse.editor/src/fr/centralesupelec/edf/riseclipse/ui/RiseClipseFatalException.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2017 CentraleSupélec & EDF. + * 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 + * + * This file is part of the RiseClipse tool + * + * Contributors: + * Computer Science Department, CentraleSupélec : initial implementation + * Contacts: + * Dominique.Marcadet@centralesupelec.fr + */ +package fr.centralesupelec.edf.riseclipse.ui; + +@SuppressWarnings( "serial" ) +public class RiseClipseFatalException extends RuntimeException { + + public RiseClipseFatalException() { + super(); + } + + public RiseClipseFatalException( String message ) { + super( message ); + } + + public RiseClipseFatalException( Throwable cause ) { + super( cause ); + } + + public RiseClipseFatalException( String message, Throwable cause ) { + super( message, cause ); + } + + // Not in Java6 +// public RiseClipseFatalException( String message, Throwable cause, boolean enableSuppression, +// boolean writableStackTrace ) { +// super( message, cause, enableSuppression, writableStackTrace ); +// } + +}