| /******************************************************************************* |
| * Copyright (c) 2010 BSI Business Systems Integration AG. |
| * 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: |
| * BSI Business Systems Integration AG - initial API and implementation |
| ******************************************************************************/ |
| package org.eclipse.scout.sdk.ui.util; |
| |
| import java.net.URI; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.URIUtil; |
| import org.eclipse.jdt.core.Flags; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IPackageFragment; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; |
| import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider; |
| import org.eclipse.jdt.ui.JavaElementImageDescriptor; |
| import org.eclipse.jdt.ui.JavaUI; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.text.IRegion; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.scout.commons.StringUtility; |
| import org.eclipse.scout.sdk.jdt.compile.ScoutSeverityManager; |
| import org.eclipse.scout.sdk.ui.internal.ScoutSdkUi; |
| import org.eclipse.scout.sdk.ui.view.outline.pages.IPage; |
| import org.eclipse.scout.sdk.ui.view.outline.pages.ITypePage; |
| import org.eclipse.scout.sdk.util.resources.ResourceUtility; |
| import org.eclipse.scout.sdk.util.type.ITypeFilter; |
| import org.eclipse.scout.sdk.util.type.TypeUtility; |
| import org.eclipse.scout.sdk.workspace.IScoutBundle; |
| import org.eclipse.scout.sdk.workspace.IScoutBundleFilter; |
| import org.eclipse.scout.sdk.workspace.ScoutBundleFilters; |
| import org.eclipse.scout.sdk.workspace.type.ScoutTypeUtility; |
| import org.eclipse.swt.graphics.Drawable; |
| import org.eclipse.swt.graphics.Font; |
| import org.eclipse.swt.graphics.GC; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IEditorReference; |
| import org.eclipse.ui.IURIEditorInput; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.texteditor.ITextEditor; |
| |
| /** |
| * <h3>{@link UiUtility}</h3> |
| * |
| * @author Andreas Hoegger |
| * @since 1.0.8 07.03.2011 |
| */ |
| @SuppressWarnings("restriction") |
| public final class UiUtility { |
| |
| private UiUtility() { |
| } |
| |
| /** |
| * Shows the given java element in the java editor. |
| * |
| * @param e |
| * The element to focus |
| * @param createNew |
| * indicates if a new editor should be opened if not open yet. If false, the element will only be shown if |
| * there is a java editor open yet. |
| */ |
| public static void showJavaElementInEditor(IJavaElement e, boolean createNew) { |
| try { |
| IEditorPart editor = null; |
| if (createNew) { |
| editor = JavaUI.openInEditor(e); |
| } |
| else { |
| editor = EditorUtility.isOpenInEditor(e); |
| if (editor != null) { |
| PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().activate(editor); |
| } |
| } |
| if (editor != null) { |
| JavaUI.revealInEditor(editor, e); |
| if (editor instanceof ITextEditor) { |
| ITextEditor textEditor = (ITextEditor) editor; |
| IRegion reg = textEditor.getHighlightRange(); |
| if (reg != null) { |
| textEditor.setHighlightRange(reg.getOffset(), reg.getLength(), true); |
| } |
| } |
| } |
| } |
| catch (Exception ex) { |
| ScoutSdkUi.logWarning(ex); |
| } |
| } |
| |
| /** |
| * Returns the extent of the given string. No tab |
| * expansion or carriage return processing will be performed. |
| * <p> |
| * The <em>extent</em> of a string is the width and height of the rectangular area it would cover if drawn in the |
| * given font. |
| * </p> |
| * |
| * @param text |
| * @param f |
| * @param context |
| * @return a point containing the extent of the string |
| */ |
| public static Point getTextBounds(String text, Font f, Drawable context) { |
| GC gc = new GC(context); |
| gc.setFont(f); |
| return gc.stringExtent(text); |
| } |
| |
| /** |
| * Gets the shortened text based on the given input so that the text returned is smaller than the given bounds. |
| * |
| * @param origText |
| * The original text that should be shortened to match into bounds. |
| * @param f |
| * The {@link Font} to use to calculate the text length. |
| * @param context |
| * The context in which the calculation should be performed. |
| * @param bounds |
| * The number of pixels. The returned text will be shorter than this limit if rendered in the given context |
| * with the given font. |
| * @return The text shortened to given bounds including an ellipsis if it has been cut. |
| */ |
| public static String getTextForBounds(String origText, Font f, Drawable context, int bounds) { |
| return getTextForBounds(origText, f, context, bounds, "…"); |
| } |
| |
| /** |
| * Gets the shortened text based on the given input so that the text returned is smaller than the given bounds. |
| * |
| * @param origText |
| * The original text that should be shortened to match into bounds. |
| * @param f |
| * The {@link Font} to use to calculate the text length. |
| * @param context |
| * The context in which the calculation should be performed. |
| * @param bounds |
| * The number of pixels. The returned text will be shorter than this limit if rendered in the given context |
| * with the given font. |
| * @param ellipsis |
| * The suffix to add if the given origText has been shortened or null if no suffix should be added. |
| * @return The text shortened to given bounds including the given ellipsis if it has been cut. |
| */ |
| public static String getTextForBounds(String origText, Font f, Drawable context, int bounds, String ellipsis) { |
| if (bounds <= 0) { |
| return origText; |
| } |
| |
| String cleanedEllipsis = null; |
| if (StringUtility.hasText(ellipsis)) { |
| cleanedEllipsis = ellipsis; |
| } |
| else { |
| cleanedEllipsis = ""; |
| } |
| StringBuilder sb = new StringBuilder(origText); |
| GC gc = new GC(context); |
| gc.setFont(f); |
| |
| Point p = gc.stringExtent(sb.toString()); |
| while (p.x > bounds && sb.length() > 0) { |
| sb.deleteCharAt(sb.length() - 1); |
| p = gc.stringExtent(sb.toString() + cleanedEllipsis); |
| } |
| |
| String ret = sb.toString(); |
| if (ret.equals(origText)) { |
| return origText; |
| } |
| else { |
| return sb.toString() + cleanedEllipsis; |
| } |
| } |
| |
| /** |
| * Gets the packages suffix of the given selection.<br> |
| * This method calculates the java package that surrounds the current selection and returns the suffix (the package |
| * part after the symbolic name of the containing bundle). |
| * |
| * @param selection |
| * The selection to evaluate |
| * @return A string with the package suffix or null. |
| */ |
| public static String getPackageSuffix(IStructuredSelection selection) { |
| if (selection == null) { |
| return null; |
| } |
| return getPackageSuffix(UiUtility.adapt(selection.getFirstElement(), IJavaElement.class)); |
| } |
| |
| /** |
| * Gets the packages suffix of the given element.<br> |
| * This method calculates the java package that surrounds the given element and returns the suffix (the package |
| * part after the symbolic name of the containing bundle). |
| * |
| * @param element |
| * The element |
| * @return A string with the package suffix or null. |
| */ |
| public static String getPackageSuffix(IJavaElement element) { |
| if (TypeUtility.exists(element)) { |
| IPackageFragment targetPackage = (IPackageFragment) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT); |
| if (TypeUtility.exists(targetPackage)) { |
| String pck = targetPackage.getElementName(); |
| IScoutBundle declaringBundle = ScoutTypeUtility.getScoutBundle(targetPackage); |
| if (declaringBundle != null && pck.startsWith(declaringBundle.getSymbolicName()) && pck.length() > declaringBundle.getSymbolicName().length()) { |
| return pck.substring(declaringBundle.getSymbolicName().length() + 1); |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Closes all open instances of the given editor.<br> |
| * If the editors are dirty, the user is asked if they should be saved. |
| * |
| * @param editorId |
| * The editor id filter or null if all editors should be closed. |
| * @param files |
| * The files filter or null. Only the editors of those files are closed. |
| * @return true if all editors have been closed. false otherwise (e.g. when the user presses cancel in the save dirty |
| * editor confirmation message box). |
| */ |
| public static boolean closeEditors(String editorId, Set<IFile> files) { |
| for (IWorkbenchWindow w : PlatformUI.getWorkbench().getWorkbenchWindows()) { |
| for (IWorkbenchPage p : w.getPages()) { |
| IEditorReference[] editorReferences = p.getEditorReferences(); |
| List<IEditorReference> partsToSave = new ArrayList<IEditorReference>(editorReferences.length); |
| for (IEditorReference r : editorReferences) { |
| if (editorId == null || editorId.equals(r.getId())) { |
| if (files == null || files.isEmpty() || isEditorInputInFiles(r, files)) { |
| partsToSave.add(r); |
| } |
| } |
| } |
| if (!partsToSave.isEmpty()) { |
| boolean success = p.closeEditors(partsToSave.toArray(new IEditorReference[partsToSave.size()]), true); |
| if (!success) { |
| return false; |
| } |
| } |
| } |
| } |
| return true; |
| } |
| |
| private static boolean isEditorInputInFiles(IEditorReference ref, Set<IFile> files) { |
| try { |
| IEditorInput editorInput = ref.getEditorInput(); |
| if (editorInput instanceof IURIEditorInput) { |
| IURIEditorInput input = (IURIEditorInput) editorInput; |
| URI uriToSearch = input.getURI(); |
| for (IFile f : files) { |
| if (URIUtil.sameURI(uriToSearch, f.getLocationURI())) { |
| return true; |
| } |
| } |
| } |
| } |
| catch (PartInitException e) { |
| ScoutSdkUi.logError("Unable to get file input of editor.", e); |
| } |
| return false; |
| } |
| |
| /** |
| * Tries to calculate the most specific scout bundle that contains the given selection. |
| * |
| * @param selection |
| * @return |
| */ |
| public static IScoutBundle getScoutBundleFromSelection(IStructuredSelection selection) { |
| return getScoutBundleFromSelection(selection, null); |
| } |
| |
| /** |
| * Tries to calculate the most specific scout bundle that contains the given selection. |
| * The given filter is taken into account so that clients can influence which types of scout bundles around the |
| * selected one that should be used.<br> |
| * |
| * @param selection |
| * @param filter |
| * @return |
| */ |
| public static IScoutBundle getScoutBundleFromSelection(IStructuredSelection selection, IScoutBundleFilter filter) { |
| if (selection != null) { |
| IScoutBundle b = UiUtility.adapt(selection.getFirstElement(), IScoutBundle.class); |
| if (b != null) { |
| if (filter == null || filter.accept(b)) { |
| return b; |
| } |
| else { |
| IScoutBundle parentShared = b.getParentBundle(ScoutBundleFilters.getBundlesOfTypeFilter(IScoutBundle.TYPE_SHARED), b, true); |
| if (parentShared != null) { |
| IScoutBundle candidate = parentShared.getChildBundle(ScoutBundleFilters.getMultiFilterAnd(ScoutBundleFilters.getWorkspaceBundlesFilter(), filter), b, true); |
| if (candidate != null) { |
| return candidate; |
| } |
| } |
| else { |
| IScoutBundle candidate = b.getChildBundle(ScoutBundleFilters.getMultiFilterAnd(ScoutBundleFilters.getWorkspaceBundlesFilter(), filter), b, false); |
| if (candidate != null) { |
| return candidate; |
| } |
| } |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| public static IType getTypeFromSelection(IStructuredSelection selection) { |
| return getTypeFromSelection(selection, null); |
| } |
| |
| public static IType getTypeFromSelection(IStructuredSelection selection, ITypeFilter filter) { |
| return getTypeFromSelection(selection.getFirstElement(), filter); |
| } |
| |
| private static IType getTypeFromSelection(Object o, ITypeFilter filter) { |
| IType t = UiUtility.adapt(o, IType.class); |
| if (TypeUtility.exists(t) && (filter == null || filter.accept(t))) { |
| return t; |
| } |
| return null; |
| } |
| |
| public static Set<IType> getTypesFromSelection(IStructuredSelection selection, ITypeFilter filter) { |
| Set<IType> result = new LinkedHashSet<IType>(selection.size()); |
| if (selection.isEmpty()) { |
| return result; |
| } |
| |
| Iterator<?> it = selection.iterator(); |
| while (it.hasNext()) { |
| Object o = it.next(); |
| IType t = getTypeFromSelection(o, filter); |
| if (t != null) { |
| result.add(t); |
| } |
| } |
| |
| return result; |
| } |
| |
| /** |
| * Tries to convert the given element into the given class. |
| * This method respects scout IPage classes. |
| * |
| * @param element |
| * The element to convert. |
| * @param targetClass |
| * The class in which it should be converted. |
| * @return the converted element or null if the conversion could not be done. |
| */ |
| @SuppressWarnings("unchecked") |
| public static <T> T adapt(Object element, Class<T> targetClass) { |
| if (element == null || targetClass == null) { |
| return null; |
| } |
| if (targetClass.isInstance(element)) { |
| return (T) element; |
| } |
| |
| // get element out of the pages |
| if (element instanceof IPage) { |
| IPage page = (IPage) element; |
| IScoutBundle sb = page.getScoutBundle(); |
| if (sb != null) { |
| element = sb; |
| } |
| |
| do { |
| if (page instanceof ITypePage) { |
| ITypePage astp = (ITypePage) page; |
| IType t = astp.getType(); |
| if (TypeUtility.exists(t)) { |
| element = t; |
| break; |
| } |
| } |
| page = page.getParent(); |
| } |
| while (page != null); |
| } |
| |
| // try to adapt |
| if (element instanceof IAdaptable) { |
| IAdaptable ad = (IAdaptable) element; |
| T result = (T) ad.getAdapter(targetClass); |
| if (result == null) { |
| // try to get a resource |
| IResource r = (IResource) ad.getAdapter(IResource.class); |
| if (!ResourceUtility.exists(r)) { |
| IJavaElement je = (IJavaElement) ad.getAdapter(IJavaElement.class); |
| if (TypeUtility.exists(je)) { |
| r = je.getResource(); |
| } |
| } |
| |
| if (ResourceUtility.exists(r)) { |
| // try to convert from a resource |
| result = (T) r.getAdapter(targetClass); |
| } |
| } |
| return result; |
| } |
| return null; |
| } |
| |
| /** |
| * Gets an image descriptor for classes.<br> |
| * The image descriptor includes flags like abstract, final, static, deprecated. Furthermore it shows different icons |
| * for interfaces and classes and includes the severity flags of the classes (e.g. error or warning). |
| * |
| * @param type |
| * The type for which the icon should be returned. |
| * @return The image descriptor. |
| */ |
| public static ImageDescriptor getTypeImageDescriptor(IType type) { |
| return getTypeImageDescriptor(type, true); |
| } |
| |
| public static ImageDescriptor getTypeImageDescriptor(IType type, boolean showSeverity) { |
| int flags = -1; |
| try { |
| flags = type.getFlags(); |
| } |
| catch (JavaModelException e) { |
| } |
| |
| boolean isInterface = Flags.isInterface(flags); |
| boolean isInner = TypeUtility.exists(type.getDeclaringType()); |
| int severity = 0; |
| if (showSeverity) { |
| ScoutSeverityManager.getInstance().getSeverityOf(type); |
| } |
| ImageDescriptor desc = JavaElementImageProvider.getTypeImageDescriptor(isInner, isInterface, flags, false); |
| |
| int adornmentFlags = 0; |
| if (Flags.isFinal(flags)) { |
| adornmentFlags |= JavaElementImageDescriptor.FINAL; |
| } |
| if (Flags.isAbstract(flags) && !isInterface) { |
| adornmentFlags |= JavaElementImageDescriptor.ABSTRACT; |
| } |
| if (Flags.isStatic(flags)) { |
| adornmentFlags |= JavaElementImageDescriptor.STATIC; |
| } |
| if (Flags.isDeprecated(flags)) { |
| adornmentFlags |= JavaElementImageDescriptor.DEPRECATED; |
| } |
| |
| if (severity == IMarker.SEVERITY_ERROR) { |
| adornmentFlags |= JavaElementImageDescriptor.ERROR; |
| } |
| else if (severity == IMarker.SEVERITY_WARNING) { |
| adornmentFlags |= JavaElementImageDescriptor.WARNING; |
| } |
| |
| return new JavaElementImageDescriptor(desc, adornmentFlags, JavaElementImageProvider.BIG_SIZE); |
| } |
| } |