blob: b58e9c713d5777fe56beec94b75bf2aaf5ecbd19 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012 Rushan R. Gilmullin and others.
* 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:
* Rushan R. Gilmullin - initial API and implementation
*******************************************************************************/
package org.eclipse.osbp.vaaclipse.presentation.renderers;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.MContext;
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack;
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
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.IPresentationEngine;
import org.eclipse.e4.ui.workbench.UIEvents;
import org.eclipse.e4.ui.workbench.UIEvents.EventTags;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.osbp.runtime.designer.api.IDesignerService;
import org.eclipse.osbp.runtime.designer.api.IDesignerService.DesignEvent;
import org.eclipse.osbp.runtime.designer.api.IDesignerService.EventType;
import org.eclipse.osbp.runtime.designer.api.IWidgetDesignConfigurator;
import org.eclipse.osbp.vaaclipse.Activator;
import org.eclipse.osbp.vaaclipse.api.ResourceInfoProvider;
import org.eclipse.osbp.vaaclipse.presentation.engine.GenericPresentationEngine;
import org.eclipse.osbp.vaaclipse.presentation.utils.Commons;
import org.eclipse.osbp.vaaclipse.presentation.utils.HierarchyUtils;
import org.eclipse.osbp.vaaclipse.publicapi.authentication.AuthenticationConstants;
import org.eclipse.osbp.vaaclipse.publicapi.change.ChangeCommand;
import org.eclipse.osbp.vaaclipse.publicapi.change.SimpleCommand;
import org.eclipse.osbp.vaaclipse.publicapi.model.Tags;
import org.eclipse.osbp.vaaclipse.publicapi.perspective.IPerspectiveHandler;
import org.eclipse.osbp.vaaclipse.publicapi.resources.BundleResource;
import org.eclipse.osbp.vaaclipse.publicapi.resources.ResourceHelper;
import org.eclipse.osbp.vaaclipse.widgets.StackWidget;
import org.eclipse.osbp.vaaclipse.widgets.TwoStateToolbarButton;
import org.eclipse.osbp.vaadin.optiondialog.OptionDialog;
import org.eclipse.osbp.vaadin.optiondialog.OptionDialog.OptionsAlign;
import org.osgi.framework.ServiceReference;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
import com.vaadin.addon.contextmenu.ContextMenu;
import com.vaadin.addon.contextmenu.MenuItem;
import com.vaadin.data.Item;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptAll;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.server.Resource;
import com.vaadin.server.Sizeable.Unit;
import com.vaadin.server.StreamVariable;
import com.vaadin.server.ThemeResource;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.DragAndDropWrapper;
import com.vaadin.ui.DragAndDropWrapper.WrapperTransferable;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Html5File;
import com.vaadin.ui.Label;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Notification.Type;
import com.vaadin.ui.Panel;
import com.vaadin.ui.Table;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
/**
* @author rushan
*
*/
public class PerspectiveStackRenderer extends VaadinRenderer implements IDesignerService.IDesignListener {
/**
* Removes the perspective from stack if it is closed.
*/
private static final String TAG__REMOVE_ON_CLOSE = "remove_on_close";
/**
* The perspective is not visible in the open perspective dialog.
*/
private static final String TAG__NOT_IN_OPEN_PERSPECTIVE_DIALOG = "not_in_open_perspective_dialog";
private MPerspectiveStack perspectiveStackForSwitcher;
private HorizontalLayout perspectiveSwitcherPanel;
private Map<MPerspective, TwoStateToolbarButton> perspective_button = new HashMap<MPerspective, TwoStateToolbarButton>();
private Map<Component, PerspectiveContextMenu> button2ContextMenu = new HashMap<Component, PerspectiveContextMenu>();
private MPerspective activePerspective;
@Inject
private UI vaadinUI;
@Inject
@Optional
private IPerspectiveHandler perspectiveRegistry;
@Inject
@Optional
private EditingDomain editingDomain;
@Inject
@Optional
private IDesignerService designerService;
@SuppressWarnings("serial")
private class PerspectiveContextMenu extends ContextMenu {
private static final String SHOW_TEXT = "Show Text";
private MenuItem showTextItem;
private MenuItem closeItem;
private final MPerspective perspective;
// Resource checkIcon = new ThemeResource("../vaaclipse_default_theme/img/check.png");
public PerspectiveContextMenu(TwoStateToolbarButton button, boolean iconsOnly, MPerspective perspective) {
super(button, true);
this.perspective = perspective;
createItems(iconsOnly);
// setIconsOnly(iconsOnly);
}
private void createItems(boolean iconsOnly) {
closeItem = addItem("Close", this::menuSelected);
showTextItem = addItem(SHOW_TEXT, this::menuSelected);
}
public MenuItem getShowTextItem() {
return showTextItem;
}
public MenuItem getCloseItem() {
return closeItem;
}
// void setIconsOnly(boolean iconsOnly) {
// showTextItem.setIcon(!iconsOnly ? checkIcon : null);
// }
void menuSelected(MenuItem clickedItem) {
if (clickedItem == getCloseItem()) {
if (perspective.getTags().contains(TAG__REMOVE_ON_CLOSE)) {
// sends new messages
modelService.removePerspectiveModel(perspective, perspective.getContext().get(MWindow.class));
switchToPreviousPerspective(perspective);
} else if (perspective == activePerspective) {
switchToPreviousPerspective(perspective);
}
perspective.setToBeRendered(false);
} else if (clickedItem == getShowTextItem()) {
if (perspectiveStackForSwitcher.getTags().contains(Tags.ICONS_ONLY))
perspectiveStackForSwitcher.getTags().remove(Tags.ICONS_ONLY);
else
perspectiveStackForSwitcher.getTags().add(Tags.ICONS_ONLY);
}
}
}
public HorizontalLayout getPerspectiveSwitcher() {
return perspectiveSwitcherPanel;
}
public MPerspectiveStack getPerspectiveStackForSwitcher() {
return perspectiveStackForSwitcher;
}
@Inject
IEventBroker eventBroker;
@Inject
MApplication application;
@Inject
EPartService partService;
@Inject
GenericPresentationEngine engine;
static final String PERSPECTIVE_LABEL = "PerspectiveLabel";
static final String PERSPECTIVE_ICON = "PerspectiveIcon";
private final EventHandler tagListener = new EventHandler() {
@SuppressWarnings("unused")
@Override
public void handleEvent(Event event) {
Object changedObj = event.getProperty(EventTags.ELEMENT);
if (!(changedObj instanceof MPerspectiveStack)) {
return;
}
final MPerspectiveStack changedElement = (MPerspectiveStack) changedObj;
String eventType = (String) event.getProperty(UIEvents.EventTags.TYPE);
String tag = (String) event.getProperty(UIEvents.EventTags.NEW_VALUE);
String oldVal = (String) event.getProperty(UIEvents.EventTags.OLD_VALUE);
if (UIEvents.EventTypes.ADD.equals(eventType) && Tags.ICONS_ONLY.equals(tag)) {
for (Map.Entry<MPerspective, TwoStateToolbarButton> entry : perspective_button.entrySet()) {
MPerspective perspective = entry.getKey();
TwoStateToolbarButton button = entry.getValue();
button.setLabelAndIcon(null, Commons.trim(perspective.getIconURI()));
PerspectiveContextMenu menu = button2ContextMenu.get(button);
// menu.setIconsOnly(true);
}
} else if (UIEvents.EventTypes.REMOVE.equals(eventType) && Tags.ICONS_ONLY.equals(oldVal)) {
for (Map.Entry<MPerspective, TwoStateToolbarButton> entry : perspective_button.entrySet()) {
MPerspective perspective = entry.getKey();
TwoStateToolbarButton button = entry.getValue();
button.setLabelAndIcon(Commons.trim(perspective.getLabel()),
Commons.trim(perspective.getIconURI()));
PerspectiveContextMenu menu = button2ContextMenu.get(button);
// menu.setIconsOnly(false);
}
}
}
};
private EventHandler selectPerspectiveHandler = new EventHandler() {
@SuppressWarnings("unchecked")
public void handleEvent(Event event) {
Object element = event.getProperty(UIEvents.EventTags.ELEMENT);
if (!(element instanceof MPerspectiveStack))
return;
MPerspectiveStack stack = (MPerspectiveStack) element;
if (stack.getRenderer() != PerspectiveStackRenderer.this)
return;
@SuppressWarnings("unused")
PerspectiveStackRenderer psr = (PerspectiveStackRenderer) stack.getRenderer();
// Gather up the elements that are being 'hidden' by this change
MUIElement oldSel = (MUIElement) event.getProperty(UIEvents.EventTags.OLD_VALUE);
if (oldSel != null) {
@SuppressWarnings("unused")
List<MUIElement> goingHidden = new ArrayList<MUIElement>();
}
if (oldSel != null) {
perspective_button.get(oldSel).setCheckedState(false);
perspective_button.get(oldSel).setSwitchStateByUserClickEnabled(true);
hideElementRecursive(oldSel);
}
((VerticalLayout) stack.getWidget()).removeAllComponents();
if (stack.getSelectedElement() != null) {
showElementRecursive(stack.getSelectedElement());
((VerticalLayout) stack.getWidget()).addComponent((Component) stack.getSelectedElement().getWidget());
perspective_button.get(stack.getSelectedElement()).setCheckedState(true);
perspective_button.get(stack.getSelectedElement()).setSwitchStateByUserClickEnabled(false);
// mark the perspective as active
switchPerspective(stack.getSelectedElement());
} else if (oldSel instanceof MElementContainer<?>) {
disconnectReferencedElementsFromPerspectiveWidgets((MElementContainer<? extends MUIElement>) oldSel);
}
}
};
private EventHandler localizeLabel = new EventHandler() {
@Override
public void handleEvent(Event event) {
Object element = event.getProperty(UIEvents.EventTags.ELEMENT);
if (!(element instanceof MPerspective))
return;
MPerspective perspective = (MPerspective) element;
String newValue = (String) event.getProperty(UIEvents.EventTags.NEW_VALUE);
boolean iconsOnly = perspectiveStackForSwitcher.getTags().contains(Tags.ICONS_ONLY);
String label = iconsOnly ? null : Commons.trim(newValue);
String iconURI = Commons.trim(perspective.getIconURI());
TwoStateToolbarButton button = perspective_button.get(perspective);
if (button != null) {
button.setLabelAndIcon(label, iconURI);
}
}
};
private EventHandler iconURI = new EventHandler() {
@Override
public void handleEvent(Event event) {
Object element = event.getProperty(UIEvents.EventTags.ELEMENT);
if (!(element instanceof MPerspective))
return;
MPerspective perspective = (MPerspective) element;
String newValue = (String) event.getProperty(UIEvents.EventTags.NEW_VALUE);
TwoStateToolbarButton button = perspective_button.get(perspective);
if (button != null) {
button.setIconURI(newValue);
}
}
};
private EventHandler localizeTooltip = new EventHandler() {
@Override
public void handleEvent(Event event) {
Object element = event.getProperty(UIEvents.EventTags.ELEMENT);
if (!(element instanceof MPerspective))
return;
MPerspective perspective = (MPerspective) element;
if (perspective.getTooltip() != null) {
String newValue = (String) event.getProperty(UIEvents.EventTags.NEW_VALUE);
TwoStateToolbarButton button = perspective_button.get(perspective);
if (button != null) {
button.setDescription(newValue);
}
}
}
};
private void disconnectReferencedElementsFromPerspectiveWidgets(MElementContainer<? extends MUIElement> container) {
for (MUIElement e : container.getChildren()) {
if (e instanceof MPlaceholder) {
MPlaceholder ph = (MPlaceholder) e;
if (ph.isToBeRendered()) {
ComponentContainer phComponent = (ComponentContainer) ph.getWidget();
Component refComponent = (Component) ph.getRef().getWidget();
phComponent.removeComponent(refComponent);
}
}
}
}
@PostConstruct
public void postConstruct() {
eventBroker.subscribe(UIEvents.ElementContainer.TOPIC_SELECTEDELEMENT, selectPerspectiveHandler);
eventBroker.subscribe(UIEvents.ApplicationElement.TOPIC_TAGS, tagListener);
eventBroker.subscribe(UIEvents.UILabel.TOPIC_LOCALIZED_LABEL, localizeLabel);
eventBroker.subscribe(UIEvents.UILabel.TOPIC_LOCALIZED_TOOLTIP, localizeTooltip);
eventBroker.subscribe(UIEvents.UILabel.TOPIC_LABEL, localizeLabel);
eventBroker.subscribe(UIEvents.UILabel.TOPIC_TOOLTIP, localizeTooltip);
eventBroker.subscribe(UIEvents.UILabel.TOPIC_ICONURI, iconURI);
eventBroker.subscribe(UIEvents.ElementContainer.TOPIC_CHILDREN, childrenMoveUpdater);
}
@PreDestroy
public void preDestroy() {
if (designerService != null) {
designerService.removeListener(this);
}
eventBroker.unsubscribe(selectPerspectiveHandler);
eventBroker.unsubscribe(tagListener);
eventBroker.unsubscribe(localizeLabel);
eventBroker.unsubscribe(localizeTooltip);
eventBroker.unsubscribe(iconURI);
eventBroker.unsubscribe(childrenMoveUpdater);
}
private EventHandler childrenMoveUpdater = new EventHandler() {
@SuppressWarnings("unchecked")
public void handleEvent(Event event) {
// Ensure that this event is for a MMenuItem
if (!(event.getProperty(UIEvents.EventTags.ELEMENT) instanceof MPerspectiveStack))
return;
MElementContainer<MUIElement> stack = (MElementContainer<MUIElement>) event
.getProperty(UIEvents.EventTags.ELEMENT);
String type = (String) event.getProperty(UIEvents.EventTags.TYPE);
// on move, we unrender an render the UI again
//
if (UIEvents.EventTypes.MOVE.equals(type)) {
MUIElement newValue = (MUIElement) event.getProperty(UIEvents.EventTags.NEW_VALUE);
removeChildGui(newValue, stack);
addChildGui(newValue, stack);
}
}
};
private DragAndDropWrapper html5Drop;
@Override
public boolean isLazy() {
return true;
}
@Override
public void createWidget(MUIElement element, MElementContainer<MUIElement> parent) {
if (perspectiveSwitcherPanel == null)
initializePerspectiveSwticherPanel((MPerspectiveStack) element);
VerticalLayout perspectiveStackContent = new VerticalLayout();
perspectiveStackContent.setSizeFull();
element.setWidget(perspectiveStackContent);
if (designerService != null) {
designerService.addListener(this);
if (designerService.isDesignMode()) {
updateDesigner(true);
}
}
}
private void initializePerspectiveSwticherPanel(MPerspectiveStack perspectiveStack) {
if (perspectiveSwitcherPanel != null)
return;
// initialize perspective switcher panel
perspectiveStackForSwitcher = perspectiveStack;
perspectiveSwitcherPanel = new HorizontalLayout();
perspectiveSwitcherPanel.setStyleName("perspectivepanel");
perspectiveSwitcherPanel.setSizeUndefined();
// add separator between openPerspectiveButton and perspective's buttons
Label separator = new Label();
separator.setSizeUndefined();
separator.addStyleName("horizontalseparator");
separator.setHeight("100%");
perspectiveSwitcherPanel.addComponent(separator);
// add buttons to perspective switch panel
for (final MPerspective perspective : perspectiveStackForSwitcher.getChildren()) {
if (perspective.isToBeRendered()) {
Component button = createPerspectiveButton(perspective);
if (button != null) {
perspectiveSwitcherPanel.addComponent(button);
}
}
}
}
@SuppressWarnings("serial")
private Component createPerspectiveButton(final MPerspective perspective) {
if (!perspective.isVisible())
return null;
boolean iconsOnly = perspectiveStackForSwitcher.getTags().contains(Tags.ICONS_ONLY);
String label = iconsOnly ? null : Commons.trim(perspective.getLocalizedLabel());
String iconURI = Commons.trim(perspective.getIconURI());
final TwoStateToolbarButton button = new TwoStateToolbarButton(label, iconURI);
if (perspective.getTooltip() != null) {
button.setDescription(perspective.getLocalizedTooltip());
}
button.addListener(new ClickListener() {
public void buttonClick(ClickEvent event) {
if (editingDomain != null) {
SimpleCommand command = new SimpleCommand("Switch perspective: "
+ activePerspective.getLocalizedLabel() + " <--> " + perspective.getLocalizedLabel()) {
final MPerspective oldPerspective = activePerspective;
final MPerspective newPerspective = perspective;
@Override
protected void doExecute() {
switchPerspective(newPerspective);
}
@Override
protected void doUndo() {
switchPerspective(oldPerspective);
}
};
editingDomain.getCommandStack().execute(command);
} else {
switchPerspective(perspective);
}
}
});
// Create context menu
final PerspectiveContextMenu menu = new PerspectiveContextMenu(button, iconsOnly, perspective);
menu.setAsContextMenuOf(button);
button2ContextMenu.put(button, menu);
perspective_button.put(perspective, button);
return button;
}
@Override
public void notify(DesignEvent event) {
updateDesigner(event.getType() == EventType.ENABLED);
}
private void updateDesigner(boolean enabled) {
IWidgetDesignConfigurator designConfigurator = context.get(IWidgetDesignConfigurator.class);
if (designConfigurator != null) {
for (Map.Entry<MPerspective, TwoStateToolbarButton> entry : perspective_button.entrySet()) {
designConfigurator.configure(entry.getValue(), (EObject) entry.getKey(), enabled);
}
}
}
@Override
public void processContents(MElementContainer<MUIElement> element) {
if (element.getChildren().isEmpty())
return;
MPerspectiveStack perspectiveStack = (MPerspectiveStack) (MElementContainer<?>) element;
MPerspective selectedPerspective = perspectiveStack.getSelectedElement();
if (selectedPerspective == null) {
// try to find by registry
if (perspectiveRegistry != null) {
String userId = (String) context.get(AuthenticationConstants.USER_ID);
String perspectiveId = perspectiveRegistry.getDefaultPerspective(userId);
if (perspectiveId != null) {
selectedPerspective = perspectiveRegistry.findPerspectiveWithId(perspectiveId);
}
if (selectedPerspective == null) {
selectedPerspective = (MPerspective) findFirstRenderableAndVisibleElement(perspectiveStack);
}
} else {
// use the first elemet
selectedPerspective = (MPerspective) findFirstRenderableAndVisibleElement(perspectiveStack);
}
}
if (selectedPerspective != null) {
if (!selectedPerspective.isToBeRendered() || !selectedPerspective.isVisible()) {
selectedPerspective = (MPerspective) findFirstRenderableAndVisibleElement(perspectiveStack);
if (selectedPerspective != null) {
switchPerspective(selectedPerspective);
} else {
perspectiveStack.setSelectedElement(null);
}
} else {
// reset selected element (set selected element handler will
// work)
perspectiveStack.setSelectedElement(null);
switchPerspective(selectedPerspective);
}
}
refreshPerspectiveStackVisibility(perspectiveStack);
}
private void switchPerspective(MPerspective perspective) {
if (perspective.isToBeRendered() && perspective.getWidget() == null)
engine.createGui(perspective);
partService.switchPerspective(perspective);
this.activePerspective = perspective;
if (perspective.getElementId() != null) {
String perspectiveId = perspective.getElementId().trim();
application.getContext().set("activePerspective", perspectiveId);
}
}
private void refreshPerspectiveStackVisibility(MPerspectiveStack stack) {
perspectiveSwitcherPanel.setVisible(stack.getChildren().size() > 0);
}
@Override
public void addChildGui(MUIElement child, MElementContainer<MUIElement> element) {
MPerspectiveStack stack = (MPerspectiveStack) (MElementContainer<?>) element;
MPerspective p = (MPerspective) child;
Component button = createPerspectiveButton(p);
// shift on 2 - the first child - open perspective button, the second
// child - is separator
int index = indexOf(child, element) + 2;
perspectiveSwitcherPanel.addComponent(button,
Math.min(index, perspectiveSwitcherPanel.getComponentCount() - 1));
refreshPerspectiveStackVisibility(stack);
}
@Override
public void removeChildGui(MUIElement child, MElementContainer<MUIElement> element) {
MPerspectiveStack stack = (MPerspectiveStack) (MElementContainer<?>) element;
MPerspective p = (MPerspective) child;
Button button = perspective_button.remove(p);
if (button != null) {
perspectiveSwitcherPanel.removeComponent(button);
button2ContextMenu.remove(button);
}
refreshPerspectiveStackVisibility(stack);
}
private void openOpenPerspectiveWindow() {
OptionDialog dlg = new OptionDialog();
dlg.setCaption("Open perspective");
ServiceReference<ResourceInfoProvider> resourceInfoProviderRef = Activator.getInstance().getContext()
.getServiceReference(ResourceInfoProvider.class);
if (resourceInfoProviderRef != null) {
ResourceInfoProvider resourceInfoProvider = Activator.getInstance().getContext()
.getService(resourceInfoProviderRef);
if (resourceInfoProvider.getApplicationHeaderIcon() != null) {
dlg.setIcon(BundleResource.valueOf(resourceInfoProvider.getApplicationHeaderIcon()));
}
}
dlg.setModal(true);
dlg.setWidth(360, Unit.PIXELS);
dlg.setHeight(440, Unit.PIXELS);
dlg.addOption(0, "OK");
dlg.addOption(1, "CANCEL");
dlg.setOptionButtonsWidth(80, Unit.PIXELS);
dlg.setOptionButtonsAlignment(OptionsAlign.RIGHT);
vaadinUI.addWindow(dlg);
dlg.setComponentProvider(new OptionDialog.ComponentProvider() {
Panel panel;
Table list;
IndexedContainer container;
@SuppressWarnings("unchecked")
@Override
public Component getComponent(OptionDialog optionDialog) {
if (panel == null) {
container = new IndexedContainer();
container.addContainerProperty(PERSPECTIVE_ICON, Resource.class, null);
container.addContainerProperty(PERSPECTIVE_LABEL, String.class, null);
for (MPerspective p : perspectiveStackForSwitcher.getChildren()) {
if (!p.isVisible()) {
continue;
}
if (p.getTags().contains(TAG__NOT_IN_OPEN_PERSPECTIVE_DIALOG)) {
continue;
}
Item item = container.addItem(p.getElementId());
Resource icon = ResourceHelper.createResource(p.getIconURI());
if (icon != null) {
item.getItemProperty(PERSPECTIVE_ICON).setValue(icon);
}
item.getItemProperty(PERSPECTIVE_LABEL).setValue(p.getLabel());
}
panel = new Panel();
list = new Table();
list.addStyleName("open_perspective_window");
panel.setContent(list);
list.setSizeFull();
list.setSelectable(true);
list.setMultiSelect(false);
list.setContainerDataSource(container);
list.setColumnHeaderMode(Table.COLUMN_HEADER_MODE_HIDDEN);
list.setVisibleColumns(new Object[] { PERSPECTIVE_LABEL });
list.setRowHeaderMode(Table.ROW_HEADER_MODE_ICON_ONLY);
list.setItemIconPropertyId(PERSPECTIVE_ICON);
list.setColumnExpandRatio(PERSPECTIVE_LABEL, 1);
}
return panel;
}
@Override
public void optionSelected(OptionDialog dlg, int optionId) {
if (optionId == 0) {
// selected perspective's elementId
String perspectiveId = (String) list.getValue();
if (perspectiveId != null) {
MPerspective perspective = (MPerspective) modelService.find(perspectiveId,
perspectiveStackForSwitcher);
if (!perspective.isToBeRendered())
perspective.setToBeRendered(true);
switchPerspective(perspective);
}
}
dlg.close();
}
@Override
public void setMessage(String message) {
}
});
}
// -------------------------------------------------------
// -------------------------------------------------------
private void hideElementRecursive(MUIElement element) {
if (element == null || element.getWidget() == null)
return;
if (element instanceof MPlaceholder) {
MPlaceholder ph = (MPlaceholder) element;
element = ph.getRef();
}
// Hide any floating windows
if (element instanceof MWindow && element.getWidget() != null) {
element.setVisible(false);
}
if (element instanceof MElementContainer<?>) {
MElementContainer<?> container = (MElementContainer<?>) element;
for (MUIElement childElement : container.getChildren()) {
hideElementRecursive(childElement);
}
// OK, now process detached windows
if (element instanceof MWindow) {
for (MWindow w : ((MWindow) element).getWindows()) {
hideElementRecursive(w);
}
} else if (element instanceof MPerspective) {
for (MWindow w : ((MPerspective) element).getWindows()) {
hideElementRecursive(w);
}
}
}
}
private void showElementRecursive(MUIElement element) {
if (!element.isToBeRendered())
return;
if (element instanceof MPlaceholder && element.getWidget() != null) {
MPlaceholder ph = (MPlaceholder) element;
MUIElement ref = ph.getRef();
ref.setCurSharedRef(ph);
ComponentContainer phComponent = (ComponentContainer) ph.getWidget();
Component refComponent = (Component) ph.getRef().getWidget();
phComponent.addComponent(refComponent);
element = ref;
// top right folder
MPartStack topLeftStack = HierarchyUtils.findTopLeftFolder(ph.getRef());
if (topLeftStack != null) {
if (ph.getTags().contains(IPresentationEngine.MAXIMIZED))
((StackWidget) topLeftStack.getWidget()).setState(1);
else if (ph.getTags().contains(IPresentationEngine.MINIMIZED))
((StackWidget) topLeftStack.getWidget()).setState(-1);
else {
if (((StackWidget) topLeftStack.getWidget()) != null) {
((StackWidget) topLeftStack.getWidget()).setState(0);
}
}
}
}
if (element instanceof MContext) {
IEclipseContext context = ((MContext) element).getContext();
if (context != null) {
IEclipseContext newParentContext = modelService.getContainingContext(element);
if (context.getParent() != newParentContext) {
context.setParent(newParentContext);
}
}
}
// Show any floating windows
if (element instanceof MWindow && element.getWidget() != null) {
int visCount = 0;
for (MUIElement kid : ((MWindow) element).getChildren()) {
if (kid.isToBeRendered() && kid.isVisible())
visCount++;
}
if (visCount > 0)
element.setVisible(true);
}
if (element instanceof MElementContainer<?>) {
MElementContainer<?> container = (MElementContainer<?>) element;
List<MUIElement> kids = new ArrayList<MUIElement>(container.getChildren());
for (MUIElement childElement : kids) {
showElementRecursive(childElement);
}
// OK, now process detached windows
if (element instanceof MWindow) {
for (MWindow w : ((MWindow) element).getWindows()) {
showElementRecursive(w);
}
} else if (element instanceof MPerspective) {
for (MWindow w : ((MPerspective) element).getWindows()) {
showElementRecursive(w);
}
}
}
}
private void switchToPreviousPerspective(final MPerspective perspective) {
MPerspective prevRenderableAndVisiblePerspective = null, nextRenderableAndVisiblePerspective = null;
boolean startSearch = false;
for (MPerspective p : perspectiveStackForSwitcher.getChildren()) {
if (startSearch && p.isToBeRendered() && p.isVisible()) {
nextRenderableAndVisiblePerspective = p;
break;
}
if (p == perspective)
startSearch = true;
if (!startSearch && p.isToBeRendered() && p.isVisible()) {
prevRenderableAndVisiblePerspective = p;
}
}
MPerspective newSelectedPerspective = nextRenderableAndVisiblePerspective != null
? nextRenderableAndVisiblePerspective : prevRenderableAndVisiblePerspective;
if (newSelectedPerspective != null) {
switchPerspective(newSelectedPerspective);
}
}
private class PerspectiveDropHandler implements DropHandler {
private static final long FILE_SIZE_LIMIT = 2 * 1024 * 1024; // 2MB
public PerspectiveDropHandler() {
}
@Override
public void drop(final DragAndDropEvent dropEvent) {
// expecting this to be an html5 drag
final WrapperTransferable tr = (WrapperTransferable) dropEvent.getTransferable();
final Html5File[] files = tr.getFiles();
if (files != null) {
for (final Html5File html5File : files) {
final String fileName = html5File.getFileName();
// if (!fileName.endsWith(".perspective")) {
// continue;
// }
if (html5File.getFileSize() > FILE_SIZE_LIMIT) {
Notification.show("File rejected. Max 2Mb files are accepted by Sampler",
Notification.Type.WARNING_MESSAGE);
} else {
final ByteArrayOutputStream bas = new ByteArrayOutputStream();
final StreamVariable streamVariable = new StreamVariable() {
@Override
public OutputStream getOutputStream() {
return bas;
}
@Override
public boolean listenProgress() {
return false;
}
@Override
public void onProgress(final StreamingProgressEvent event) {
}
@Override
public void streamingStarted(final StreamingStartEvent event) {
}
@Override
public void streamingFinished(final StreamingEndEvent event) {
addPerspective(fileName, html5File.getType(),
new ByteArrayInputStream(bas.toByteArray()));
}
@Override
public void streamingFailed(final StreamingErrorEvent event) {
}
@Override
public boolean isInterrupted() {
return false;
}
};
html5File.setStreamVariable(streamVariable);
}
}
}
}
@SuppressWarnings("restriction")
private void addPerspective(final String name, final String type, final InputStream stream) {
XMIResource resource = new XMIResourceImpl(URI.createURI("perspective" + name));
try {
resource.load(stream, null);
final MPerspective perspective = (MPerspective) resource.getContents().get(0);
ChangeCommand command = new ChangeCommand("Drop perspective: " + perspective.getLocalizedLabel(),
((EObject) getPerspectiveStackForSwitcher()).eResource()) {
@Override
protected void doExecute() {
// add the perspective
//
getPerspectiveStackForSwitcher().getChildren().add(perspective);
getPerspectiveStackForSwitcher().setSelectedElement(perspective);
}
};
editingDomain.getCommandStack().execute(command);
resource.unload();
} catch (IOException e) {
Notification.show(e.toString(), Type.ERROR_MESSAGE);
}
}
@Override
public AcceptCriterion getAcceptCriterion() {
return AcceptAll.get();
}
}
}