Bug 548124 - [ui] added editor folding for copyright and imports

Change-Id: I10a3431f0a09988bab910f298c9edf5cffab0c0a
diff --git a/plugins/org.eclipse.etrice.core.common.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.etrice.core.common.ui/META-INF/MANIFEST.MF
index b7975ba..533dee9 100644
--- a/plugins/org.eclipse.etrice.core.common.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.etrice.core.common.ui/META-INF/MANIFEST.MF
@@ -27,6 +27,7 @@
  org.eclipse.etrice.core.common.ui.contentassist.antlr,
  org.eclipse.etrice.core.common.ui.contentassist.antlr.internal,
  org.eclipse.etrice.core.common.ui.editor,
+ org.eclipse.etrice.core.common.ui.editor.folding,
  org.eclipse.etrice.core.common.ui.editor.model,
  org.eclipse.etrice.core.common.ui.highlight,
  org.eclipse.etrice.core.common.ui.hover,
diff --git a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/editor/folding/FoldingRegionProvider.java b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/editor/folding/FoldingRegionProvider.java
new file mode 100644
index 0000000..e720e41
--- /dev/null
+++ b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/editor/folding/FoldingRegionProvider.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2010 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ * 
+ * CONTRIBUTORS:
+ * 		Juergen Haug (initial contribution)
+ * 
+ *******************************************************************************/
+
+package org.eclipse.etrice.core.common.ui.editor.folding;
+
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.etrice.core.common.base.Import;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.xtext.resource.ILocationInFileProvider;
+import org.eclipse.xtext.ui.editor.folding.DefaultFoldingRegionProvider;
+import org.eclipse.xtext.ui.editor.folding.IFoldingRegionAcceptor;
+import org.eclipse.xtext.ui.editor.folding.IFoldingRegionAcceptorExtension;
+import org.eclipse.xtext.ui.editor.model.IXtextDocument;
+import org.eclipse.xtext.util.ITextRegion;
+
+import com.google.inject.Inject;
+
+public class FoldingRegionProvider extends DefaultFoldingRegionProvider {
+	
+	@Inject
+	private ILocationInFileProvider locationInFileProvider;
+	
+	@Override
+	protected void computeCommentFolding(IXtextDocument xtextDocument,
+			IFoldingRegionAcceptor<ITextRegion> foldingRegionAcceptor, ITypedRegion typedRegion,
+			boolean initiallyFolded) throws BadLocationException {
+		
+		// auto fold copyright
+		boolean isFolded = initiallyFolded;
+		int offset = typedRegion.getOffset();
+		int length = typedRegion.getLength();
+		if(offset == 0) {
+			String text = xtextDocument.get(offset, length);
+			isFolded |= text.trim().toLowerCase().contains("copyright");
+		}
+		
+		super.computeCommentFolding(xtextDocument, foldingRegionAcceptor, typedRegion, isFolded);
+	}
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	protected void computeObjectFolding(EObject eObject, IFoldingRegionAcceptor<ITextRegion> foldingRegionAcceptor,
+			boolean initiallyFolded) {
+		
+		if(eObject instanceof Import) {
+			// fold imports
+			EStructuralFeature importsFeature = eObject.eContainmentFeature();
+			if(importsFeature.isMany()) {
+				List<Import> imports = (List<Import>) eObject.eContainer().eGet(importsFeature);
+				if(imports.size() >= 2 && imports.get(0) == eObject) {
+					// assuming imports syntax is a single block
+					ITextRegion region = imports.stream().map(imp -> locationInFileProvider.getFullTextRegion(imp)).reduce((first, second) -> first.merge(second)).get();
+					ITextRegion significant = locationInFileProvider.getSignificantTextRegion(eObject);
+					((IFoldingRegionAcceptorExtension<ITextRegion>)foldingRegionAcceptor).accept(region.getOffset(), region.getLength(), true, significant);	
+				}
+			}		
+		}
+		
+		super.computeObjectFolding(eObject, foldingRegionAcceptor, initiallyFolded);
+	}
+
+}
diff --git a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/hover/BaseHoverDocumentationProvider.java b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/hover/BaseHoverDocumentationProvider.java
index af3c337..330986e 100644
--- a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/hover/BaseHoverDocumentationProvider.java
+++ b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/hover/BaseHoverDocumentationProvider.java
@@ -19,15 +19,25 @@
 import static org.eclipse.etrice.core.common.documentation.DocumentationMarkup.trimMarkupTag;
 
 import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
 import org.eclipse.xtext.ui.editor.hover.html.DefaultHoverDocumentationProvider;
 
 public class BaseHoverDocumentationProvider extends DefaultHoverDocumentationProvider {
 	
 	@Override
-	public String getDocumentation(EObject object) {
+	public String getDocumentation(EObject object) { 
 		String text = super.getDocumentation(object);
-		
-		return (text != null) ? processMarkup(text) : null;
+		if (text != null) {
+			// hide copyright header
+			int totalOffset = NodeModelUtils.getNode(object).getTotalOffset();
+			if (totalOffset == 0 && text.trim().toLowerCase().startsWith("copyright")) {
+				return null;
+			} else {
+				return processMarkup(text);
+			}
+		}
+
+		return null;
 	}
 	
 	protected String processMarkup(String text) {
diff --git a/plugins/org.eclipse.etrice.core.config.ui/src/org/eclipse/etrice/core/ui/ConfigUiModule.java b/plugins/org.eclipse.etrice.core.config.ui/src/org/eclipse/etrice/core/ui/ConfigUiModule.java
index a8550b5..1cd0beb 100644
--- a/plugins/org.eclipse.etrice.core.config.ui/src/org/eclipse/etrice/core/ui/ConfigUiModule.java
+++ b/plugins/org.eclipse.etrice.core.config.ui/src/org/eclipse/etrice/core/ui/ConfigUiModule.java
@@ -14,9 +14,13 @@
 
 package org.eclipse.etrice.core.ui;
 
+import org.eclipse.etrice.core.common.ui.editor.folding.FoldingRegionProvider;
+import org.eclipse.etrice.core.common.ui.hover.BaseHoverDocumentationProvider;
 import org.eclipse.etrice.core.common.ui.linking.GlobalNonPlatformURIEditorOpener;
 import org.eclipse.etrice.core.ui.linking.ConfigHyperlinkHelper;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.xtext.ui.editor.folding.IFoldingRegionProvider;
+import org.eclipse.xtext.ui.editor.hover.html.IEObjectHoverDocumentationProvider;
 import org.eclipse.xtext.ui.editor.hyperlinking.IHyperlinkHelper;
 
 /**
@@ -38,4 +42,12 @@
 	public Class<? extends IHyperlinkHelper> bindIHyperlinkHelper() {
 		return ConfigHyperlinkHelper.class;
 	}
+	
+	public Class<? extends IFoldingRegionProvider> bindIFoldingRegionProvider() {
+		return FoldingRegionProvider.class;
+	}
+	
+	public Class<? extends IEObjectHoverDocumentationProvider> bindIEObjectHoverDocumentationProvider() {
+		return BaseHoverDocumentationProvider.class;
+	}
 }
diff --git a/plugins/org.eclipse.etrice.core.etmap.ui/src/org/eclipse/etrice/core/etmap/ui/ETMapUiModule.java b/plugins/org.eclipse.etrice.core.etmap.ui/src/org/eclipse/etrice/core/etmap/ui/ETMapUiModule.java
index 0a9916f..676226d 100644
--- a/plugins/org.eclipse.etrice.core.etmap.ui/src/org/eclipse/etrice/core/etmap/ui/ETMapUiModule.java
+++ b/plugins/org.eclipse.etrice.core.etmap.ui/src/org/eclipse/etrice/core/etmap/ui/ETMapUiModule.java
@@ -14,9 +14,13 @@
 
 package org.eclipse.etrice.core.etmap.ui;
 
+import org.eclipse.etrice.core.common.ui.editor.folding.FoldingRegionProvider;
+import org.eclipse.etrice.core.common.ui.hover.BaseHoverDocumentationProvider;
 import org.eclipse.etrice.core.common.ui.linking.GlobalNonPlatformURIEditorOpener;
 import org.eclipse.etrice.core.common.ui.linking.ImportAwareHyperlinkHelper;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.xtext.ui.editor.folding.IFoldingRegionProvider;
+import org.eclipse.xtext.ui.editor.hover.html.IEObjectHoverDocumentationProvider;
 import org.eclipse.xtext.ui.editor.hyperlinking.IHyperlinkHelper;
 
 /**
@@ -34,4 +38,12 @@
 	public Class<? extends IHyperlinkHelper> bindIHyperlinkHelper() {
 		return ImportAwareHyperlinkHelper.class;
 	}
+	
+	public Class<? extends IFoldingRegionProvider> bindIFoldingRegionProvider() {
+		return FoldingRegionProvider.class;
+	}
+	
+	public Class<? extends IEObjectHoverDocumentationProvider> bindIEObjectHoverDocumentationProvider() {
+		return BaseHoverDocumentationProvider.class;
+	}
 }
diff --git a/plugins/org.eclipse.etrice.core.etphys.ui/src/org/eclipse/etrice/core/etphys/ui/ETPhysUiModule.java b/plugins/org.eclipse.etrice.core.etphys.ui/src/org/eclipse/etrice/core/etphys/ui/ETPhysUiModule.java
index 900f4a8..c8d9b1a 100644
--- a/plugins/org.eclipse.etrice.core.etphys.ui/src/org/eclipse/etrice/core/etphys/ui/ETPhysUiModule.java
+++ b/plugins/org.eclipse.etrice.core.etphys.ui/src/org/eclipse/etrice/core/etphys/ui/ETPhysUiModule.java
@@ -14,15 +14,20 @@
 
 package org.eclipse.etrice.core.etphys.ui;
 
+import org.eclipse.etrice.core.common.ui.editor.folding.FoldingRegionProvider;
+import org.eclipse.etrice.core.common.ui.hover.BaseHoverDocumentationProvider;
 import org.eclipse.etrice.core.common.ui.linking.GlobalNonPlatformURIEditorOpener;
 import org.eclipse.etrice.core.common.ui.linking.ImportAwareHyperlinkHelper;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.xtext.ui.editor.folding.IFoldingRegionProvider;
+import org.eclipse.xtext.ui.editor.hover.html.IEObjectHoverDocumentationProvider;
 import org.eclipse.xtext.ui.editor.hyperlinking.IHyperlinkHelper;
 
 /**
  * Use this class to register components to be used within the IDE.
  */
 public class ETPhysUiModule extends org.eclipse.etrice.core.etphys.ui.AbstractETPhysUiModule {
+	
 	public ETPhysUiModule(AbstractUIPlugin plugin) {
 		super(plugin);
 	}
@@ -30,8 +35,17 @@
 	public Class<? extends org.eclipse.xtext.ui.editor.IURIEditorOpener> bindIURIEditorOpener() {
 		return GlobalNonPlatformURIEditorOpener.class;
 	}
+	
 	public Class<? extends IHyperlinkHelper> bindIHyperlinkHelper() {
 		return ImportAwareHyperlinkHelper.class;
 	}
 	
+	public Class<? extends IFoldingRegionProvider> bindIFoldingRegionProvider() {
+		return FoldingRegionProvider.class;
+	}
+	
+	public Class<? extends IEObjectHoverDocumentationProvider> bindIEObjectHoverDocumentationProvider() {
+		return BaseHoverDocumentationProvider.class;
+	}
+	
 }
diff --git a/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/RoomUiModule.java b/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/RoomUiModule.java
index c7eb390..bd67c34 100644
--- a/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/RoomUiModule.java
+++ b/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/RoomUiModule.java
@@ -16,6 +16,7 @@
 
 import org.eclipse.etrice.core.common.ui.autoedit.BaseAutoEditStrategyProvider;
 import org.eclipse.etrice.core.common.ui.editor.BaseDoubleClickStrategyProvider;
+import org.eclipse.etrice.core.common.ui.editor.folding.FoldingRegionProvider;
 import org.eclipse.etrice.core.common.ui.editor.model.BaseTokenTypeToPartitionMapper;
 import org.eclipse.etrice.core.common.ui.hover.BaseHoverDocumentationProvider;
 import org.eclipse.etrice.core.common.ui.hover.IKeywordHoverContentProvider;
@@ -34,6 +35,7 @@
 import org.eclipse.xtext.ide.editor.syntaxcoloring.ISemanticHighlightingCalculator;
 import org.eclipse.xtext.ui.editor.autoedit.AbstractEditStrategyProvider;
 import org.eclipse.xtext.ui.editor.doubleClicking.DoubleClickStrategyProvider;
+import org.eclipse.xtext.ui.editor.folding.IFoldingRegionProvider;
 import org.eclipse.xtext.ui.editor.hover.IEObjectHover;
 import org.eclipse.xtext.ui.editor.hover.IEObjectHoverProvider;
 import org.eclipse.xtext.ui.editor.hover.html.IEObjectHoverDocumentationProvider;
@@ -59,8 +61,6 @@
 		// keyword hover stuff
 		binder.bind(IKeywordHoverContentProvider.class).to(KeywordHoverContentProvider.class);
 		binder.bind(IEObjectHoverProvider.class).to(RoomHoverProvider.class);	
-		
-		binder.bind(IEObjectHoverDocumentationProvider.class).to(BaseHoverDocumentationProvider.class);
 	}
 
 	@Override
@@ -110,6 +110,14 @@
 		return BaseDoubleClickStrategyProvider.class;
 	}
 	
+	public Class<? extends IFoldingRegionProvider> bindIFoldingRegionProvider() {
+		return FoldingRegionProvider.class;
+	}
+	
+	public Class<? extends IEObjectHoverDocumentationProvider> bindIEObjectHoverDocumentationProvider() {
+		return BaseHoverDocumentationProvider.class;
+	}
+	
 	@Override
 	public Class<? extends org.eclipse.xtext.ui.editor.quickfix.IssueResolutionProvider> bindIssueResolutionProvider() {
 		return RoomQuickFixProviderXtend.class;
diff --git a/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/hover/RoomEObjectHover.xtend b/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/hover/RoomEObjectHover.xtend
index 8043af8..68570d7 100644
--- a/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/hover/RoomEObjectHover.xtend
+++ b/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/hover/RoomEObjectHover.xtend
@@ -32,11 +32,12 @@
 	RoomGrammarAccess grammar
 	
 	override protected getXtextElementAt(XtextResource resource, int offset) {
-		// lookup expression
+		
 		val parseResult = resource.parseResult
 		if(parseResult !== null) {
 			val leafNode = NodeModelUtils.findLeafNodeAtOffset(parseResult.rootNode, offset)
 			if(leafNode?.grammarElement instanceof RuleCall) {
+				// lookup model element in DetailCode
 				if((leafNode.grammarElement as RuleCall).rule == grammar.CC_STRINGRule && leafNode.semanticElement instanceof DetailCode){
 					val exprFeature = UIExpressionUtil.findAtOffset(leafNode, offset)
 					if(exprFeature?.data instanceof EObject)