/* Copyright (C) 2009 Mobile Sorcery AB This program is free software; you can redistribute it and/or modify it under the terms of the Eclipse Public License v1.0. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Eclipse Public License v1.0 for more details. You should have received a copy of the Eclipse Public License v1.0 along with this program. It is also available at http://www.eclipse.org/legal/epl-v10.html */ package com.mobilesorcery.sdk.ui; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.StyledString; import org.eclipse.jface.viewers.StyledString.Styler; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.ImageLoader; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.graphics.TextStyle; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.ide.IDE; import com.mobilesorcery.sdk.core.MoSyncProject; import com.mobilesorcery.sdk.core.Util; import com.mobilesorcery.sdk.ui.internal.console.PathLink; public class UIUtils { public static void setDefaultShellBounds(Shell shell) { Rectangle displayBounds = shell.getDisplay().getBounds(); shell.setSize(320, 480); int x = (displayBounds.width - shell.getBounds().width) / 2; int y = (displayBounds.height - shell.getBounds().height) / 2; shell.setLocation(x, y); } public static int getDefaultFieldSize() { return 180; } public static int getDefaultListHeight() { return 320; } public static int getRowHeight(int rows) { Display display = Display.getCurrent(); GC gc = new GC(display); try { Point wh = gc.textExtent("\n"); return rows * wh.y; } finally { gc.dispose(); } } /** * Opens the editor in the workbench for a specific file. * @param workbench * @param file */ public static void openResource(final IWorkbenchWindow window, final IFile file) { if (window != null) { final IWorkbenchPage activePage = window.getActivePage(); if (activePage != null) { final Display display = window.getShell().getDisplay(); if (display != null) { display.asyncExec(new Runnable() { @Override public void run() { try { IDE.openEditor(activePage, file, true); } catch (PartInitException e) { e.printStackTrace(); } } }); } } } } public static void openResource(IWorkbench workbench, IFile file) { openResource(workbench.getActiveWorkbenchWindow(), file); } public static void openResource(IPath path, int lineNumber) { // Minor hack :) IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(path); if (files.length > 0) { new PathLink(files[0], null, -1, -1, lineNumber).linkActivated(); } else { new PathLink(path, null, -1, -1, lineNumber).linkActivated(); } } public static void setTransparency(ImageData data, int alpha) { for (int x = 0; x < data.width; x++) { for (int y = 0; y < data.height; y++) { data.setAlpha(x, y, alpha); } } } public static ImageData mix(ImageData data, RGB mixRGB, int alpha) { Image image = new Image(Display.getCurrent(), data); GC gc = new GC(image); Color mixColor = new Color(Display.getCurrent(), mixRGB); try { gc.setAlpha(alpha); gc.setBackground(mixColor); gc.fillRectangle(image.getBounds()); return image.getImageData(); } finally { image.dispose(); gc.dispose(); mixColor.dispose(); } } public static void safeDispose(GC gc) { if (gc != null && !gc.isDisposed()) { gc.dispose(); } } public static void safeDispose(Image image) { if (image != null && !image.isDisposed()) { image.dispose(); } } public static void safeDispose(Shell shell) { if (shell != null && !shell.isDisposed()) { shell.dispose(); } } /** * Returns a password property; if no such property is defined (or empty), * a password dialog is popped up. * @param project * @param propertyKey * @return */ public static String getPassword(final MoSyncProject project, final String propertyKey) { String pwd = project.getProperty(propertyKey); if (Util.isEmpty(pwd)) { final String[] result = new String[1]; Display display = PlatformUI.getWorkbench().getDisplay(); display.syncExec(new Runnable() { @Override public void run() { Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); PasswordDialog dialog = new PasswordDialog(shell); if (dialog.open() == PasswordDialog.OK) { result[0] = dialog.getPassword(); if (dialog.shouldRememberPassword()) { project.setProperty(propertyKey, result[0]); } } } }); return result[0]; } else { return pwd; } } /** * <p>Creates a new {@link Font} based on a prototype font.</p> * <p>Clients must dispose of the new font.</p> * @param original * @param style The style(ie <code>SWT.BOLD</code>) to apply to * the new font, or <code>SWT.DEFAULT</code> if the current style should be kept * @return */ public static Font modifyFont(Font original, int style) { return modifyFont(original, style, 0); } /** * <p>Creates a new {@link Font} based on a prototype font.</p> * <p>Clients must dispose of the new font.</p> * @param original * @param style The style(ie <code>SWT.BOLD</code>) to apply to * the new font, or <code>SWT.DEFAULT</code> if the current style should be kept * @param relativeHeight * @return */ public static Font modifyFont(Font original, int style, int relativeHeight) { if (original == null) { original = JFaceResources.getDefaultFont(); } FontData[] fd = original.getFontData(); fd = modifyFont(fd, style, relativeHeight); return new Font(original.getDevice(), fd); } /** * <p>Modifies an array of {@link FontData} based on a new style and relative height.</p> * @param original * @param style The style(ie <code>SWT.BOLD</code>) to apply to * the new font, or <code>SWT.DEFAULT</code> if the current style should be kept * @param relativeHeight * @return The modified array, always the same as the input value unless the input value is <code>null</code> * in which case a new array is created. */ public static FontData[] modifyFont(FontData[] fd, int style, int relativeHeight) { if (fd == null) { fd = JFaceResources.getDefaultFont().getFontData(); } for (int i = 0; i < fd.length; i++) { if (style != SWT.DEFAULT) { fd[i].setStyle(style); } fd[i].setHeight(fd[i].getHeight() + relativeHeight); } return fd; } public static void main(String[] args) { Image i = new Image(Display.getCurrent(), "C:\\development\\projects\\mobilesorcery-4\\com.mobilesorcery.sdk.ui\\icons\\mosyncproject.png"); ImageData d = i.getImageData(); ImageData d2 = mix(d, new RGB(0xff, 0xff, 0xff), 0x7f); ImageLoader il = new ImageLoader(); il.data = new ImageData[] { d2 }; il.save("C:\\development\\projects\\mobilesorcery-4\\com.mobilesorcery.sdk.ui\\icons\\deprecated-mosyncproject.png", SWT.IMAGE_PNG); i.dispose(); } public static void dispose(Object... resources) { for (int i = 0; i < resources.length; i++) { Object resource = resources[i]; if (resource instanceof Color) { ((Color) resource).dispose(); } else if (resource instanceof Font) { ((Font) resource).dispose(); } else if (resource instanceof Widget) { ((Widget) resource).dispose(); } } } /** * Returns a default layout for preference/property pages * (no margins) * @param i * @return */ public static GridLayout newPrefsLayout(int columns) { GridLayout result = new GridLayout(columns, false); result.marginWidth = 0; result.marginHeight = 0; return result; } /** * Runs a runnable on the current UI thread, or if the * thread this method is called from is NOT a UI thread, * it will be posted to the UI thread. * @param display * @param r */ public static void onUiThread(Display display, Runnable r, boolean fork) { if (display == Display.getCurrent()) { r.run(); } else { if (fork) { display.asyncExec(r); } else { display.syncExec(r); } } } public static void centerShell(Shell newShell) { Rectangle screenSize = Display.getCurrent().getPrimaryMonitor().getBounds(); int x = (screenSize.width - newShell.getSize().x) / 2; int y = (screenSize.height - newShell.getSize().y) / 2; newShell.setLocation(x, y); } /** * Sets the name of control. For testing purposes. * @param control * @param name */ public static void nameControl(Control control, String name) { if (control != null) { control.setData("name", name); } } public static StyledString.Styler createStyler(final Font font, final Color fgColor) { Styler result = new StyledString.Styler() { @Override public void applyStyles(TextStyle textstyle) { if (fgColor != null) { textstyle.foreground = fgColor; } if (font != null) { textstyle.font = font; } } }; return result; } }