/******************************************************************************* * Copyright 2012 Geoscience Australia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package au.gov.ga.earthsci.application.parts.legend; import java.net.URL; import java.util.Arrays; import java.util.List; import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.inject.Named; import org.eclipse.e4.core.di.annotations.Optional; import org.eclipse.e4.ui.model.application.ui.MUIElement; import org.eclipse.e4.ui.model.application.ui.basic.MBasicFactory; import org.eclipse.e4.ui.model.application.ui.basic.MPart; import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; import org.eclipse.e4.ui.model.application.ui.basic.MWindow; import org.eclipse.e4.ui.workbench.modeling.EModelService; import org.eclipse.e4.ui.workbench.modeling.EPartService; import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState; import org.eclipse.swt.SWT; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.widgets.Composite; import au.gov.ga.earthsci.layer.tree.ILayerTreeNode; import au.gov.ga.earthsci.worldwind.common.util.Util; /** * Part that displays layer legends. * * @author Michael de Hoog (michael.dehoog@ga.gov.au) */ public class LegendPart { public static final String PART_ID = "au.gov.ga.earthsci.application.legend.part"; //$NON-NLS-1$ public static final String WINDOW_ID = PART_ID + ".window"; //$NON-NLS-1$ public static final String STACK_ID = PART_ID + ".stack"; //$NON-NLS-1$ public static final String INPUT_NAME = PART_ID + ".input"; //$NON-NLS-1$ public static final String PERSISTED_URL_KEY = PART_ID + ".persistedUrl"; //$NON-NLS-1$ private Browser browser; @Inject private MPart part; @PostConstruct public void init(Composite parent) { browser = new Browser(parent, SWT.NONE); setUrl(part.getPersistedState().get(PERSISTED_URL_KEY)); } @Inject @Optional private void setPartInput(@Named(INPUT_NAME) ILayerTreeNode partInput) { ILayerTreeNode layer = partInput; URL url = layer.getLegendURL(); setUrl(url != null ? url.toString() : null); } public void setUrl(String url) { part.getPersistedState().put(PERSISTED_URL_KEY, url); if (!Util.isBlank(url)) { browser.setUrl(url); } else { browser.setText(generateMissingHtml()); } } private String generateMissingHtml() { String message = "No legend defined."; return "<html><body>" + message + "</body></html>"; //$NON-NLS-1$ //$NON-NLS-2$ } public static MPart showPart(EPartService partService, EModelService modelService, MWindow window, String reuseTag, String label) { MPart part = null; //find a part to reuse if possible if (reuseTag != null) { List<MPart> reuse = modelService.findElements(window, PART_ID, MPart.class, Arrays.asList(new String[] { reuseTag })); if (!reuse.isEmpty()) { part = reuse.get(0); } } if (part == null) { //create the part from the PartDescriptor part = partService.createPart(PART_ID); if (reuseTag != null) { part.getTags().add(reuseTag); } //first find the stack to add the part to MPartStack stack = null; //find other legend parts to put this part next to List<MPart> siblings = modelService.findElements(window, PART_ID, MPart.class, null); //use this opportunity to clean up old legend parts for (MPart sibling : siblings) { //legend parts are not reused, so remove them if they are not ToBeRendered if (!sibling.isToBeRendered() && sibling.getParent() != null) { sibling.getParent().getChildren().remove(sibling); } } //select a stack next to one of the siblings for (MPart sibling : siblings) { if (sibling.isToBeRendered()) { Object parent = sibling.getParent(); if (parent instanceof MPartStack) { stack = (MPartStack) parent; if (getFirstWindowParent(sibling) != window) { //prefer an external window if possible break; } } } } //if no stack was found with a sibling, create a new one in a new window if (stack == null) { MWindow newWindow = MBasicFactory.INSTANCE.createWindow(); newWindow.setElementId(WINDOW_ID); newWindow.setWidth(300); //TODO fix arbitrary constants newWindow.setHeight(250); window.getWindows().add(newWindow); stack = MBasicFactory.INSTANCE.createPartStack(); stack.setElementId(STACK_ID); newWindow.getChildren().add(stack); } //add it to the stack stack.getChildren().add(part); } //show and return the part part.setLabel(label); partService.showPart(part, PartState.ACTIVATE); return part; } private static MWindow getFirstWindowParent(MUIElement element) { while (element != null && !(element instanceof MWindow)) { element = element.getParent(); } return (MWindow) element; } }