Bug 577378: [Ltk-Model] Add extensible element content and label
provider
Change-Id: I0ec465227ff7e8b44f082093f48934f4bf84ce8d
diff --git a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/ElementSet.java b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/ElementSet.java
index dfbbd49..ea6eb3f 100644
--- a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/ElementSet.java
+++ b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/ElementSet.java
@@ -153,7 +153,7 @@
}
public @Nullable IResource getOwningResource(final LtkModelElement<?> element) {
- if ((element.getElementType() & LtkModelElement.MASK_C2) < LtkModelElement.C2_SOURCE_CHUNK) {
+ if ((element.getElementType() & LtkModelElement.MASK_C12) < LtkModelElement.C12_SOURCE_CHUNK) {
IResource resource;
resource= element.getAdapter(IResource.class);
return resource;
diff --git a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/element/LtkModelElement.java b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/element/LtkModelElement.java
index e0ebcb0..1e32d7c 100644
--- a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/element/LtkModelElement.java
+++ b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/element/LtkModelElement.java
@@ -31,21 +31,22 @@
public interface LtkModelElement<TModelChild extends LtkModelElement<?>> extends IAdaptable {
- static final int MASK_C1= 0xf00;
- static final int SHIFT_C1= 8;
- static final int MASK_C2= 0xff0;
- static final int MASK_C3= 0xfff;
+ static final int SHIFT_C1= 8;
+ static final int SHIFT_C2= 4;
+ static final int SHIFT_C3= 0;
+ static final int MASK_C1= 0xF << SHIFT_C1;
+ static final int MASK_C12= MASK_C1 | 0xF << SHIFT_C2;
+ static final int MASK_C123= MASK_C12 | 0xF << SHIFT_C3;
- static final int C1_BUNDLE= 0x100;
- static final int C1_SOURCE= 0x200;
- static final int C1_IMPORT= 0x300;
- static final int C1_CLASS= 0x400;
- static final int C1_METHOD= 0x500;
- static final int C1_VARIABLE= 0x600;
- static final int C1_EMBEDDED= 0x800;
-
- static final int C2_SOURCE_FILE= C1_SOURCE | 0x10;
- static final int C2_SOURCE_CHUNK= C1_SOURCE | 0x80;
+ static final int C1_BUNDLE= 0x1 << SHIFT_C1;
+ static final int C1_SOURCE= 0x2 << SHIFT_C1;
+ static final int C12_SOURCE_FILE= C1_SOURCE | 0x1 << SHIFT_C2;
+ static final int C12_SOURCE_CHUNK= C1_SOURCE | 0x8 << SHIFT_C2;
+ static final int C1_IMPORT= 0x3 << SHIFT_C1;
+ static final int C1_CLASS= 0x4 << SHIFT_C1;
+ static final int C1_METHOD= 0x5 << SHIFT_C1;
+ static final int C1_VARIABLE= 0x6 << SHIFT_C1;
+ static final int C1_EMBEDDED= 0x8 << SHIFT_C1;
String getModelTypeId();
diff --git a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/impl/GenericFragmentSourceUnit.java b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/impl/GenericFragmentSourceUnit.java
index 5281445..b9340cc 100644
--- a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/impl/GenericFragmentSourceUnit.java
+++ b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/impl/GenericFragmentSourceUnit.java
@@ -97,11 +97,11 @@
* {@inheritDoc}
*
* A source unit of this type is usually of the type
- * {@link LtkModelElement#C2_SOURCE_CHUNK C2_SOURCE_CHUNK}.
+ * {@link LtkModelElement#C12_SOURCE_CHUNK C2_SOURCE_CHUNK}.
*/
@Override
public int getElementType() {
- return LtkModelElement.C2_SOURCE_CHUNK;
+ return LtkModelElement.C12_SOURCE_CHUNK;
}
@Override
diff --git a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/impl/GenericResourceSourceUnit.java b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/impl/GenericResourceSourceUnit.java
index 15e5894..945d921 100644
--- a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/impl/GenericResourceSourceUnit.java
+++ b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/impl/GenericResourceSourceUnit.java
@@ -129,11 +129,11 @@
* {@inheritDoc}
*
* A source unit of this type is usually of the type
- * {@link LtkModelElement#C2_SOURCE_FILE C2_SOURCE_FILE}.
+ * {@link LtkModelElement#C12_SOURCE_FILE C2_SOURCE_FILE}.
*/
@Override
public int getElementType() {
- return C2_SOURCE_FILE;
+ return C12_SOURCE_FILE;
}
@Override
diff --git a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/impl/GenericUriSourceUnit.java b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/impl/GenericUriSourceUnit.java
index 9fb093f..bf31dcc 100644
--- a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/impl/GenericUriSourceUnit.java
+++ b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/impl/GenericUriSourceUnit.java
@@ -95,11 +95,11 @@
* {@inheritDoc}
*
* A source unit of this type is usually of the type
- * {@link LtkModelElement#C2_SOURCE_FILE C2_SOURCE_FILE}.
+ * {@link LtkModelElement#C12_SOURCE_FILE C2_SOURCE_FILE}.
*/
@Override
public int getElementType() {
- return LtkModelElement.C2_SOURCE_FILE;
+ return LtkModelElement.C12_SOURCE_FILE;
}
@Override
diff --git a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/refactoring/core/RefactoringAdapter.java b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/refactoring/core/RefactoringAdapter.java
index 8e837e9..42e1b61 100644
--- a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/refactoring/core/RefactoringAdapter.java
+++ b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/refactoring/core/RefactoringAdapter.java
@@ -539,7 +539,7 @@
}
public void checkFinalToDelete(final RefactoringStatus result, final LtkModelElement element) throws CoreException {
- if ((element.getElementType() & LtkModelElement.MASK_C2) == LtkModelElement.C2_SOURCE_FILE) {
+ if ((element.getElementType() & LtkModelElement.MASK_C12) == LtkModelElement.C12_SOURCE_FILE) {
if (element instanceof WorkspaceSourceUnit) {
checkFinalToDelete(result, ((WorkspaceSourceUnit)element).getResource());
}
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/internal/ltk/ui/refactoring/ModelElementTester.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/internal/ltk/ui/refactoring/ModelElementTester.java
index 3482fc9..60624a3 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/internal/ltk/ui/refactoring/ModelElementTester.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/internal/ltk/ui/refactoring/ModelElementTester.java
@@ -47,7 +47,7 @@
mask= LtkModelElement.MASK_C1;
}
else if (IS_ELEMENT_C2_TYPE_SELECTION.equals(property)) {
- mask= LtkModelElement.MASK_C2;
+ mask= LtkModelElement.MASK_C12;
}
int numSu= 1;
String modelType= (String) expectedValue;
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ElementContentProvider.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ElementContentProvider.java
new file mode 100644
index 0000000..149f9a1
--- /dev/null
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ElementContentProvider.java
@@ -0,0 +1,48 @@
+/*=============================================================================#
+ # Copyright (c) 2021 Stephan Wahlbrink and others.
+ #
+ # This program and the accompanying materials are made available under the
+ # terms of the Eclipse Public License 2.0 which is available at
+ # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ # which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ #
+ # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ #
+ # Contributors:
+ # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
+ #=============================================================================*/
+
+package org.eclipse.statet.ltk.ui;
+
+import java.util.List;
+
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
+
+import org.eclipse.statet.ltk.model.core.element.LtkModelElement;
+import org.eclipse.statet.ltk.model.core.element.LtkModelElementFilter;
+import org.eclipse.statet.ltk.model.core.element.SourceStructElement;
+
+
+@NonNullByDefault
+public interface ElementContentProvider {
+
+
+ default @Nullable SourceStructElement<?, ?> getSourceParent(
+ final SourceStructElement<?, ?> element) {
+ return element.getSourceParent();
+ }
+
+ default boolean hasSourceChildren(
+ final SourceStructElement<?, ?> element,
+ final @Nullable LtkModelElementFilter<? super SourceStructElement<?, ?>> filter) {
+ return element.hasSourceChildren(filter);
+ }
+
+ default List<? extends LtkModelElement<?>> getSourceChildren(
+ final SourceStructElement<?, ?> element,
+ final @Nullable LtkModelElementFilter<? super SourceStructElement<?, ?>> filter) {
+ return element.getSourceChildren(filter);
+ }
+
+}
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ElementLabelProvider.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ElementLabelProvider.java
index ccc4c84..8931317 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ElementLabelProvider.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ElementLabelProvider.java
@@ -36,24 +36,29 @@
static final StyledString.Styler TITLE_STYLER= new StyledString.Styler() {
@Override
public void applyStyles(final TextStyle style) {
- ((StyleRange) style).fontStyle= SWT.BOLD;
+ ((StyleRange)style).fontStyle= SWT.BOLD;
};
};
- String getText(final LtkModelElement element);
+ default @Nullable Image getImage(final LtkModelElement<?> element) {
+ return null;
+ }
-// void decorateText(final StringBuilder text, final LtkModelElement element);
+ default @Nullable String getText(final LtkModelElement<?> element) {
+ return null;
+ }
- StyledString getStyledText(final LtkModelElement element);
+ default @Nullable StyledString getStyledText(final LtkModelElement<?> element) {
+ final var text= getText(element);
+ return (text != null) ? new StyledString(text) : null;
+ }
- default int @Nullable [] getStyledTextRegions(final LtkModelElement element,
+ default int @Nullable [] getStyledTextRegions(final LtkModelElement<?> element,
final int flags, final int[] regions) {
return null;
}
// void decorateStyledText(final StyledString text, final LtkModelElement element);
- Image getImage(final LtkModelElement element);
-
}
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/OutlineContentProvider.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/OutlineContentProvider.java
deleted file mode 100644
index 4a6c490..0000000
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/OutlineContentProvider.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*=============================================================================#
- # Copyright (c) 2014, 2021 Stephan Wahlbrink and others.
- #
- # This program and the accompanying materials are made available under the
- # terms of the Eclipse Public License 2.0 which is available at
- # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
- # which is available at https://www.apache.org/licenses/LICENSE-2.0.
- #
- # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
- #
- # Contributors:
- # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
- #=============================================================================*/
-
-package org.eclipse.statet.ltk.ui.sourceediting;
-
-import java.util.List;
-
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-import org.eclipse.statet.jcommons.lang.NonNull;
-import org.eclipse.statet.jcommons.lang.NonNullByDefault;
-import org.eclipse.statet.jcommons.lang.Nullable;
-
-import org.eclipse.statet.ltk.core.source.SourceModelStamp;
-import org.eclipse.statet.ltk.model.core.element.LtkModelElementFilter;
-import org.eclipse.statet.ltk.model.core.element.SourceStructElement;
-import org.eclipse.statet.ltk.model.core.element.SourceUnitModelInfo;
-
-
-@NonNullByDefault
-public class OutlineContentProvider implements ITreeContentProvider {
-
-
- private static final @NonNull SourceStructElement<?, ?>[] NO_CHILDREN= new @NonNull SourceStructElement[0];
-
-
- public interface OutlineContent {
-
- @Nullable SourceUnitModelInfo getModelInfo(Object inputElement);
-
- @Nullable LtkModelElementFilter<? super SourceStructElement<?, ?>> getContentFilter();
-
- }
-
-
- private final OutlineContent content;
-
-
- public OutlineContentProvider(final OutlineContent content) {
- this.content= content;
- }
-
-
- protected final OutlineContent getContent() {
- return this.content;
- }
-
- public @Nullable SourceModelStamp getStamp(final Object inputElement) {
- final SourceUnitModelInfo modelInfo= getContent().getModelInfo(inputElement);
- return (modelInfo != null) ? modelInfo.getStamp() : null;
- }
-
- @Override
- public void inputChanged(final Viewer viewer, final @Nullable Object oldInput, final @Nullable Object newInput) {
- }
-
- @Override
- public void dispose() {
- }
-
-
- protected SourceStructElement[] getElements(final @Nullable SourceUnitModelInfo modelInfo) {
- if (modelInfo != null) {
- final List<? extends SourceStructElement<?, ?>> children= modelInfo.getSourceElement()
- .getSourceChildren(getContent().getContentFilter());
- return children.toArray(new @NonNull SourceStructElement[children.size()]);
- }
- return NO_CHILDREN;
- }
-
- protected @Nullable SourceStructElement getParent(final SourceStructElement<?, ?> element) {
- return element.getSourceParent();
- }
-
- protected boolean hasChildren(final @Nullable SourceStructElement<?, ?> element) {
- return (element != null
- && element.hasSourceChildren(getContent().getContentFilter()) );
- }
-
- protected SourceStructElement[] getChildren(final @Nullable SourceStructElement<?, ?> element) {
- if (element != null) {
- final List<? extends SourceStructElement> children= element
- .getSourceChildren(getContent().getContentFilter());
- return children.toArray(new @NonNull SourceStructElement[children.size()]);
- }
- return NO_CHILDREN;
- }
-
-
- @Override
- public @NonNull Object[] getElements(final Object inputElement) {
- return getElements(getContent().getModelInfo(inputElement));
- }
-
- @Override
- public @Nullable Object getParent(final Object element) {
- return getParent((SourceStructElement<?, ?>)element);
- }
-
- @Override
- public boolean hasChildren(final Object element) {
- return hasChildren((SourceStructElement<?, ?>)element);
- }
-
- @Override
- public @NonNull Object[] getChildren(final Object element) {
- return getChildren((SourceStructElement<?, ?>)element);
- }
-
-}
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/QuickOutlineInformationControl.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/QuickOutlineInformationControl.java
index b08a880..a5904e1 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/QuickOutlineInformationControl.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/QuickOutlineInformationControl.java
@@ -14,9 +14,13 @@
package org.eclipse.statet.ltk.ui.sourceediting;
+import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullLateInit;
+
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;
@@ -36,6 +40,8 @@
import org.eclipse.statet.ltk.model.core.element.SourceUnitModelInfo;
import org.eclipse.statet.ltk.ui.LtkActions;
import org.eclipse.statet.ltk.ui.sourceediting.actions.OpenDeclaration;
+import org.eclipse.statet.ltk.ui.util.ExtModelContentProvider;
+import org.eclipse.statet.ltk.ui.util.ExtModelLabelProvider;
/**
@@ -48,7 +54,7 @@
protected static final String INHERITED_COLOR_NAME= "org.eclipse.jdt.ui.ColoredLabels.inherited"; //$NON-NLS-1$
- protected class QuickOutlineContent implements OutlineContentProvider.OutlineContent {
+ protected class QuickOutlineContent implements ExtModelContentProvider.ModelContent {
public QuickOutlineContent() {
@@ -69,7 +75,7 @@
private final OpenDeclaration opener;
- private OutlineContentProvider contentProvider;
+ private ITreeContentProvider contentProvider= nonNullLateInit();
private boolean requireFullName;
@@ -90,7 +96,7 @@
}
- public abstract String getModelTypeId();
+ public abstract String getModelTypeId(int page);
@Override
protected IDialogSettings getDialogSettings() {
@@ -128,15 +134,21 @@
protected void configureViewer(final TreeViewer viewer) {
this.contentProvider= createContentProvider();
viewer.setContentProvider(this.contentProvider);
+ viewer.setLabelProvider(createLabelProvider());
}
- protected OutlineContentProvider createContentProvider() {
- return new OutlineContentProvider(new QuickOutlineContent());
+ protected ITreeContentProvider createContentProvider() {
+ return new ExtModelContentProvider(new QuickOutlineContent());
+ }
+
+ protected ILabelProvider createLabelProvider() {
+ return new ExtModelLabelProvider(getModelTypeId(0));
}
protected @Nullable SourceUnitModelInfo getModelInfo(final Object input) {
if (input instanceof SourceUnit) {
- return ((SourceUnit) input).getModelInfo(getModelTypeId(), 0, null);
+ final String modelTypeId= getModelTypeId(getIterationPosition());
+ return ((SourceUnit)input).getModelInfo(modelTypeId, 0, null);
}
return null;
}
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor1.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor1.java
index fce88bc..a777de7 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor1.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor1.java
@@ -678,12 +678,12 @@
case LtkModelElement.C1_METHOD:
return expand(element.getSourceRange(), element.getDocumentationRange());
case LtkModelElement.C1_SOURCE:
- if ((element.getElementType() & LtkModelElement.MASK_C2) == LtkModelElement.C2_SOURCE_CHUNK) {
+ if ((element.getElementType() & LtkModelElement.MASK_C12) == LtkModelElement.C12_SOURCE_CHUNK) {
return expand(element.getSourceRange(), element.getDocumentationRange());
}
return null;
case LtkModelElement.C1_VARIABLE:
- if ((element.getSourceParent().getElementType() & LtkModelElement.MASK_C2) == LtkModelElement.C2_SOURCE_FILE) {
+ if ((element.getSourceParent().getElementType() & LtkModelElement.MASK_C12) == LtkModelElement.C12_SOURCE_FILE) {
return expand(element.getSourceRange(), element.getDocumentationRange());
}
//$FALL-THROUGH$
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor1OutlinePage.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor1OutlinePage.java
index 39aeed4..1fd4883 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor1OutlinePage.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor1OutlinePage.java
@@ -68,6 +68,7 @@
import org.eclipse.statet.ltk.ui.LTKInputData;
import org.eclipse.statet.ltk.ui.ModelElementInputListener;
import org.eclipse.statet.ltk.ui.SelectionWithElementInfoListener;
+import org.eclipse.statet.ltk.ui.util.ExtModelContentProvider;
/**
@@ -80,7 +81,7 @@
IPostSelectionProvider, ModelElementInputListener<LtkModelElement<?>> {
- protected class PageOutlineContent implements OutlineContentProvider.OutlineContent {
+ protected class PageOutlineContent implements ExtModelContentProvider.ModelContent {
public PageOutlineContent() {
@@ -99,7 +100,7 @@
}
- public class AstContentProvider extends OutlineContentProvider {
+ public class AstContentProvider extends ExtModelContentProvider {
public AstContentProvider() {
@@ -229,7 +230,7 @@
private final SourceEditor1 editor;
private final String mainType;
- private OutlineContentProvider contentProvider;
+ private ExtModelContentProvider contentProvider;
private @Nullable SourceModelStamp currentModelStamp;
@@ -279,8 +280,8 @@
getViewer().setInput(this.inputUnit);
}
- protected OutlineContentProvider createContentProvider() {
- return new OutlineContentProvider(new PageOutlineContent());
+ protected ExtModelContentProvider createContentProvider() {
+ return new ExtModelContentProvider(new PageOutlineContent());
}
@Override
@@ -402,7 +403,7 @@
selectedElement= currentSelection.getFirstElement();
}
while (element != null
- && (element.getElementType() & LtkModelElement.MASK_C2) != LtkModelElement.C2_SOURCE_FILE) {
+ && (element.getElementType() & LtkModelElement.MASK_C12) != LtkModelElement.C12_SOURCE_FILE) {
if (selectedElement != null && element.equals(selectedElement)) {
return;
}
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/util/ExtModelContentProvider.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/util/ExtModelContentProvider.java
new file mode 100644
index 0000000..4bf2f08
--- /dev/null
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/util/ExtModelContentProvider.java
@@ -0,0 +1,193 @@
+/*=============================================================================#
+ # Copyright (c) 2021 Stephan Wahlbrink and others.
+ #
+ # This program and the accompanying materials are made available under the
+ # terms of the Eclipse Public License 2.0 which is available at
+ # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ # which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ #
+ # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ #
+ # Contributors:
+ # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
+ #=============================================================================*/
+
+package org.eclipse.statet.ltk.ui.util;
+
+import java.util.IdentityHashMap;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+import org.eclipse.statet.jcommons.lang.Disposable;
+import org.eclipse.statet.jcommons.lang.NonNull;
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
+
+import org.eclipse.statet.ltk.core.source.SourceModelStamp;
+import org.eclipse.statet.ltk.model.core.LtkModels;
+import org.eclipse.statet.ltk.model.core.element.EmbeddingForeignElement;
+import org.eclipse.statet.ltk.model.core.element.LtkModelElement;
+import org.eclipse.statet.ltk.model.core.element.LtkModelElementFilter;
+import org.eclipse.statet.ltk.model.core.element.SourceStructElement;
+import org.eclipse.statet.ltk.model.core.element.SourceUnitModelInfo;
+import org.eclipse.statet.ltk.ui.ElementContentProvider;
+
+
+@NonNullByDefault
+public class ExtModelContentProvider implements ITreeContentProvider {
+
+
+ private static final @NonNull SourceStructElement<?, ?>[] NO_CHILDREN= new SourceStructElement[0];
+
+ protected static final ElementContentProvider NO_PROVIDER= new ElementContentProvider() {
+ };
+
+
+ private final IdentityHashMap<String, ElementContentProvider> providers= new IdentityHashMap<>(4);
+
+
+ public interface ModelContent {
+
+ @Nullable SourceUnitModelInfo getModelInfo(Object inputElement);
+
+ @Nullable LtkModelElementFilter<? super SourceStructElement<?, ?>> getContentFilter();
+
+ }
+
+
+ private final ModelContent content;
+
+
+ public ExtModelContentProvider(final ModelContent content) {
+ this.content= content;
+ }
+
+ @Override
+ public void dispose() {
+ for (final var provider : this.providers.values()) {
+ if (provider instanceof Disposable) {
+ ((Disposable)provider).dispose();
+ }
+ }
+ this.providers.clear();
+ }
+
+
+ protected final ModelContent getContent() {
+ return this.content;
+ }
+
+ public @Nullable SourceModelStamp getStamp(final Object inputElement) {
+ final SourceUnitModelInfo modelInfo= getContent().getModelInfo(inputElement);
+ return (modelInfo != null) ? modelInfo.getStamp() : null;
+ }
+
+ @Override
+ public void inputChanged(final Viewer viewer, final @Nullable Object oldInput, final @Nullable Object newInput) {
+ }
+
+
+ protected @Nullable ElementContentProvider getElementContentProvider(final @Nullable String modelId) {
+ if (modelId == null) {
+ return null;
+ }
+ var provider= this.providers.get(modelId);
+ if (provider == null) {
+ provider= LtkModels.getModelAdapter(modelId, ElementContentProvider.class);
+ if (provider == null) {
+ provider= NO_PROVIDER;
+ }
+ this.providers.put(modelId, provider);
+ }
+ return (provider != NO_PROVIDER) ? provider : null;
+ }
+
+ protected void addProvider(final String modelId, final ElementContentProvider provider) {
+ this.providers.put(modelId, provider);
+ }
+
+
+ private boolean skipToForeignElement(final @Nullable SourceStructElement<?, ?> element) {
+ return (element != null
+ && (element.getElementType() & LtkModelElement.MASK_C1) == LtkModelElement.C1_EMBEDDED );
+ }
+
+ protected boolean skipInTree(final SourceStructElement<?, ?> element) {
+ return false;
+ }
+
+ protected @NonNull SourceStructElement<?, ?>[] getElements(final @Nullable SourceUnitModelInfo modelInfo) {
+ if (modelInfo != null) {
+ final var children= modelInfo.getSourceElement()
+ .getSourceChildren(getContent().getContentFilter());
+ return children.toArray(new @NonNull SourceStructElement[children.size()]);
+ }
+ return NO_CHILDREN;
+ }
+
+ protected @Nullable SourceStructElement<?, ?> getParent(final SourceStructElement<?, ?> element) {
+ var parent= element.getSourceParent();
+ while (parent != null && (skipToForeignElement(parent) || skipInTree(parent))) {
+ parent= parent.getSourceParent();
+ }
+ return parent;
+ }
+
+ protected boolean hasChildren(@Nullable SourceStructElement<?, ?> element) {
+ if (skipToForeignElement(element)) {
+ element= ((EmbeddingForeignElement<?, ?>)element).getForeignElement();
+ }
+ ElementContentProvider provider;
+ if (element != null) {
+ if ((provider= getElementContentProvider(element.getModelTypeId())) != null) {
+ return provider.hasSourceChildren(element, getContent().getContentFilter());
+ }
+ else {
+ return element.hasSourceChildren(getContent().getContentFilter());
+ }
+ }
+ return false;
+ }
+
+ protected @NonNull SourceStructElement<?, ?>[] getChildren(@Nullable SourceStructElement<?, ?> element) {
+ if (skipToForeignElement(element)) {
+ element= ((EmbeddingForeignElement<?, ?>)element).getForeignElement();
+ }
+ ElementContentProvider provider;
+ if (element != null) {
+ List<? extends LtkModelElement<?>> children;
+ if ((provider= getElementContentProvider(element.getModelTypeId())) != null) {
+ children= provider.getSourceChildren(element, getContent().getContentFilter());
+ }
+ else {
+ children= element.getSourceChildren(getContent().getContentFilter());
+ }
+ return children.toArray(new @NonNull SourceStructElement[children.size()]);
+ }
+ return NO_CHILDREN;
+ }
+
+
+ @Override
+ public @NonNull Object[] getElements(final Object inputElement) {
+ return getElements(getContent().getModelInfo(inputElement));
+ }
+
+ @Override
+ public @Nullable Object getParent(final Object element) {
+ return getParent((SourceStructElement<?, ?>)element);
+ }
+
+ @Override
+ public boolean hasChildren(final Object element) {
+ return hasChildren((SourceStructElement<?, ?>)element);
+ }
+
+ @Override
+ public @NonNull Object[] getChildren(final Object element) {
+ return getChildren((SourceStructElement<?, ?>)element);
+ }
+
+}
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/util/ExtModelLabelProvider.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/util/ExtModelLabelProvider.java
new file mode 100644
index 0000000..c5d4d2b
--- /dev/null
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/util/ExtModelLabelProvider.java
@@ -0,0 +1,201 @@
+/*=============================================================================#
+ # Copyright (c) 2021 Stephan Wahlbrink and others.
+ #
+ # This program and the accompanying materials are made available under the
+ # terms of the Eclipse Public License 2.0 which is available at
+ # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ # which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ #
+ # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ #
+ # Contributors:
+ # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
+ #=============================================================================*/
+
+package org.eclipse.statet.ltk.ui.util;
+
+import java.util.IdentityHashMap;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.StyledCellLabelProvider;
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.jface.viewers.ViewerCell;
+import org.eclipse.swt.graphics.Image;
+
+import org.eclipse.statet.jcommons.lang.Disposable;
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
+
+import org.eclipse.statet.ltk.model.core.LtkModels;
+import org.eclipse.statet.ltk.model.core.element.EmbeddingForeignElement;
+import org.eclipse.statet.ltk.model.core.element.LtkModelElement;
+import org.eclipse.statet.ltk.ui.ElementLabelProvider;
+
+
+@NonNullByDefault
+public class ExtModelLabelProvider extends StyledCellLabelProvider
+ implements ILabelProvider, ElementLabelProvider, Disposable {
+
+
+ protected static final ElementLabelProvider NO_PROVIDER= new ElementLabelProvider() {
+ };
+
+
+ private final IdentityHashMap<String, ElementLabelProvider> providers= new IdentityHashMap<>(4);
+
+ private @Nullable String modelTypeId;
+
+
+ public ExtModelLabelProvider(final String modelTypeId) {
+ this.modelTypeId= modelTypeId;
+ }
+
+ public ExtModelLabelProvider() {
+ }
+
+
+ @Override
+ public void dispose() {
+ for (final var provider : this.providers.values()) {
+ if (provider instanceof Disposable) {
+ ((Disposable)provider).dispose();
+ }
+ }
+ this.providers.clear();
+
+ super.dispose();
+ }
+
+
+ protected @Nullable ElementLabelProvider getElementLabelProvider(final @Nullable String modelId) {
+ if (modelId == null) {
+ return null;
+ }
+ var provider= this.providers.get(modelId);
+ if (provider == null) {
+ provider= LtkModels.getModelAdapter(modelId, ElementLabelProvider.class);
+ if (provider == null) {
+ provider= NO_PROVIDER;
+ }
+ this.providers.put(modelId, provider);
+ }
+ return (provider != NO_PROVIDER) ? provider : null;
+ }
+
+ protected void addProvider(final String modelId, final ElementLabelProvider provider) {
+ this.providers.put(modelId, provider);
+ }
+
+
+ @Override
+ public @Nullable Image getImage(final @Nullable Object element) {
+ if (element instanceof LtkModelElement) {
+ return getImage((LtkModelElement<?>)element);
+ }
+ return null;
+ }
+
+ @Override
+ public @Nullable String getText(final @Nullable Object element) {
+ if (element instanceof LtkModelElement) {
+ return getText((LtkModelElement<?>)element);
+ }
+ return null;
+ }
+
+
+ @Override
+ public @Nullable Image getImage(final LtkModelElement<?> element) {
+ final boolean embedding= ((element.getElementType() & LtkModelElement.MASK_C1) == LtkModelElement.C1_EMBEDDED);
+ Image image= null;
+ ElementLabelProvider provider;
+ if (image == null && embedding && this.modelTypeId != element.getModelTypeId()
+ && (provider= getElementLabelProvider(this.modelTypeId)) != null) {
+ image= provider.getImage(element);
+ }
+ if (image == null
+ && (provider= getElementLabelProvider(element.getModelTypeId())) != null) {
+ image= provider.getImage(element);
+ }
+ if (image == null && embedding) {
+ final var embeddedElement= ((EmbeddingForeignElement<?, ?>)element).getForeignElement();
+ if (embeddedElement != null
+ && (provider= getElementLabelProvider(embeddedElement.getModelTypeId())) != null) {
+ image= provider.getImage(embeddedElement);
+ }
+ }
+ return image;
+ }
+
+ @Override
+ public String getText(final LtkModelElement<?> element) {
+ final boolean embedding= ((element.getElementType() & LtkModelElement.MASK_C1) == LtkModelElement.C1_EMBEDDED);
+ String text= null;
+ ElementLabelProvider provider;
+ if (text == null && embedding && this.modelTypeId != element.getModelTypeId()
+ && (provider= getElementLabelProvider(this.modelTypeId)) != null) {
+ text= provider.getText(element);
+ }
+ if (text == null
+ && (provider= getElementLabelProvider(element.getModelTypeId())) != null) {
+ text= provider.getText(element);
+ }
+ if (text == null && embedding) {
+ final var embeddedElement= ((EmbeddingForeignElement<?, ?>)element).getForeignElement();
+ if (embeddedElement != null
+ && (provider= getElementLabelProvider(embeddedElement.getModelTypeId())) != null) {
+ text= provider.getText(embeddedElement);
+ }
+ }
+ if (text == null) {
+ text= element.getElementName().getDisplayName();
+ }
+ return text;
+ }
+
+ @Override
+ public StyledString getStyledText(final LtkModelElement<?> element) {
+ final boolean embedding= ((element.getElementType() & LtkModelElement.MASK_C1) == LtkModelElement.C1_EMBEDDED);
+ StyledString text= null;
+ ElementLabelProvider provider;
+ if (text == null && embedding && this.modelTypeId != element.getModelTypeId()
+ && (provider= getElementLabelProvider(this.modelTypeId)) != null) {
+ text= provider.getStyledText(element);
+ }
+ if (text == null
+ && (provider= getElementLabelProvider(element.getModelTypeId())) != null) {
+ text= provider.getStyledText(element);
+ }
+ if (text == null && embedding) {
+ final var embeddedElement= ((EmbeddingForeignElement<?, ?>)element).getForeignElement();
+ if (embeddedElement != null
+ && (provider= getElementLabelProvider(embeddedElement.getModelTypeId())) != null) {
+ text= provider.getStyledText(embeddedElement);
+ }
+ }
+ if (text == null) {
+ text= new StyledString(element.getElementName().getDisplayName());
+ }
+ return text;
+ }
+
+
+ @Override
+ public void update(final ViewerCell cell) {
+ final Object cellElement= cell.getElement();
+ if (cellElement instanceof LtkModelElement) {
+ final var element= (LtkModelElement<?>)cellElement;
+ cell.setImage(getImage(element));
+ final StyledString styledText= getStyledText(element);
+ cell.setText(styledText.getString());
+ cell.setStyleRanges(styledText.getStyleRanges());
+ }
+ else {
+ cell.setImage(null);
+ cell.setText(cellElement.toString());
+ cell.setStyleRanges(null);
+ }
+ super.update(cell);
+ }
+
+}