package eu.jucy.ui.smileys; import helpers.GH; import helpers.PreferenceChangedAdapter; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Map.Entry; import java.util.concurrent.CopyOnWriteArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.ZipFile; import logger.LoggerFactory; import org.apache.log4j.Logger; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.ImageLoader; import org.eclipse.swt.widgets.Display; import org.osgi.framework.Bundle; import uc.IHub; import eu.jucy.gui.texteditor.ITextModificator; import eu.jucy.gui.texteditor.StyledTextViewer; import eu.jucy.gui.texteditor.StyledTextViewer.ImageReplacement; import eu.jucy.gui.texteditor.StyledTextViewer.Message; import eu.jucy.gui.texteditor.StyledTextViewer.TextReplacement; /** * * * @author Quicksilver * */ public class SmileyTextModificator implements ITextModificator { private static final Logger logger = LoggerFactory.make(); private static final String BUNDLE_NAME= "smileys.properties"; private static final List<Image[]> images = new CopyOnWriteArrayList<Image[]>(); private static final Map<String,Integer> smileyToImageNumber = new HashMap<String,Integer>(); private static final List<Entry<Integer,String>> smileyToCorrespondingText = new ArrayList<Entry<Integer,String>>(); private static Pattern allSmileys; private static Properties loadProperties() { Properties p = new Properties(); InputStream is = null; try { is = getInputStream(BUNDLE_NAME,SmileysPI.get(SmileysPI.SMILEYS_PATH)); p.load(is); } catch(IOException ioe) { ioe.printStackTrace(); } finally { GH.close(is); } return p; } private static InputStream getInputStream(String relpath,String zipPath) { try { if (GH.isEmpty(zipPath) || !new File(zipPath).isFile()) { Bundle bundle = Platform.getBundle(SmileysPI.PLUGIN_ID); Path path = new Path(relpath); URL url = FileLocator.find(bundle, path, Collections.EMPTY_MAP); return url.openStream(); } else { ZipFile zip = new ZipFile(zipPath); return zip.getInputStream(zip.getEntry(relpath)); } } catch (IOException e) { throw new IllegalStateException(e); } } public static boolean isValidZipFile(File f) { try { if (!f.isFile()) { return false; } ZipFile zip = new ZipFile(f); return zip.getEntry(BUNDLE_NAME) != null; } catch(IOException ioe) { return false; } } public static void loadAll() { images.clear();//ugly resource leak ...though unproblematic if not changed to often.. smileyToImageNumber.clear(); smileyToCorrespondingText.clear(); Properties prop = loadProperties(); String fullRegex = null; int i = -1; for (Entry<Object,Object> e: prop.entrySet()) { i++; String key = e.getKey().toString();; String smiley = e.getValue().toString(); // prop.getProperty(key); String[] smileys = smiley.split( Pattern.quote("$$$")); ImageLoader il = new ImageLoader(); ImageData[] imageData = il.load(getInputStream("smileys/"+key,SmileysPI.get(SmileysPI.SMILEYS_PATH))); Image[] imArray = new Image[imageData.length]; for (int x = 0; x < imageData.length; x++) { imageData[x].transparentPixel = imageData[x].getPixel(0, 0); imArray[x] = new Image(Display.getCurrent(),imageData[x]); } // if (imArray.length != 1) { // logger.info("smiley with "+imArray.length+" pics "+smiley); // } images.add(imArray); smileyToCorrespondingText.addAll(Collections.singletonMap(i,smileys[0]).entrySet()); for (String value:smileys) { smileyToImageNumber.put(value, i); String regex = "(?:"+Pattern.quote(value)+")"; if (fullRegex == null) { fullRegex=" ("+regex; } else { fullRegex += "|"+regex; } } } fullRegex += ") ?"; allSmileys = Pattern.compile(fullRegex); } static { loadAll(); new PreferenceChangedAdapter(SmileysPI.PLUGIN_ID,SmileysPI.SMILEYS_PATH) { @Override public void preferenceChanged(String preference, String oldValue,String newValue) { loadAll(); logger.debug("reloading smileys"); } }; } static List<Entry<Integer, String>> getSmileyToCorrespondingText() { return smileyToCorrespondingText; } static List<Image[]> getImages() { return images; } public void init(StyledText st ,StyledTextViewer viewer, IHub hub) {} public void dispose() {} public void getMessageModifications(Message original, boolean pm,List<TextReplacement> replacement) { int offset = 0; Matcher m = allSmileys.matcher(original.getMessage()); while (m.find(offset)) { int position = m.start(1); String smiley = m.group(1); Image img = images.get(smileyToImageNumber.get(smiley))[0]; replacement.add(new ImageReplacement(position,smiley,img)); //TODO ImageReplacement for multiple images offset = m.end(1); } } }