Skip to content

Package: AbstractSWTTabRenderer$1

AbstractSWTTabRenderer$1

nameinstructionbranchcomplexitylinemethod
widgetSelected(SelectionEvent)
M: 7 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
{...}
M: 0 C: 9
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2019 EclipseSource Muenchen GmbH and others.
3: *
4: * All rights reserved. This program and the accompanying materials
5: * are made available under the terms of the Eclipse Public License 2.0
6: * which accompanies this distribution, and is available at
7: * https://www.eclipse.org/legal/epl-2.0/
8: *
9: * SPDX-License-Identifier: EPL-2.0
10: *
11: * Contributors:
12: * Eugen Neufeld - initial API and implementation
13: * Christian W. Damus - bugs 548592, 552852
14: ******************************************************************************/
15: package org.eclipse.emf.ecp.view.spi.categorization.swt;
16:
17: import java.util.LinkedHashMap;
18: import java.util.Map;
19: import java.util.Set;
20:
21: import org.eclipse.core.databinding.observable.value.IObservableValue;
22: import org.eclipse.core.runtime.IStatus;
23: import org.eclipse.core.runtime.Status;
24: import org.eclipse.emf.common.util.EList;
25: import org.eclipse.emf.databinding.EMFDataBindingContext;
26: import org.eclipse.emf.databinding.edit.EMFEditObservables;
27: import org.eclipse.emf.ecp.view.internal.categorization.swt.Activator;
28: import org.eclipse.emf.ecp.view.internal.categorization.swt.ValidationTabImageHelper;
29: import org.eclipse.emf.ecp.view.spi.categorization.model.VAbstractCategorization;
30: import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
31: import org.eclipse.emf.ecp.view.spi.model.VDiagnostic;
32: import org.eclipse.emf.ecp.view.spi.model.VElement;
33: import org.eclipse.emf.ecp.view.spi.model.VViewPackage;
34: import org.eclipse.emf.ecp.view.spi.model.reporting.StatusReport;
35: import org.eclipse.emf.ecp.view.spi.renderer.NoPropertyDescriptorFoundExeption;
36: import org.eclipse.emf.ecp.view.spi.renderer.NoRendererFoundException;
37: import org.eclipse.emf.ecp.view.template.model.VTStyleProperty;
38: import org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider;
39: import org.eclipse.emf.ecp.view.template.style.tab.model.VTTabStyleProperty;
40: import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
41: import org.eclipse.emf.edit.domain.EditingDomain;
42: import org.eclipse.emfforms.common.Optional;
43: import org.eclipse.emfforms.spi.common.report.ReportService;
44: import org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer;
45: import org.eclipse.emfforms.spi.swt.core.EMFFormsNoRendererException;
46: import org.eclipse.emfforms.spi.swt.core.EMFFormsRendererFactory;
47: import org.eclipse.emfforms.spi.swt.core.SWTDataElementIdHelper;
48: import org.eclipse.emfforms.spi.swt.core.layout.GridDescriptionFactory;
49: import org.eclipse.emfforms.spi.swt.core.layout.SWTGridCell;
50: import org.eclipse.emfforms.spi.swt.core.layout.SWTGridDescription;
51: import org.eclipse.jface.databinding.swt.typed.WidgetProperties;
52: import org.eclipse.jface.layout.GridDataFactory;
53: import org.eclipse.jface.layout.GridLayoutFactory;
54: import org.eclipse.swt.SWT;
55: import org.eclipse.swt.custom.CTabFolder;
56: import org.eclipse.swt.custom.CTabItem;
57: import org.eclipse.swt.custom.ScrolledComposite;
58: import org.eclipse.swt.events.SelectionAdapter;
59: import org.eclipse.swt.events.SelectionEvent;
60: import org.eclipse.swt.graphics.Image;
61: import org.eclipse.swt.widgets.Composite;
62: import org.eclipse.swt.widgets.Control;
63:
64: /**
65: * Abstract class for a tab renderer.
66: *
67: * @author Eugen Neufeld
68: * @param <VELEMENT> the {@link VElement}
69: */
70: public abstract class AbstractSWTTabRenderer<VELEMENT extends VElement> extends AbstractSWTRenderer<VELEMENT> {
71:
72:         private final Map<CTabItem, VAbstractCategorization> itemToCategorizationMap = new LinkedHashMap<CTabItem, VAbstractCategorization>();
73:         private final Map<VAbstractCategorization, CTabItem> categorizationToItemMap = new LinkedHashMap<VAbstractCategorization, CTabItem>();
74:         private final Map<CTabItem, Composite> itemToCompositeMap = new LinkedHashMap<CTabItem, Composite>();
75:
76:         private final EMFFormsRendererFactory emfFormsRendererFactory;
77:         private final EMFDataBindingContext dataBindingContext;
78:         private final VTViewTemplateProvider viewTemplateProvider;
79:
80:         private EMFFormsRendererFactory getEMFFormsRendererFactory() {
81:                 return emfFormsRendererFactory;
82:         }
83:
84:         /**
85:          * Default constructor.
86:          *
87:          * @param vElement the view model element to be rendered
88:          * @param viewContext the view context
89:          * @param reportService the {@link ReportService}
90:          * @param emfFormsRendererFactory The {@link EMFFormsRendererFactory}
91:          * @param viewTemplateProvider the {@link VTViewTemplateProvider}
92:          * @since 1.8
93:          */
94:         public AbstractSWTTabRenderer(
95:                 VELEMENT vElement,
96:                 ViewModelContext viewContext,
97:                 ReportService reportService,
98:                 EMFFormsRendererFactory emfFormsRendererFactory,
99:                 VTViewTemplateProvider viewTemplateProvider) {
100:                 super(vElement, viewContext, reportService);
101:                 this.emfFormsRendererFactory = emfFormsRendererFactory;
102:                 this.viewTemplateProvider = viewTemplateProvider;
103:                 dataBindingContext = new EMFDataBindingContext();
104:         }
105:
106:         /**
107:          * Returns the view template provider.
108:          *
109:          * @return the {@link VTViewTemplateProvider}
110:          * @since 1.8
111:          */
112:         protected final VTViewTemplateProvider getViewTemplateProvider() {
113:                 return viewTemplateProvider;
114:         }
115:
116:         @Override
117:         public SWTGridDescription getGridDescription(SWTGridDescription gridDescription) {
118:                 return GridDescriptionFactory.INSTANCE.createSimpleGrid(1, 1, this);
119:         }
120:
121:         @Override
122:         protected Control renderControl(SWTGridCell cell, Composite parent)
123:                 throws NoRendererFoundException, NoPropertyDescriptorFoundExeption {
124:                 final boolean useScrolledContent = useScrolledContent();
125:
126:                 final CTabFolder folder = new CTabFolder(parent, getTabFolderStyle());
127:                 folder.addSelectionListener(new SelectionAdapter() {
128:                         @Override
129:                         public void widgetSelected(SelectionEvent e) {
130:                                 itemSelected(folder.getSelection());
131:                         }
132:                 });
133:                 folder.setBackground(parent.getBackground());
134:                 final EList<VAbstractCategorization> categorizations = getCategorizations();
135:                 for (final VAbstractCategorization categorization : categorizations) {
136:                         final CTabItem item = new CTabItem(folder, SWT.NULL);
137:                         final Composite composite;
138:                         if (useScrolledContent) {
139:                                 composite = new ScrolledComposite(folder, SWT.V_SCROLL | SWT.H_SCROLL);
140:                         } else {
141:                                 composite = new Composite(folder, SWT.NONE);
142:                                 GridLayoutFactory.fillDefaults().applyTo(composite);
143:                         }
144:
145:                         itemToCategorizationMap.put(item, categorization);
146:                         categorizationToItemMap.put(categorization, item);
147:                         itemToCompositeMap.put(item, composite);
148:
149:                         final EditingDomain editingDomain = AdapterFactoryEditingDomain.getEditingDomainFor(categorization);
150:                         final IObservableValue modelLabelValue = EMFEditObservables.observeValue(
151:                                 editingDomain,
152:                                 categorization,
153:                                 VViewPackage.eINSTANCE.getElement_Label());
154:                         final IObservableValue targetLabelValue = WidgetProperties.text().observe(item);
155:                         dataBindingContext.bindValue(targetLabelValue, modelLabelValue);
156:
157:                         final IObservableValue modelTooltipValue = EMFEditObservables.observeValue(
158:                                 editingDomain,
159:                                 categorization,
160:                                 VViewPackage.eINSTANCE.getHasTooltip_Tooltip());
161:                         final IObservableValue targetTooltipValue = WidgetProperties.tooltipText().observe(item);
162:                         dataBindingContext.bindValue(targetTooltipValue, modelTooltipValue);
163:
164:                         if (!renderLazy()) {
165:                                 renderItem(item);
166:                         }
167:                         SWTDataElementIdHelper.setElementIdDataWithSubId(item, categorization, "tabitem", getViewModelContext()); //$NON-NLS-1$
168:                         SWTDataElementIdHelper.setElementIdDataWithSubId(composite, categorization, "tabitem-composite", //$NON-NLS-1$
169:                                 getViewModelContext());
170:                 }
171:                 if (folder.getItemCount() > 0) {
172:                         folder.setSelection(0);
173:                         itemSelected(folder.getSelection());
174:                 }
175:                 SWTDataElementIdHelper.setElementIdDataWithSubId(folder, getVElement(), "tabfolder", getViewModelContext()); //$NON-NLS-1$
176:                 return folder;
177:         }
178:
179:         private void renderItem(final CTabItem item) throws NoRendererFoundException, NoPropertyDescriptorFoundExeption {
180:                 if (!itemToCategorizationMap.containsKey(item)) {
181:                         return;/* already rendered or invalid state */
182:                 }
183:
184:                 /* remove from the maps on first rendering */
185:                 final VAbstractCategorization categorization = itemToCategorizationMap.remove(item);
186:                 final Composite composite = itemToCompositeMap.remove(item);
187:                 final boolean useScrolledContent = useScrolledContent();
188:
189:                 AbstractSWTRenderer<VElement> renderer;
190:                 try {
191:                         renderer = getEMFFormsRendererFactory().getRendererInstance(categorization, getViewModelContext());
192:                 } catch (final EMFFormsNoRendererException ex) {
193:                         getReportService().report(
194:                                 new StatusReport(
195:                                         new Status(IStatus.INFO, Activator.PLUGIN_ID, String.format(
196:                                                 "No Renderer for %s found.", categorization.eClass().getName(), ex)))); //$NON-NLS-1$
197:                         return;
198:                 }
199:                 final SWTGridDescription gridDescription = renderer.getGridDescription(GridDescriptionFactory.INSTANCE
200:                         .createEmptyGridDescription());
201:                 for (final SWTGridCell gridCell : gridDescription.getGrid()) {
202:                         final Control render = renderer.render(gridCell, composite);
203:                         renderer.finalizeRendering(composite);
204:                         GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true)
205:                                 .applyTo(render);
206:                         if (useScrolledContent) {
207:                                 final ScrolledComposite scrolledComposite = ScrolledComposite.class.cast(composite);
208:                                 scrolledComposite.setExpandHorizontal(true);
209:                                 scrolledComposite.setExpandVertical(true);
210:                                 scrolledComposite.setContent(render);
211:                                 scrolledComposite.setMinSize(render.computeSize(SWT.DEFAULT, SWT.DEFAULT));
212:                         }
213:                         item.setControl(composite);
214:                 }
215:         }
216:
217:         /**
218:          * This method gets called when a tab item was selected. Subclasses may call this method when programmatic selection
219:          * changes have been made.
220:          *
221:          * @param selection the selected item
222:          *
223:          * @since 1.9
224:          */
225:         protected final void itemSelected(CTabItem selection) {
226:                 try {
227:                         renderItem(selection);
228:                 } catch (final NoRendererFoundException ex) {
229:                         getReportService().report(
230:                                 new StatusReport(
231:                                         new Status(IStatus.INFO, Activator.PLUGIN_ID, String.format(
232:                                                 "No Renderer for %s found.", selection.getText(), ex)))); //$NON-NLS-1$
233:                 } catch (final NoPropertyDescriptorFoundExeption ex) {
234:                         getReportService().report(
235:                                 new StatusReport(
236:                                         new Status(IStatus.INFO, Activator.PLUGIN_ID, String.format(
237:                                                 "No Renderer for %s found.", selection.getText(), ex)))); //$NON-NLS-1$
238:                 }
239:         }
240:
241:         /**
242:          * Whether a {@link ScrolledComposite} should be used as the item's content or not.
243:          *
244:          * @return <code>true</code> if pane should be scrollable, <code>false</code> otherwise
245:          * @since 1.9
246:          */
247:         protected boolean useScrolledContent() {
248:                 return true;
249:         }
250:
251:         /**
252:          * Whether to render all tab items immediately or on selection.
253:          *
254:          * @return <code>true</code> if the item UI will be rendered on first selection, <code>false</code> if all items
255:          * will be rendered immediately
256:          * @since 1.9
257:          */
258:         protected boolean renderLazy() {
259:                 return false;
260:         }
261:
262:         private Optional<VTTabStyleProperty> getTabStyle() {
263:                 if (getViewTemplateProvider() == null) {
264:                         return Optional.empty();
265:                 }
266:                 final Set<VTStyleProperty> styleProperties = getViewTemplateProvider()
267:                         .getStyleProperties(getVElement(), getViewModelContext());
268:                 for (final VTStyleProperty styleProperty : styleProperties) {
269:                         if (!VTTabStyleProperty.class.isInstance(styleProperty)) {
270:                                 continue;
271:                         }
272:                         return Optional.of(VTTabStyleProperty.class.cast(styleProperty));
273:                 }
274:                 return Optional.empty();
275:         }
276:
277:         private int getTabFolderStyle() {
278:                 final Optional<VTTabStyleProperty> tabStyle = getTabStyle();
279:                 if (!tabStyle.isPresent()) {
280:                         return getDefaultFolderStyle();
281:                 }
282:                 final VTTabStyleProperty style = tabStyle.get();
283:                 switch (style.getType()) {
284:                 case BOTTOM:
285:                         return SWT.BOTTOM;
286:                 case TOP:
287:                         return SWT.TOP;
288:                 default:
289:                         return getDefaultFolderStyle();
290:                 }
291:         }
292:
293:         private int getDefaultFolderStyle() {
294:                 return SWT.BOTTOM;
295:         }
296:
297:         /**
298:          * The list of categorizations to display in the tree.
299:          *
300:          * @return the list of {@link VAbstractCategorization}
301:          */
302:         protected abstract EList<VAbstractCategorization> getCategorizations();
303:
304:         @Override
305:         protected void applyValidation() {
306:                 super.applyValidation();
307:                 for (final VAbstractCategorization categorization : getCategorizations()) {
308:                         final VDiagnostic diagnostic = categorization.getDiagnostic();
309:                         Image image = null;
310:                         if (diagnostic != null) {
311:                                 final int highestSeverity = diagnostic.getHighestSeverity();
312:                                 image = ValidationTabImageHelper.getValidationIcon(getTabStyle(), highestSeverity);
313:                         }
314:                         final CTabItem tabItem = categorizationToItemMap.get(categorization);
315:                         tabItem.setImage(image);
316:                 }
317:         }
318:
319:         /**
320:          * {@inheritDoc}
321:          *
322:          * @see org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer#dispose()
323:          */
324:         @Override
325:         protected void dispose() {
326:                 dataBindingContext.dispose();
327:                 super.dispose();
328:         }
329:
330:         /**
331:          * Reveal the control that renders the given {@code categorization}.
332:          *
333:          * @param categorization a categorization to reveal
334:          * @return whether the {@code categorization} was successfully revealed
335:          *
336:          * @since 1.22
337:          */
338:         public boolean showCategorization(VAbstractCategorization categorization) {
339:                 final CTabItem item = categorizationToItemMap.get(categorization);
340:                 final boolean result = item != null;
341:
342:                 if (result) {
343:                         item.getParent().setSelection(item);
344:                         itemSelected(item);
345:                 }
346:
347:                 return result;
348:         }
349:
350: }