| /****************************************************************************** |
| * Copyright (c) 2002, 2006 IBM Corporation and others. |
| * 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: |
| * IBM Corporation - initial API and implementation |
| ****************************************************************************/ |
| |
| package org.eclipse.gmf.runtime.emf.ui.properties.actions; |
| |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.transaction.TransactionalEditingDomain; |
| import org.eclipse.emf.transaction.util.TransactionUtil; |
| import org.eclipse.gmf.runtime.common.core.util.Log; |
| import org.eclipse.gmf.runtime.common.core.util.StringStatics; |
| import org.eclipse.gmf.runtime.common.core.util.Trace; |
| import org.eclipse.gmf.runtime.common.ui.dialogs.PropertiesDialog; |
| import org.eclipse.gmf.runtime.common.ui.services.properties.extended.PropertyPagePropertyDescriptor; |
| import org.eclipse.gmf.runtime.emf.ui.properties.internal.EMFPropertiesDebugOptions; |
| import org.eclipse.gmf.runtime.emf.ui.properties.internal.EMFPropertiesPlugin; |
| import org.eclipse.gmf.runtime.emf.ui.properties.internal.EMFPropertiesStatusCodes; |
| import org.eclipse.gmf.runtime.emf.ui.properties.internal.l10n.EMFUIPropertiesMessages; |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.preference.IPreferencePage; |
| import org.eclipse.jface.preference.PreferenceManager; |
| import org.eclipse.jface.preference.PreferenceNode; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.plugin.AbstractUIPlugin; |
| import org.eclipse.ui.views.properties.IPropertyDescriptor; |
| import org.eclipse.ui.views.properties.IPropertySource; |
| |
| import com.ibm.icu.text.Collator; |
| |
| /** |
| * Action responsible for showing the properties page dialog when the it is |
| * invoked. |
| * <P> |
| * This action is always enabled. If there are no property pages applicable to |
| * the selection, a message dialog is shown to indicate that there are no |
| * property pages. |
| * |
| * @author ldamus |
| */ |
| public class PropertyPageViewAction |
| extends Action { |
| |
| /** |
| * Constructs a new action with the default label, image and tooltip. |
| */ |
| public PropertyPageViewAction() { |
| super(EMFUIPropertiesMessages.PropertyPageViewAction_label, |
| AbstractUIPlugin.imageDescriptorFromPlugin(EMFPropertiesPlugin.getPluginId(), "icons/property_page.gif")); //$NON-NLS-1$ |
| setToolTipText(EMFUIPropertiesMessages.PropertyPageViewAction_tooltip); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.action.Action#run() |
| */ |
| public void run() { |
| Trace.trace(EMFPropertiesPlugin.getDefault(), |
| EMFPropertiesDebugOptions.METHODS_ENTERING, |
| "PropertyPageViewActionDelegate.doRun Entering"); //$NON-NLS-1$ |
| IWorkbenchPage page = EMFPropertiesPlugin.getActivePage(); |
| if (page != null) { |
| final ISelection selection = page.getSelection(); |
| if (selection != null && selection instanceof IStructuredSelection) { |
| TransactionalEditingDomain domain = getEditingDomain((IStructuredSelection) selection); |
| |
| if (domain != null) { |
| try { |
| domain.runExclusive(new Runnable() { |
| |
| public void run() { |
| |
| // build the pages for the property dialog |
| List propertyPages = getMergedPropertyPages((IStructuredSelection) selection); |
| |
| if (!propertyPages.isEmpty()) { |
| // sort the pages |
| Collections.sort(propertyPages, |
| new Comparator() { |
| |
| public int compare(Object o1, |
| Object o2) { |
| IPreferencePage p1 = (IPreferencePage) o1; |
| IPreferencePage p2 = (IPreferencePage) o2; |
| String s1 = p1.getTitle(); |
| String s2 = p2.getTitle(); |
| return Collator.getInstance() |
| .compare(s1, s2); |
| } |
| }); |
| |
| // add the pages and invoke the property |
| // dialog |
| PropertiesDialog dialog = new PropertiesDialog( |
| Display.getCurrent().getActiveShell(), |
| new PreferenceManager()); |
| |
| for (Iterator iter = propertyPages |
| .iterator(); iter.hasNext();) { |
| dialog.getPreferenceManager() |
| .addToRoot( |
| new PreferenceNode( |
| StringStatics.BLANK, |
| (IPreferencePage) iter |
| .next())); |
| } |
| |
| dialog.create(); |
| dialog.open(); |
| } else { |
| MessageDialog |
| .openInformation( |
| Display.getCurrent() |
| .getActiveShell(), |
| EMFUIPropertiesMessages.PropertyPageViewAction_NoPropertiesMessageBox_Title, |
| EMFUIPropertiesMessages.PropertyPageViewAction_NoPropertiesMessageBox_Message); |
| } |
| } |
| }); |
| } catch (InterruptedException e) { |
| Trace.catching(EMFPropertiesPlugin.getDefault(), |
| EMFPropertiesDebugOptions.EXCEPTIONS_CATCHING, |
| getClass(), "run", e); //$NON-NLS-1$ |
| Log.error(EMFPropertiesPlugin.getDefault(), |
| EMFPropertiesStatusCodes.ACTION_FAILURE, e |
| .getLocalizedMessage(), e); |
| } |
| } |
| } |
| } |
| Trace.trace(EMFPropertiesPlugin.getDefault(), |
| EMFPropertiesDebugOptions.METHODS_EXITING, |
| "PropertyPageViewActionDelegate.doRun Exiting"); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Gets the property pages common to the given selection |
| * |
| * @param selection |
| * the selection |
| * @return List the list of property pages common to the given selection |
| */ |
| private List getMergedPropertyPages(IStructuredSelection selection) { |
| // build the merged properties, common to the entire selection |
| List mergedDescriptors = computeMergedPropertyDescriptors(selection); |
| |
| // build the merged pages from the merged properties |
| List mergedPages = new ArrayList(); |
| if (mergedDescriptors != null) { // if there were no objects to provide |
| // us with even property sources |
| for (Iterator i = mergedDescriptors.iterator(); i.hasNext();) { |
| PropertyPagePropertyDescriptor descriptor = (PropertyPagePropertyDescriptor) i |
| .next(); |
| List pages = descriptor.createPropertyPages(); |
| pages.removeAll(mergedPages); |
| mergedPages.addAll(pages); |
| } |
| } |
| return mergedPages; |
| } |
| |
| /** |
| * Return the intersection of all the <code>IPropertyDescriptor</code> s |
| * for the objects. |
| */ |
| private List computeMergedPropertyDescriptors(IStructuredSelection selection) { |
| if (selection.size() == 0) |
| return new ArrayList(0); |
| |
| // get all descriptors from each object |
| Map[] propertyDescriptorMaps = new Map[selection.size()]; |
| |
| Iterator i = selection.iterator(); |
| for (int index = 0; i.hasNext(); index++) { |
| Object object = i.next(); |
| IPropertySource source = (IPropertySource) ((IAdaptable) object) |
| .getAdapter(IPropertySource.class); |
| |
| if (source == null) { |
| // if one of the selected items is not a property source |
| // then we show no properties |
| return new ArrayList(0); |
| } |
| // get the property descriptors keyed by id |
| propertyDescriptorMaps[index] = computePropertyDescriptorsFor(source); |
| } |
| |
| // intersect |
| Map intersection = propertyDescriptorMaps[0]; |
| for (int p = 1; p < propertyDescriptorMaps.length; p++) { |
| // get the current ids |
| Object[] ids = intersection.keySet().toArray(); |
| for (int j = 0; j < ids.length; j++) { |
| Object object = propertyDescriptorMaps[p].get(ids[j]); |
| if (object == null |
| || |
| // see if the descriptors (which have the same id) are |
| // compatible |
| !((IPropertyDescriptor) intersection.get(ids[j])) |
| .isCompatibleWith((IPropertyDescriptor) object)) |
| intersection.remove(ids[j]); |
| } |
| } |
| |
| return new ArrayList(intersection.values()); |
| } |
| |
| /** |
| * Returns an map of property descritptors (keyed on id) for the |
| * given property source. |
| * |
| * @source a property source for which to obtain descriptors |
| * @return a table of decriptors keyed on their id |
| */ |
| private Map computePropertyDescriptorsFor(IPropertySource source) { |
| IPropertyDescriptor[] descriptors = source.getPropertyDescriptors(); |
| Map result = new HashMap(descriptors.length * 2 + 1); |
| for (int i = 0; i < descriptors.length; i++) { |
| if (descriptors[i] instanceof PropertyPagePropertyDescriptor) |
| result.put(descriptors[i].getId(), descriptors[i]); |
| } |
| return result; |
| } |
| |
| private TransactionalEditingDomain getEditingDomain(IStructuredSelection s) { |
| |
| TransactionalEditingDomain result = null; |
| |
| for (Iterator i = s.iterator(); i.hasNext();) { |
| Object next = i.next(); |
| |
| result = TransactionUtil.getEditingDomain(next); |
| |
| if (result == null && next instanceof IAdaptable) { |
| EObject eObject = (EObject) ((IAdaptable) next) |
| .getAdapter(EObject.class); |
| result = TransactionUtil.getEditingDomain(eObject); |
| } |
| |
| if (result != null) { |
| return result; |
| } |
| } |
| return null; |
| } |
| } |