/***************************************************************************** * Copyright (c) 2009 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: * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation * Arthut Daussy (Atos) arthur.daussy@atos.net - Bug 363827 - [Improvement] Diagram creation, remember the latest tab chosen * *****************************************************************************/ package org.eclipse.papyrus.infra.hyperlink.ui; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.eclipse.core.runtime.Assert; import org.eclipse.emf.common.command.CompoundCommand; import org.eclipse.emf.ecore.EModelElement; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.papyrus.infra.core.editorsfactory.IPageIconsRegistry; import org.eclipse.papyrus.infra.hyperlink.Activator; import org.eclipse.papyrus.infra.hyperlink.helper.AbstractHyperLinkHelper; import org.eclipse.papyrus.infra.hyperlink.helper.HyperLinkHelperFactory; import org.eclipse.papyrus.infra.hyperlink.messages.Messages; import org.eclipse.papyrus.infra.hyperlink.object.HyperLinkObject; import org.eclipse.papyrus.infra.hyperlink.util.HyperLinkException; import org.eclipse.papyrus.infra.hyperlink.util.HyperLinkTabsRegistrationUtil; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.IMemento; import org.eclipse.ui.WorkbenchException; import org.eclipse.ui.XMLMemento; /** * The Class HyperLinkManagerShell2. */ public class HyperLinkManagerShell extends AbstractHyperLinkManagerShell { /** * Memento's name to store Hyper Link Shell data */ private static final String HYPER_LINK_SHELL_MEMENTO = "HYPER_LINK_SHELL_MEMENTO"; //$NON-NLS-1$ /** * Memento's name to store index of the last tab used for a specific element type */ private static final String LAST_TAB_USE_MEMENTO = "LAST_TAB_USE_MEMENTO"; //$NON-NLS-1$ /** * Memento's name to store index of the last tab (for all element) */ protected static final String LAST_GLOBAL_TAB_USED = "LAST_USED_MEMENTO"; //$NON-NLS-1$ /** * The command to execute to set the new eannotation */ private CompoundCommand cmd; final protected List<HyperLinkObject> allhypHyperlinkObjects = new ArrayList<HyperLinkObject>(); /** The graphical representation of the element (a View in GMF) */ protected EModelElement view; protected EObject semanticElement; /** the root of the model. */ protected EObject amodel; /** The domain. */ protected TransactionalEditingDomain transactionalEditingDomain; protected HyperLinkHelperFactory hyperLinkHelperFactory; public void setInput(List<HyperLinkObject> hyperLinkObjectList) { this.allhypHyperlinkObjects.clear(); this.allhypHyperlinkObjects.addAll(hyperLinkObjectList); Iterator<AbstractHyperLinkTab> iter = tabList.iterator(); while(iter.hasNext()) { AbstractHyperLinkTab hyperLinkTab = iter.next(); hyperLinkTab.setInput(allhypHyperlinkObjects); } } /** * Instantiates a new hyper link manager shell2. * * @param editorFactoryRegistry * the editor factory registry * @param model * the model that contains all elements * @param domain * the domain inorder to execute command * @param umlElement * the uml element linked to the view * @param aview * the aview of the uml element */ public HyperLinkManagerShell(IPageIconsRegistry editorFactoryRegistry, TransactionalEditingDomain domain, EModelElement semanticElement, EModelElement aview, EModelElement model, HyperLinkHelperFactory hyperHelperFactory) { super(); this.hyperLinkHelperFactory = hyperHelperFactory; this.view = aview; this.semanticElement = semanticElement; this.amodel = model; this.transactionalEditingDomain = domain; createHyperLinkShell(); initializeFolder(null); // // associate tableViewer for each table // Iterator<AbstractHyperLinkHelper> iter = hyperHelperFactory.getHyperLinkHelpers().iterator(); // while(iter.hasNext()) { // AbstractHyperLinkHelper abstractHyperLinkHelper = (AbstractHyperLinkHelper)iter.next(); // initializeFolder(abstractHyperLinkHelper); // } // listener for the button cancel getCancelButton().addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { tabList.clear(); getHyperLinkShell().close(); } public void widgetDefaultSelected(SelectionEvent e) { }; }); // listener for the button OK SelectionListener okListener = new SelectionListener() { public void widgetSelected(SelectionEvent e) { executeOkButton(); } public void widgetDefaultSelected(SelectionEvent e) { } }; getOkButton().addSelectionListener(okListener); } protected void executeOkButton() {//should be final? CompoundCommand myCommand = getCommand(); //clear the current annotations myCommand.append(HyperLinkHelperFactory.getEmptyAllHyperLinkCommand(transactionalEditingDomain, view)); doAction(); //store eannotation command try { myCommand.append(hyperLinkHelperFactory.getAddHyperLinkCommand(transactionalEditingDomain, view, allhypHyperlinkObjects)); } catch (HyperLinkException e) { Activator.log.error(e); } //execute the command Assert.isTrue(myCommand.canExecute()); this.transactionalEditingDomain.getCommandStack().execute(myCommand); closeDialog(); } /** * do the action and fill the command */ protected void doAction() { // empty all hyperlinks //clear command // CompoundCommand tmp = getCommand(); // tmp.append(HyperLinkHelperFactory.getEmptyAllHyperLinkCommand(transactionalEditingDomain, view)); allhypHyperlinkObjects.clear(); allhypHyperlinkObjects.addAll(getSelectedHyperLinkObjectCrossingTabs()); //set all hyper links is default to false Iterator<HyperLinkObject> iterator = allhypHyperlinkObjects.iterator(); while(iterator.hasNext()) { HyperLinkObject hyperLink = iterator.next(); hyperLink.setIsDefault(false); } //specific behavior for the DefautHyperLinkTab DefaultHyperLinkTab defaultHyperLinkTab = getDefaultHyperLinkTab(); //look for all hyperlink default and put it as default at the top of the list int i = defaultHyperLinkTab.getDefaultHyperLinkObject().size() - 1; while(i >= 0) { HyperLinkObject hyperLinkObject = defaultHyperLinkTab.getDefaultHyperLinkObject().get(i); hyperLinkObject.setIsDefault(true); if(allhypHyperlinkObjects.contains(hyperLinkObject)) { allhypHyperlinkObjects.remove(hyperLinkObject); allhypHyperlinkObjects.add(0, hyperLinkObject); } i--; } // //store eannotation command // try { // tmp.append(hyperLinkHelperFactory.getAddHyperLinkCommand(transactionalEditingDomain, view, allhypHyperlinkObjects)); // } catch (HyperLinkException e) { // Activator.log.error(e); // } } private void closeDialog() { //save the corresponding tab saveCorrespondingTab(); tabList.clear(); getHyperLinkShell().close(); } protected CompoundCommand getCommand() { if(cmd == null) { cmd = new CompoundCommand(Messages.HyperLinkManagerShell_HyperLinksCommands); } return cmd; } /** * Initialize diagram folder. */ public void initializeFolder(final AbstractHyperLinkHelper abstractHyperLinkHelper) { //TODO remove this parameter which is not used! Iterator<AbstractHyperLinkTab> iter = HyperLinkTabsRegistrationUtil.INSTANCE.getAllHyperLinkTab().iterator(); while(iter.hasNext()) { AbstractHyperLinkTab current = iter.next(); current.init(getcTabFolder(), allhypHyperlinkObjects, amodel); tabList.add(current); } //specific behavior for the default tab : final DefaultHyperLinkTab defaultTab = getDefaultHyperLinkTab(); defaultTab.getMainComposite().addListener(SWT.Show, new Listener() { public void handleEvent(Event event) { defaultTab.setInput(HyperLinkManagerShell.this.getSelectedHyperLinkObjectCrossingTabs()); } }); } /** * Open the shell. */ public void open() { Display display = Display.getCurrent(); getHyperLinkShell().pack(); // getHyperLinkShell().setBounds(500, 500, 700, 300); getHyperLinkShell().open(); //Select the good tab selectLastTab(); // code use to wait for an action from the user while(!getHyperLinkShell().isDisposed()) { if(!display.readAndDispatch()) { display.sleep(); } } } /** * Save the last tab used for the specific element and the global last tab used * * @param rootMemento * {@link IMemento} use to save information about last tab used */ protected void saveCorrespondingTab() { IMemento rootMemento = getExistingHPMemento(); IMemento memento = getLastTabUseMemento(rootMemento); if(semanticElement != null) { //Save the corresponding tab for the element //Use InstanceTypeName in order to make a convenient ID int selectionIndex = getcTabFolder().getSelectionIndex(); memento.putInteger(semanticElement.eClass().getInstanceTypeName(), selectionIndex); //Save the global last tab used memento.putInteger(LAST_GLOBAL_TAB_USED, selectionIndex); } saveMemento((XMLMemento)rootMemento, HYPER_LINK_SHELL_MEMENTO); } /** * Select the last tab used. * If an element of the same type has already been encountered then it open the last tab used for this type * else open the last tab used for all element */ protected void selectLastTab() { IMemento rootMemento = getExistingHPMemento(); Integer lastIndexUsed = null; if(semanticElement != null) { lastIndexUsed = getLastTabUseMemento(rootMemento, semanticElement.eClass().getInstanceTypeName()); } if(lastIndexUsed == null) { lastIndexUsed = getLastTabUseMemento(rootMemento, LAST_GLOBAL_TAB_USED); if(lastIndexUsed == null) { lastIndexUsed = 0; } } try { getcTabFolder().setSelection(lastIndexUsed); } catch (IndexOutOfBoundsException e) { getcTabFolder().setSelection(0); } } /** * Save the the moment into the Preference store * * @param xmlMemento * @param key */ public static void saveMemento(XMLMemento xmlMemento, String key) { // save memento StringWriter writer = new StringWriter(); try { xmlMemento.save(writer); if(getPreferenceStore() != null) { getPreferenceStore().setValue(key, writer.toString()); } } catch (IOException e) { Activator.log.error(Messages.HyperLinkManagerShell_InputOutputException, e); } } /** * Retrieves the root memento for Hyper Link Date Shell data from the plugin preferences if any or create a new one if none * * @return the root memento for Hyper Links Data */ public static IMemento getExistingHPMemento() { String sValue = getPreferenceStore().getString(HYPER_LINK_SHELL_MEMENTO); try { if(sValue != null && !sValue.equals("")) { //$NON-NLS-1$ XMLMemento rootMemento = XMLMemento.createReadRoot(new StringReader(sValue)); return rootMemento; } else { return XMLMemento.createWriteRoot(HYPER_LINK_SHELL_MEMENTO); } } catch (WorkbenchException e) { Activator.log.error(Messages.HyperLinkManagerShell_ImpossibleToReadPreferences, e); } return null; } /** * Return the index of the last tab used for the type (represented by semantic hinted) or null if none * * @param rootMemento * Root memento used for Hyper Link Data * @param elementSemanticHint * String to represent the EClass of the EObject * @return */ public static Integer getLastTabUseMemento(IMemento rootMemento, String elementSemanticHint) { IMemento lastTabUsedMemento = getLastTabUseMemento(rootMemento); if(lastTabUsedMemento != null) { return lastTabUsedMemento.getInteger(elementSemanticHint); } return null; } /** * @param memento * @return */ protected static IMemento getLastTabUseMemento(IMemento memento) { IMemento lastTabUsedMemento = memento.getChild(LAST_TAB_USE_MEMENTO); if(lastTabUsedMemento == null) { lastTabUsedMemento = memento.createChild(LAST_TAB_USE_MEMENTO); } return lastTabUsedMemento; } private static IPreferenceStore getPreferenceStore() { return Activator.getDefault().getPreferenceStore(); } //TODO : should be a set ? public List<HyperLinkObject> getSelectedHyperLinkObjectCrossingTabs() { Set<HyperLinkObject> selectedObjects = new HashSet<HyperLinkObject>(); for(AbstractHyperLinkTab current : tabList) { if(!(current instanceof DefaultHyperLinkTab)) { List<HyperLinkObject> tmp = current.getHyperlinkObjects(); if(tmp != null) { selectedObjects.addAll(tmp); } } } return new ArrayList<HyperLinkObject>(selectedObjects); } protected DefaultHyperLinkTab getDefaultHyperLinkTab() { int nbTab = 0; DefaultHyperLinkTab defaultHyperLinkTab = null; for(AbstractHyperLinkTab current : tabList) { if(current instanceof DefaultHyperLinkTab) { defaultHyperLinkTab = (DefaultHyperLinkTab)current; nbTab++; } } //there is only one DefaultHyperLinkTab in the dialog! Assert.isTrue(nbTab == 1); Assert.isNotNull(defaultHyperLinkTab); return defaultHyperLinkTab; } }