/* * Copyright (c) 2008 Stiftung Deutsches Elektronen-Synchrotron, * Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY. * * THIS SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "../AS IS" BASIS. * WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR PARTICULAR PURPOSE AND * NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * THE USE OR OTHER DEALINGS IN THE SOFTWARE. SHOULD THE SOFTWARE PROVE DEFECTIVE * IN ANY RESPECT, THE USER ASSUMES THE COST OF ANY NECESSARY SERVICING, REPAIR OR * CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. * NO USE OF ANY SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. * DESY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, * OR MODIFICATIONS. * THE FULL LICENSE SPECIFYING FOR THE SOFTWARE THE REDISTRIBUTION, MODIFICATION, * USAGE AND OTHER RIGHTS AND OBLIGATIONS IS INCLUDED WITH THE DISTRIBUTION OF THIS * PROJECT IN THE FILE LICENSE.HTML. IF THE LICENSE IS NOT INCLUDED YOU MAY FIND A COPY * AT HTTP://WWW.DESY.DE/LEGAL/LICENSE.HTM */ package org.csstudio.sds.ui.runmode; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.csstudio.sds.internal.runmode.RunModeBoxInput; import org.csstudio.sds.internal.runmode.RunModeType; import org.csstudio.sds.model.DisplayModel; import org.csstudio.sds.ui.internal.runmode.AbstractRunModeBox; import org.csstudio.sds.ui.internal.runmode.DisplayViewPart; import org.csstudio.sds.ui.internal.runmode.IRunModeDisposeListener; import org.csstudio.sds.ui.internal.runmode.ShellRunModeBox; import org.csstudio.sds.ui.internal.runmode.ViewRunModeBox; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.graphics.Point; import org.eclipse.ui.IMemento; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * Service, which manages the run mode versions of graphical viewers. * * @author Sven Wende */ public final class RunModeService { private static final Logger LOG = LoggerFactory.getLogger(RunModeService.class); private static final String SEPARATOR = "���"; /** * The singleton instance. */ private static RunModeService _instance; /** * A Map of the already displayed IFiles and their RunModeBoxes. */ private HashMap<RunModeBoxInput, AbstractRunModeBox> _activeBoxes; private ArrayList<IOpenDisplayListener> _openDisplayListener; /** * Constructor. */ private RunModeService() { _activeBoxes = new HashMap<RunModeBoxInput, AbstractRunModeBox>(); _openDisplayListener = new ArrayList<IOpenDisplayListener>(); } /** * Returns the singleton instance. * * @return the singleton instance */ public static RunModeService getInstance() { if (_instance == null) { _instance = new RunModeService(); } return _instance; } public void openDisplayShellInRunMode(final IPath path, final Map<String, String> aliases) { openDisplayShellInRunMode(path, aliases, null); } /** * Opens a Display in a new Shell and adds the new Aliases. * * @param path * The IPath of the Display * @param aliases * A Map of new Aliases for the Display (can be null) */ public void openDisplayShellInRunMode(final IPath path, final Map<String, String> aliases, RunModeBoxInput predecessor) { assert path != null; final RunModeBoxInput runModeBoxInput = new RunModeBoxInput(path, aliases, RunModeType.SHELL); runModeBoxInput.setPredecessorBox(predecessor); Point location = null; if (_activeBoxes.containsKey(predecessor)) { AbstractRunModeBox runModeBox = _activeBoxes.get(predecessor); location = runModeBox.getCurrentLocation(); } if (_activeBoxes.containsKey(runModeBoxInput)) { AbstractRunModeBox box = _activeBoxes.get(runModeBoxInput); box.bringToTop(); } else { try { final AbstractRunModeBox runModeBox = new ShellRunModeBox( runModeBoxInput, location); // memorize box _activeBoxes.put(runModeBoxInput, runModeBox); // when the box is disposed, forget the box runModeBox.addDisposeListener(new IRunModeDisposeListener() { @Override public void dispose() { _activeBoxes.remove(runModeBoxInput); assert !_activeBoxes.containsKey(runModeBox) : "!_activeBoxes.containsKey(runModeBox)"; } }); // open the box runModeBox.openRunMode(null, new IDisplayLoadedCallback() { @Override public void displayLoaded() { notifyOpenDisplayListener(); } @Override public void displayClosed() { notifyOpenDisplayListener(); } }); } catch (IllegalArgumentException e) { LOG.info("Cannot open run mode: " + path.toOSString() + " does not exist."); MessageDialog.openError(null, "Control System Studio", "The display file was not found: " + path.toString()); } } } /** * Closes the RunModeBox corresponding to the given {@link RunModeBoxInput}. * * @param modeBoxInput * The {@link RunModeBoxInput} */ public void closeRunModeBox(final RunModeBoxInput modeBoxInput) { LOG.debug("Close RunModeBox: " + modeBoxInput.getFilePath()); AbstractRunModeBox runModeBox = _activeBoxes.get(modeBoxInput); runModeBox.dispose(); notifyOpenDisplayListener(); } /** * Opens a Display in a new View. * * @param location * The IPath to the Display */ public void openDisplayViewInRunMode(final IPath location) { this.openDisplayViewInRunMode(location, new HashMap<String, String>()); } /** * Opens a Display in a new View and adds the new Aliases. * * @param path * The IPath to the Display * @param aliases * The new Aliases for the Display (can be null) */ public void openDisplayViewInRunMode(final IPath path, final Map<String, String> aliases) { assert path != null; openBoxForWorkbenchView(path, aliases, null); } /** * Opens a Display in a new View with the informations of the given * {@link IMemento}. * * @param displayViewPart * the {@link DisplayViewPart} * @param memento * the {@link IMemento} for the view * @required memento!=null */ public void openDisplayViewInRunMode(final DisplayViewPart displayViewPart, final IMemento memento) { assert memento != null : "Precondition violated: memento!=null"; String storedPath = memento.getString("FILE"); if (storedPath != null) { Map<String, String> aliases = new HashMap<String, String>(); String tmp = memento.getString("ALIASES"); if (tmp != null) { String[] tmpA = tmp.split(SEPARATOR); if ((tmpA.length % 2 == 0)) { for (int i = 0; i <= tmpA.length - 1; i += 2) { String key = tmpA[i]; String value = tmpA[i + 1]; assert key != null; assert value != null; aliases.put(key, value); } } } openBoxForWorkbenchView(new Path(storedPath), aliases, displayViewPart); } } private void openBoxForWorkbenchView(final IPath path, final Map<String, String> aliases, final DisplayViewPart view) { assert path != null; final RunModeBoxInput runModeBoxInput = new RunModeBoxInput(path, aliases, RunModeType.VIEW); if (_activeBoxes.containsKey(runModeBoxInput)) { AbstractRunModeBox box = _activeBoxes.get(runModeBoxInput); box.bringToTop(); } else { try { final ViewRunModeBox runModeBox = new ViewRunModeBox( runModeBoxInput, view); // memorize box _activeBoxes.put(runModeBoxInput, runModeBox); // when the box is disposed, forget the box runModeBox.addDisposeListener(new IRunModeDisposeListener() { @Override public void dispose() { _activeBoxes.remove(runModeBoxInput); } }); // create a runnable that is executed, when the view is fully // launched Runnable runnable = new Runnable() { @Override public void run() { // IMPORTANT: set the memento infos on the view Map<String, String> mementoInfos = new HashMap<String, String>(); // the file path mementoInfos.put("FILE", path.toOSString()); if (aliases != null) { StringBuffer sb = new StringBuffer(); for (String key : aliases.keySet()) { sb.append(key + SEPARATOR + aliases.get(key)); } mementoInfos.put("ALIASES", sb.toString()); } // TODO: Funktioniert so nicht, da die View asynchron // geladen wird runModeBox.getView().setMementoInfos(mementoInfos); } }; // open the box runModeBox.openRunMode(runnable, new IDisplayLoadedCallback() { @Override public void displayLoaded() { notifyOpenDisplayListener(); } @Override public void displayClosed() { notifyOpenDisplayListener(); } }); } catch (IllegalArgumentException e) { LOG.info("Cannot open run mode: " + path.toOSString() + " does not exist."); MessageDialog.openError(null, "Control System Studio", "The display file was not found: " + path.toString()); } } } /** * Opens a Display in a new Shell. * * @param filePath * The IPath of the Display */ public void openDisplayShellInRunMode(final IPath filePath) { openDisplayShellInRunMode(filePath, new HashMap<String, String>()); } /** * Closes all running instances of the specified display. * * @param path * the display path */ public void closeDisplayShellInRunMode(IPath path) { for (RunModeBoxInput in : _activeBoxes.keySet()) { if (path.equals(in.getFilePath())) { _activeBoxes.get(in).dispose(); notifyOpenDisplayListener(); } } } public DisplayModel[] getAllActivDisplayModels() { List<DisplayModel> displays = new ArrayList<DisplayModel>(); for (AbstractRunModeBox box : _activeBoxes.values()) { displays.add(box.getDisplayModel()); } return displays.toArray(new DisplayModel[displays.size()]); } public void addOpenDisplayListener( IOpenDisplayListener openDisplayListener) { _openDisplayListener.add(openDisplayListener); } public void removeOpenDisplayListener( IOpenDisplayListener openDisplayListener) { _openDisplayListener.remove(openDisplayListener); } private void notifyOpenDisplayListener() { for (IOpenDisplayListener listener : _openDisplayListener) { listener.openDisplayChanged(); } } }