package uihelpers; import helpers.GH; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.HeadlessException; import java.awt.Transparency; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.PixelGrabber; import java.awt.image.WritableRaster; import java.io.File; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; import javax.swing.Icon; import javax.swing.ImageIcon; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.PaletteData; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; /** * Singleton that will manage loaded file icons.. * --> outsourced from the Editor icon providers.. * * @author quicksilver * */ public class IconManager { private static final class ManagerHolder { private static final IconManager singleton = new IconManager(); } private static final PaletteData PALETTE_DATA = new PaletteData(0xFF0000, 0xFF00, 0xFF); private final Image folder ; private final Image unknownFile; private static final Map<String,File> fileEnding = Collections.synchronizedMap(new HashMap<String,File>()); private final Map<String,Image> imageCache = new HashMap<String,Image>(); private boolean macOsX = Platform.OS_MACOSX.equals(Platform.getOS()); private IconManager() { //load unknown file icon and unknown folder icon File folder = new File(Platform.getInstanceLocation().getURL().getFile());//new File("unknownFolder"); File f = new File(folder,"unknownFile"); Image unknownFileImage = null; Image folderImage = null; try { if (folder.isDirectory() || folder.mkdirs()) { folderImage = loadImageFromFile(folder,null); } f.createNewFile(); unknownFileImage = loadImageFromFile(f,null); if (!f.delete()) { f.deleteOnExit(); } } catch (IOException ioe) { ioe.printStackTrace(); System.err.println("File: "+f); } if (unknownFileImage == null) { unknownFileImage = PlatformUI.getWorkbench().getSharedImages(). getImageDescriptor(ISharedImages.IMG_OBJ_FILE).createImage(); } if (folderImage == null) { folderImage = PlatformUI.getWorkbench().getSharedImages(). getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER).createImage(); } this.unknownFile = unknownFileImage; this.folder = folderImage; } public static IconManager get() { return ManagerHolder.singleton; } public Image getIconByFilename(String filename) { int i = filename.lastIndexOf('.'); if (i == -1) { return getIcon(""); } else { return getIcon(filename.substring(i+1)); } } /** * this function may only be accessed by the UI thread * * will return an item for the provided file ending * with and without a dot is accepted.. i.e. ".avi" or "avi" * @param ending a file ending * @return an unknown image if no image can be determined.. * else the matching image for the ending.. */ public Image getIcon(String ending) { if (GH.isEmpty(ending)) { return unknownFile; } else if (ending.charAt(0) == '.') { return getIcon(ending.substring(1)); } else if (imageCache.containsKey(ending)){ return imageCache.get(ending); } else if (fileEnding.containsKey(ending)) { File f = fileEnding.get(ending); Image fileIcon = null; if (f.isFile()) { fileIcon = loadImageFromFile(f,unknownFile); } else { fileEnding.remove(ending); } if (fileIcon != null) { imageCache.put(ending, fileIcon); return fileIcon; } } else { File f = null; try { File dir = new File(Platform.getInstanceLocation().getURL().getFile()); f = new File(dir, "iconfile."+ending); f.createNewFile(); Image fileIcon = loadImageFromFile(f,unknownFile); if (!f.delete()) { f.deleteOnExit(); } if (fileIcon != null) { imageCache.put(ending, fileIcon); return fileIcon; } } catch(IOException ioe) { ioe.printStackTrace(); if (f != null) { System.err.println(f); String path = f.getPath(); for (int i= 0 ; i < path.length(); i++) { System.err.print(" "+ (int)path.charAt(i)); } } } } return unknownFile; } /** * * @return an icon to represent a folder.. */ public Image getFolderIcon() { return folder; } /** * -> method must be static so IconManager is not initialized.. * * loads source files and folders of the provided folder * and its children * maps them to file endings so the files can be used * to create images.. * @param sourcefolder from where on files should be searched * for producing images.. */ public static void loadImageSources(File sourcefolder) { if (!sourcefolder.isDirectory()) { throw new IllegalArgumentException("provided path is not an existing folder "+sourcefolder); } File[] children = GH.getFiles(sourcefolder, false); for (File f:children) { if (f.isFile()) { checkFileForLoading(f); } else if (f.isDirectory()) { loadImageSources(f); } } } /** * will add the file to the caching MashMap.. * maps a local file to an ending * so it can be retrieved for loading images.. */ private static void checkFileForLoading(File f) { int i = f.getName().lastIndexOf('.'); if (i != -1) { String ending = f.getName().substring(i+1); if (!fileEnding.containsKey(ending)) { fileEnding.put(ending, f); } } } /** * will load the image of the provided file to RAM * @param f - the file on the disc that will be used for loading * @return the image that was loaded.. */ private Image loadImageFromFile(File f,Image defaultImage) { //System.out.println("f: "+f); if (f != null && f.exists()) { try { Icon ic = GH.getFileSystemView().getSystemIcon(f); IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); return convert(window.getShell().getDisplay(),toBufferedImage(ic)); } catch(Exception e) { e.printStackTrace(); } } return defaultImage ; } /** * */ private BufferedImage toBufferedImage(Icon icon) { java.awt.Image image; if (icon instanceof ImageIcon) { image = ((ImageIcon)icon).getImage(); } else { int w = icon.getIconWidth(); int h = icon.getIconHeight(); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gd = ge.getDefaultScreenDevice(); GraphicsConfiguration gc = gd.getDefaultConfiguration(); BufferedImage img = gc.createCompatibleImage(w, h); Graphics2D g = img.createGraphics(); icon.paintIcon(null, g, 0, 0); g.dispose(); image = img; } //following code taken from The Java Developers Almanac if (image instanceof BufferedImage) { return (BufferedImage)image; } // This code ensures that all the pixels in the image are loaded image = new ImageIcon(image).getImage(); // Determine if the image has transparent pixels; for this method's // implementation, see e661 Determining If an Image Has Transparent Pixels boolean hasAlpha = hasAlpha(image); // Create a buffered image with a format that's compatible with the screen BufferedImage bimage = null; GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); try { // Determine the type of transparency of the new buffered image int transparency = Transparency.OPAQUE; if (hasAlpha) { transparency = Transparency.BITMASK; } // Create the buffered image GraphicsDevice gs = ge.getDefaultScreenDevice(); GraphicsConfiguration gc = gs.getDefaultConfiguration(); bimage = gc.createCompatibleImage( image.getWidth(null), image.getHeight(null), transparency); } catch (HeadlessException e) { // The system does not have a screen } if (bimage == null) { // Create a buffered image using the default color model int type = BufferedImage.TYPE_INT_RGB; if (hasAlpha) { type = BufferedImage.TYPE_INT_ARGB; } bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type); } // Copy image to buffered image Graphics g = bimage.createGraphics(); // Paint the image onto the buffered image g.drawImage(image, 0, 0, null); g.dispose(); return bimage; } /** * code taken from The Java Developers Almanac */ // This method returns true if the specified image has transparent pixels private boolean hasAlpha(java.awt.Image image) { // If buffered image, the color model is readily available if (image instanceof BufferedImage) { BufferedImage bimage = (BufferedImage)image; return bimage.getColorModel().hasAlpha(); } // Use a pixel grabber to retrieve the image's color model; // grabbing a single pixel is usually sufficient PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false); try { pg.grabPixels(); } catch (InterruptedException e) { } // Get the image's color model ColorModel cm = pg.getColorModel(); return cm.hasAlpha(); } /** * Credit goes to (I think) Jody Schofield for this method. * * @param org.eclipse.swt.widgets.Display * @param java.awt.image.BufferedImage * @return org.eclipse.swt.graphics.Image */ private final Image convert(Display display, BufferedImage bufferedImage) { ImageData imageData = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), 24, PALETTE_DATA); int scansize = (((bufferedImage.getWidth() * 3) + 3) * 4) / 4; WritableRaster alphaRaster = bufferedImage.getAlphaRaster(); byte[] alphaBytes = new byte[bufferedImage.getWidth()]; for (int y = 0; y < bufferedImage.getHeight(); y++) { int[] buff = bufferedImage.getRGB(0, y, bufferedImage.getWidth(), 1, null, 0, scansize); imageData.setPixels(0, y, bufferedImage.getWidth(), buff, 0); if (alphaRaster != null) { int[] alpha = alphaRaster.getPixels(0, y, bufferedImage.getWidth(), 1, (int[]) null); for (int i = 0; i < bufferedImage.getWidth(); i++) { alphaBytes[i] = (byte) alpha[i]; } imageData.setAlphas(0, y, bufferedImage.getWidth(), alphaBytes, 0); } } bufferedImage.flush(); if (macOsX) { imageData.transparentPixel = 0; } return new Image(display, imageData); } /** * creates image descriptor from a local file.. * if the file does not exist it will instead return image form the ending of the provided file * @param f the file to provide an image for * @return IMagedescriptor.. or null */ public ImageDescriptor getImageDescriptorFromFile(File f) { Image img = imageCache.get(f.getPath()); if (img == null) { if (f.exists()) { img = loadImageFromFile(f, null); imageCache.put(f.getPath(), img); } else { img = getIconByFilename(f.getName()); } } if (img != null) { return ImageDescriptor.createFromImage(img); } else { return null; } } }