/***************************************************************************** * Copyright (c) 2010 CEA LIST. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation *****************************************************************************/ package org.eclipse.papyrus.views.properties.xwt; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.Collator; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.jface.viewers.ISelection; import org.eclipse.papyrus.views.properties.Activator; import org.eclipse.papyrus.views.properties.contexts.View; import org.eclipse.papyrus.views.properties.runtime.ConfigurationManager; import org.eclipse.papyrus.views.properties.runtime.DefaultDisplayEngine; import org.eclipse.papyrus.views.properties.runtime.DisplayEngine; import org.eclipse.papyrus.views.properties.runtime.ViewConstraintEngine; import org.eclipse.ui.IPartListener; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.internal.views.properties.tabbed.view.TabbedPropertyRegistry; import org.eclipse.ui.internal.views.properties.tabbed.view.TabbedPropertyRegistryFactory; import org.eclipse.ui.views.properties.tabbed.ITabDescriptor; import org.eclipse.ui.views.properties.tabbed.ITabDescriptorProvider; import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor; /** * An implementation of ITabDescriptorProvider, which displays the Property view * from XWT files. * * @author Camille Letavernier */ public class XWTTabDescriptorProvider implements ITabDescriptorProvider { private ITabDescriptor[] cachedResult; private ISelection previousSelection; private IWorkbenchPart previousPart; private final Map<IWorkbenchPart, DisplayEngine> displays = new HashMap<IWorkbenchPart, DisplayEngine>(); private DisplayEngine getDisplay(final IWorkbenchPart part) { if(!displays.containsKey(part)) { displays.put(part, new DefaultDisplayEngine()); part.getSite().getPage().addPartListener(new IPartListener() { public void partClosed(IWorkbenchPart part) { part.getSite().getPage().removePartListener(this); DisplayEngine display = displays.get(part); if(display != null) { display.dispose(); displays.remove(part); } } public void partActivated(IWorkbenchPart part) { //Nothing } public void partBroughtToTop(IWorkbenchPart part) { //Nothing } public void partDeactivated(IWorkbenchPart part) { //Nothing } public void partOpened(IWorkbenchPart part) { //Nothing } }); } return displays.get(part); } public ITabDescriptor[] getTabDescriptors(final IWorkbenchPart part, final ISelection selection) { if(selection != this.previousSelection || part != previousPart) { this.previousSelection = selection; this.previousPart = part; ViewConstraintEngine constraintEngine = ConfigurationManager.instance.constraintEngine; List<ITabDescriptor> descriptors = new LinkedList<ITabDescriptor>(); Set<View> views = constraintEngine.getViews(selection); if(!views.isEmpty()) { descriptors.addAll(getDisplay(part).getTabDescriptors(views)); } // get all tab descriptors for the registered extension points TabbedPropertyRegistry registry = TabbedPropertyRegistryFactory.getInstance().createRegistry((ITabbedPropertySheetPageContributor)part); // invoke dynamically on the tab registry, as method is private // problem of implementation of tabbed properties tabbed registry. Either contribution using extension points, either a tabprovider // both contribution can not exist together, the only solution is to make a workaround. try { Method method = TabbedPropertyRegistry.class.getDeclaredMethod("getAllTabDescriptors"); //$NON-NLS-1$ method.setAccessible(true); ITabDescriptor[] registeredTabDesriptors; registeredTabDesriptors = (ITabDescriptor[])method.invoke(registry); if(registeredTabDesriptors != null) { for(ITabDescriptor descriptor : registeredTabDesriptors) { if(descriptor.getSectionDescriptors().size() > 0) { descriptors.add(descriptor); } } } } catch (IllegalArgumentException e) { Activator.log.error(e); } catch (IllegalAccessException e) { Activator.log.error(e); } catch (InvocationTargetException e) { Activator.log.error(e); } catch (SecurityException e) { Activator.log.error(e); } catch (NoSuchMethodException e) { Activator.log.error(e); } orderTabDescriptors(descriptors); cachedResult = descriptors.toArray(new ITabDescriptor[descriptors.size()]); } return cachedResult; } /** * Order the tab descriptors in the given list, given the afterTab comparator * * @param descriptors * tab descriptor list to order */ protected void orderTabDescriptors(final List<ITabDescriptor> descriptors) { Collections.sort(descriptors, new Comparator<ITabDescriptor>() { /** * compares two tab descriptors each other * * @param tabDescriptor1 * first tab to compare * @param tabDescriptor2 * second tab to compare * @return an integer lesser than -1 if the first tab should be placed before the second tab */ public int compare(ITabDescriptor tabDescriptor1, ITabDescriptor tabDescriptor2) { int priority1 = getPriority(tabDescriptor1); int priority2 = getPriority(tabDescriptor2); if(priority1 < priority2) { return -1; } if(priority1 > priority2) { return 1; } //p1 == p2 priority1 = getXWTTabPriority(tabDescriptor1); priority2 = getXWTTabPriority(tabDescriptor2); if(priority1 < priority2) { return -1; } if(priority1 > priority2) { return 1; } //p1 == p2 String label1 = tabDescriptor1.getLabel(); String label2 = tabDescriptor2.getLabel(); return Collator.getInstance().compare(label1, label2); } /** * Returns the tab descriptor before tab * * @param tab * the tab to test * @return the tab descriptor before tab */ private ITabDescriptor getPreviousTab(ITabDescriptor tab) { String afterId = tab.getAfterTab(); if(!(ITabDescriptor.TOP.equals(afterId))) { for(ITabDescriptor descriptor : descriptors) { String id = descriptor.getId(); if(id != null && id.equals(afterId)) { return descriptor; } } } // not found. Return null return null; } private int getPriority(ITabDescriptor tab) { ITabDescriptor previousTab = getPreviousTab(tab); if(previousTab != null) { return getPriority(previousTab) + 1; } return getXWTTabPriority(tab); } private int getXWTTabPriority(ITabDescriptor tab) { if(tab instanceof XWTTabDescriptor) { XWTTabDescriptor xwtTab = (XWTTabDescriptor)tab; return xwtTab.getPriority(); } else { return 100; //This tab is not handled by our framework } } }); } }