From 7cd410e8e36cc790b86533a6f0bb1bfbdfb051a1 Mon Sep 17 00:00:00 2001 From: pescuma Date: Wed, 2 Apr 2008 04:28:33 +0000 Subject: Initial version of MepEditor git-svn-id: http://pescuma.googlecode.com/svn/trunk/Miranda@74 c086bb3d-8645-0410-b8da-73a8550f86e7 --- Plugins/emoticons/MepEditor/.classpath | 18 + Plugins/emoticons/MepEditor/.project | 17 + Plugins/emoticons/MepEditor/JarDescription.jardesc | 16 + Plugins/emoticons/MepEditor/MepEditor.png | Bin 0 -> 39266 bytes Plugins/emoticons/MepEditor/ZIP/MepEditor.bat | 2 + Plugins/emoticons/MepEditor/imgs/disk.png | Bin 0 -> 620 bytes .../emoticons/MepEditor/lib/commons-codec-1.3.jar | Bin 0 -> 46725 bytes .../MepEditor/lib/commons-httpclient-3.1.jar | Bin 0 -> 305001 bytes .../lib/commons-logging-1.1.1-javadoc.jar | Bin 0 -> 141401 bytes .../lib/commons-logging-1.1.1-sources.jar | Bin 0 -> 74976 bytes .../MepEditor/lib/commons-logging-1.1.1.jar | Bin 0 -> 60841 bytes Plugins/emoticons/MepEditor/lib/src.zip | Bin 0 -> 1805090 bytes Plugins/emoticons/MepEditor/lib/swt-debug.jar | Bin 0 -> 1951088 bytes Plugins/emoticons/MepEditor/lib/swt.jar | Bin 0 -> 1399767 bytes .../MepEditor/src/emoticons/EmoFormat.java | 92 ++++ .../MepEditor/src/emoticons/Emoticon.java | 42 ++ .../MepEditor/src/emoticons/EmoticonImage.java | 6 + .../MepEditor/src/emoticons/ImageFile.java | 89 ++++ .../MepEditor/src/emoticons/ImageUtils.java | 78 ++++ Plugins/emoticons/MepEditor/src/emoticons/Mep.java | 110 +++++ .../MepEditor/src/emoticons/MepEditor.java | 471 +++++++++++++++++++++ .../MepEditor/src/emoticons/MepFormat.java | 256 +++++++++++ 22 files changed, 1197 insertions(+) create mode 100644 Plugins/emoticons/MepEditor/.classpath create mode 100644 Plugins/emoticons/MepEditor/.project create mode 100644 Plugins/emoticons/MepEditor/JarDescription.jardesc create mode 100644 Plugins/emoticons/MepEditor/MepEditor.png create mode 100644 Plugins/emoticons/MepEditor/ZIP/MepEditor.bat create mode 100644 Plugins/emoticons/MepEditor/imgs/disk.png create mode 100644 Plugins/emoticons/MepEditor/lib/commons-codec-1.3.jar create mode 100644 Plugins/emoticons/MepEditor/lib/commons-httpclient-3.1.jar create mode 100644 Plugins/emoticons/MepEditor/lib/commons-logging-1.1.1-javadoc.jar create mode 100644 Plugins/emoticons/MepEditor/lib/commons-logging-1.1.1-sources.jar create mode 100644 Plugins/emoticons/MepEditor/lib/commons-logging-1.1.1.jar create mode 100644 Plugins/emoticons/MepEditor/lib/src.zip create mode 100644 Plugins/emoticons/MepEditor/lib/swt-debug.jar create mode 100644 Plugins/emoticons/MepEditor/lib/swt.jar create mode 100644 Plugins/emoticons/MepEditor/src/emoticons/EmoFormat.java create mode 100644 Plugins/emoticons/MepEditor/src/emoticons/Emoticon.java create mode 100644 Plugins/emoticons/MepEditor/src/emoticons/EmoticonImage.java create mode 100644 Plugins/emoticons/MepEditor/src/emoticons/ImageFile.java create mode 100644 Plugins/emoticons/MepEditor/src/emoticons/ImageUtils.java create mode 100644 Plugins/emoticons/MepEditor/src/emoticons/Mep.java create mode 100644 Plugins/emoticons/MepEditor/src/emoticons/MepEditor.java create mode 100644 Plugins/emoticons/MepEditor/src/emoticons/MepFormat.java diff --git a/Plugins/emoticons/MepEditor/.classpath b/Plugins/emoticons/MepEditor/.classpath new file mode 100644 index 0000000..79c0ee8 --- /dev/null +++ b/Plugins/emoticons/MepEditor/.classpath @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/Plugins/emoticons/MepEditor/.project b/Plugins/emoticons/MepEditor/.project new file mode 100644 index 0000000..8ead2fb --- /dev/null +++ b/Plugins/emoticons/MepEditor/.project @@ -0,0 +1,17 @@ + + + MepEditor + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/Plugins/emoticons/MepEditor/JarDescription.jardesc b/Plugins/emoticons/MepEditor/JarDescription.jardesc new file mode 100644 index 0000000..ce47ff8 --- /dev/null +++ b/Plugins/emoticons/MepEditor/JarDescription.jardesc @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/Plugins/emoticons/MepEditor/MepEditor.png b/Plugins/emoticons/MepEditor/MepEditor.png new file mode 100644 index 0000000..e96a7f6 Binary files /dev/null and b/Plugins/emoticons/MepEditor/MepEditor.png differ diff --git a/Plugins/emoticons/MepEditor/ZIP/MepEditor.bat b/Plugins/emoticons/MepEditor/ZIP/MepEditor.bat new file mode 100644 index 0000000..8d24a8d --- /dev/null +++ b/Plugins/emoticons/MepEditor/ZIP/MepEditor.bat @@ -0,0 +1,2 @@ +@echo off +javaw -classpath MepEditor.jar;swt.jar;commons-codec-1.3.jar;commons-httpclient-3.1.jar;commons-logging-1.1.1.jar;swt.jar emoticons.MepEditor diff --git a/Plugins/emoticons/MepEditor/imgs/disk.png b/Plugins/emoticons/MepEditor/imgs/disk.png new file mode 100644 index 0000000..99d532e Binary files /dev/null and b/Plugins/emoticons/MepEditor/imgs/disk.png differ diff --git a/Plugins/emoticons/MepEditor/lib/commons-codec-1.3.jar b/Plugins/emoticons/MepEditor/lib/commons-codec-1.3.jar new file mode 100644 index 0000000..957b675 Binary files /dev/null and b/Plugins/emoticons/MepEditor/lib/commons-codec-1.3.jar differ diff --git a/Plugins/emoticons/MepEditor/lib/commons-httpclient-3.1.jar b/Plugins/emoticons/MepEditor/lib/commons-httpclient-3.1.jar new file mode 100644 index 0000000..7c59774 Binary files /dev/null and b/Plugins/emoticons/MepEditor/lib/commons-httpclient-3.1.jar differ diff --git a/Plugins/emoticons/MepEditor/lib/commons-logging-1.1.1-javadoc.jar b/Plugins/emoticons/MepEditor/lib/commons-logging-1.1.1-javadoc.jar new file mode 100644 index 0000000..83e063f Binary files /dev/null and b/Plugins/emoticons/MepEditor/lib/commons-logging-1.1.1-javadoc.jar differ diff --git a/Plugins/emoticons/MepEditor/lib/commons-logging-1.1.1-sources.jar b/Plugins/emoticons/MepEditor/lib/commons-logging-1.1.1-sources.jar new file mode 100644 index 0000000..00fc09c Binary files /dev/null and b/Plugins/emoticons/MepEditor/lib/commons-logging-1.1.1-sources.jar differ diff --git a/Plugins/emoticons/MepEditor/lib/commons-logging-1.1.1.jar b/Plugins/emoticons/MepEditor/lib/commons-logging-1.1.1.jar new file mode 100644 index 0000000..8758a96 Binary files /dev/null and b/Plugins/emoticons/MepEditor/lib/commons-logging-1.1.1.jar differ diff --git a/Plugins/emoticons/MepEditor/lib/src.zip b/Plugins/emoticons/MepEditor/lib/src.zip new file mode 100644 index 0000000..970ffce Binary files /dev/null and b/Plugins/emoticons/MepEditor/lib/src.zip differ diff --git a/Plugins/emoticons/MepEditor/lib/swt-debug.jar b/Plugins/emoticons/MepEditor/lib/swt-debug.jar new file mode 100644 index 0000000..f6fb385 Binary files /dev/null and b/Plugins/emoticons/MepEditor/lib/swt-debug.jar differ diff --git a/Plugins/emoticons/MepEditor/lib/swt.jar b/Plugins/emoticons/MepEditor/lib/swt.jar new file mode 100644 index 0000000..9542ca1 Binary files /dev/null and b/Plugins/emoticons/MepEditor/lib/swt.jar differ diff --git a/Plugins/emoticons/MepEditor/src/emoticons/EmoFormat.java b/Plugins/emoticons/MepEditor/src/emoticons/EmoFormat.java new file mode 100644 index 0000000..7f01070 --- /dev/null +++ b/Plugins/emoticons/MepEditor/src/emoticons/EmoFormat.java @@ -0,0 +1,92 @@ +package emoticons; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class EmoFormat +{ + public final List emoticons; + public final List protocols; + + public EmoFormat(List emoticons, List protocols) + { + this.emoticons = emoticons; + this.protocols = protocols; + } + + public void load() + { + File path = new File("data/"); + for (File file : path.listFiles()) + { + if (!file.getName().endsWith(".emo")) + continue; + + String protocol = file.getName(); + protocol = protocol.substring(0, protocol.length() - 4); + protocols.add(protocol); + try + { + BufferedReader in = new BufferedReader(new FileReader(file)); + String line; + while ((line = in.readLine()) != null) + { + line = line.trim(); + if (line.length() <= 0 || line.startsWith("#")) + continue; + + int pos = line.indexOf('='); + if (pos < 0) + continue; + + String name = removeSeparators(line.substring(0, pos)); + Emoticon emoticon = getEmoticon(name); + emoticon.icons.put(protocol, new EmoticonImage()); + } + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + Collections.sort(emoticons, new Comparator() { + public int compare(Emoticon o1, Emoticon o2) + { + return o1.name.compareToIgnoreCase(o2.name); + } + }); + } + + private String removeSeparators(String str) + { + str = str.trim(); + if (str.endsWith(",")) + { + str = str.substring(0, str.length() - 1); + str = str.trim(); + } + if (str.charAt(0) == '"' && str.charAt(str.length() - 1) == '"') + str = str.substring(1, str.length() - 1); + return str; + } + + private Emoticon getEmoticon(String name) + { + for (Emoticon emoticon : emoticons) + { + if (emoticon.name.equals(name)) + return emoticon; + } + Emoticon emo = new Emoticon(); + emo.name = name; + emo.icons.put(null, new EmoticonImage()); + emoticons.add(emo); + return emo; + } + +} diff --git a/Plugins/emoticons/MepEditor/src/emoticons/Emoticon.java b/Plugins/emoticons/MepEditor/src/emoticons/Emoticon.java new file mode 100644 index 0000000..f0470d1 --- /dev/null +++ b/Plugins/emoticons/MepEditor/src/emoticons/Emoticon.java @@ -0,0 +1,42 @@ +package emoticons; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.swt.widgets.Composite; + +public class Emoticon +{ + String name; + final Map icons = new HashMap(); + + Composite frames; + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final Emoticon other = (Emoticon) obj; + if (name == null) + { + if (other.name != null) + return false; + } + else if (!name.equals(other.name)) + return false; + return true; + } +} diff --git a/Plugins/emoticons/MepEditor/src/emoticons/EmoticonImage.java b/Plugins/emoticons/MepEditor/src/emoticons/EmoticonImage.java new file mode 100644 index 0000000..9b6bcd5 --- /dev/null +++ b/Plugins/emoticons/MepEditor/src/emoticons/EmoticonImage.java @@ -0,0 +1,6 @@ +package emoticons; + +public class EmoticonImage +{ + ImageFile image; +} diff --git a/Plugins/emoticons/MepEditor/src/emoticons/ImageFile.java b/Plugins/emoticons/MepEditor/src/emoticons/ImageFile.java new file mode 100644 index 0000000..8de644f --- /dev/null +++ b/Plugins/emoticons/MepEditor/src/emoticons/ImageFile.java @@ -0,0 +1,89 @@ +package emoticons; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.methods.GetMethod; +import org.eclipse.swt.graphics.Image; + +public class ImageFile +{ + public String path; + public File realPath; + public Image[] frames; + public int frame; + + public ImageFile(String path, File realPath) + { + this.path = path; + this.realPath = realPath; + } + + public void loadFrames() + { + if (frames != null) + return; + + if (path == null || realPath == null) + return; + + if (path.startsWith("http://") && !realPath.exists()) + downloadFile(); + + if (realPath == null || !realPath.exists()) + return; + + frames = ImageUtils.getFrames(realPath); + } + + private void downloadFile() + { + System.out.print("Going to download " + path + "..."); + + // Create an instance of HttpClient. + HttpClient client = new HttpClient(); + + // Create a method instance. + GetMethod method = new GetMethod(path); + + // Provide custom retry handler is necessary + // method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false)); + + try + { + // Execute the method. + int statusCode = client.executeMethod(method); + if (statusCode != HttpStatus.SC_OK) + throw new HttpException(); + + // Read the response body. + byte[] responseBody = method.getResponseBody(); + + realPath.getParentFile().mkdirs(); + + FileOutputStream out = new FileOutputStream(realPath, false); + out.write(responseBody); + + System.out.println("Done"); + } + catch (HttpException e) + { + System.out.println("Err"); + realPath = null; + } + catch (IOException e) + { + System.out.println("Err"); + realPath = null; + } + finally + { + // Release the connection. + method.releaseConnection(); + } + } + +} diff --git a/Plugins/emoticons/MepEditor/src/emoticons/ImageUtils.java b/Plugins/emoticons/MepEditor/src/emoticons/ImageUtils.java new file mode 100644 index 0000000..81527d1 --- /dev/null +++ b/Plugins/emoticons/MepEditor/src/emoticons/ImageUtils.java @@ -0,0 +1,78 @@ +package emoticons; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.graphics.Color; +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.widgets.Display; + +public class ImageUtils +{ + + public static Image[] getFrames(File file) + { + List frames = new ArrayList(); + + try + { + Color shellBackground = MepEditor.shell.getBackground(); + + ImageLoader loader = new ImageLoader(); + ImageData[] imageDataArray = loader.load(file.getCanonicalPath()); + if (imageDataArray.length == 1) + return new Image[] { new Image(Display.getCurrent(), imageDataArray[0]) }; + + Image fullGif = new Image(Display.getCurrent(), loader.logicalScreenWidth, loader.logicalScreenHeight); + GC fullGifGC = new GC(fullGif); + fullGifGC.setBackground(shellBackground); + fullGifGC.fillRectangle(0, 0, loader.logicalScreenWidth, loader.logicalScreenHeight); + + for (ImageData imageData : imageDataArray) + { + Image image = new Image(Display.getCurrent(), imageData); + fullGifGC.drawImage(image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, imageData.width, + imageData.height); + + Image frame = new Image(Display.getCurrent(), loader.logicalScreenWidth, loader.logicalScreenHeight); + GC frameGC = new GC(frame); + frameGC.drawImage(fullGif, 0, 0); + frameGC.dispose(); + frames.add(frame); + + switch (imageData.disposalMethod) + { + case SWT.DM_FILL_BACKGROUND: + Color bgColor = null; + if (loader.backgroundPixel != -1) + bgColor = new Color(Display.getCurrent(), imageData.palette.getRGB(loader.backgroundPixel)); + fullGifGC.setBackground(bgColor != null ? bgColor : shellBackground); + fullGifGC.fillRectangle(imageData.x, imageData.y, imageData.width, imageData.height); + if (bgColor != null) + bgColor.dispose(); + break; + } + } + + fullGifGC.dispose(); + fullGif.dispose(); + } + catch (SWTException e) + { + e.printStackTrace(); + } + catch (IOException e) + { + e.printStackTrace(); + } + + return frames.toArray(new Image[0]); + } + +} diff --git a/Plugins/emoticons/MepEditor/src/emoticons/Mep.java b/Plugins/emoticons/MepEditor/src/emoticons/Mep.java new file mode 100644 index 0000000..e058e0f --- /dev/null +++ b/Plugins/emoticons/MepEditor/src/emoticons/Mep.java @@ -0,0 +1,110 @@ +package emoticons; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class Mep +{ + public File path; + public String name = ""; + public String creator = ""; + public String udaterURL = ""; + public List emoticons; + public final List images = new ArrayList(); + + public Emoticon getEmoticon(String emoName, boolean create) + { + for (Emoticon emo : emoticons) + if (emo.name.equalsIgnoreCase(emoName)) + return emo; + + if (create) + { + Emoticon emo = new Emoticon(); + emo.name = emoName; + emo.icons.put(null, new EmoticonImage()); + emoticons.add(emo); + return emo; + } + + return null; + } + + public ImageFile getImage(String imgPath) + { + for (ImageFile img : images) + if (img.path.equalsIgnoreCase(imgPath)) + return img; + return null; + } + + public ImageFile createImage(String imgPath, String protocol) + { + return newImage(imgPath, protocol, true); + } + + public ImageFile createTemporaryImage(String imgPath, String protocol) + { + return newImage(imgPath, protocol, false); + } + + private ImageFile newImage(String imgPath, String protocol, boolean addToList) + { + String realPath = imgPath; + if (realPath.startsWith("http://")) + { + String p = realPath.substring(realPath.lastIndexOf('/') + 1); + if (protocol == null) + realPath = "cache\\" + p; + else + realPath = "cache\\" + protocol + "\\" + p; + } + File imgRealPath = new File(path, realPath); + + ImageFile image = null; + for (ImageFile img : images) + { + if (img.path.equalsIgnoreCase(imgPath)) + { + image = img; + break; + } + } + + if (image == null) + { + image = new ImageFile(imgPath, imgRealPath); + if (addToList) + images.add(image); + } + else + { + image.realPath = imgRealPath; + } + + return image; + } + + public void setEmoticonImage(String protocol, String name, ImageFile image) + { + Emoticon emo = getEmoticon(name, false); + if (emo == null) + return; + + if (protocol == null) + { + for (EmoticonImage icon : emo.icons.values()) + { + icon.image = image; + } + } + else + { + EmoticonImage icon = emo.icons.get(protocol); + if (icon == null) + return; + icon.image = image; + } + } +} diff --git a/Plugins/emoticons/MepEditor/src/emoticons/MepEditor.java b/Plugins/emoticons/MepEditor/src/emoticons/MepEditor.java new file mode 100644 index 0000000..6b9cfa5 --- /dev/null +++ b/Plugins/emoticons/MepEditor/src/emoticons/MepEditor.java @@ -0,0 +1,471 @@ +package emoticons; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +public class MepEditor +{ + private static MepFormat mepFormat; + private static Mep mep; + private static final List protocols = new ArrayList(); + static Shell shell; + private static ScrolledComposite emoticonsScroll; + private static Composite emoticonsComposite; + + private static boolean inGuiSetCommand; + + public static void main(String[] args) throws IOException + { + List emoticons = new ArrayList(); + new EmoFormat(emoticons, protocols).load(); + + Display display = new Display(); + shell = new Shell(display); + DirectoryDialog dialog = new DirectoryDialog(shell, SWT.NONE); + dialog.setText("Select folder with emoticon images"); + String path = dialog.open(); + if (path == null) + return; + // String path = "C:\\Desenvolvimento\\Miranda\\bin\\Debug Unicode\\Customize\\Emoticons\\Originals"; + File mepPath = new File(path); + if (!mepPath.exists()) + return; + + mepFormat = new MepFormat(mepPath, emoticons, protocols); + mep = mepFormat.load(); + + shell.setLayout(new FillLayout()); + + createMainWindow(shell); + + shell.setText("Emoticon Pack Editor"); + shell.setImage(new Image(Display.getCurrent(), "data/Defaults/smile.png")); + shell.setSize(500, 600); + shell.open(); + + while (!shell.isDisposed()) + { + if (!display.readAndDispatch()) + display.sleep(); + } + display.dispose(); + } + + static long time = System.nanoTime(); + + @SuppressWarnings("unused") + private static void profile(String text) + { + time = System.nanoTime() - time; + + System.out.println(text + " : " + (time / 1000000)); + + time = System.nanoTime(); + } + + private static void createMainWindow(Composite main) + { + main.setLayout(new GridLayout(1, true)); + + createToolbar(main); + createPackGroup(main); + createEmoticonsGroup(main, null); + } + + private static void createToolbar(Composite main) + { + Button save = new Button(main, SWT.PUSH); + save.setImage(new Image(Display.getCurrent(), "imgs/disk.png")); + save.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) + { + try + { + mepFormat.save(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + }); + } + + private static void createEmoticonsGroup(final Composite main, String protocol) + { + final Group group = new Group(main, SWT.NONE); + group.setLayoutData(new GridData(GridData.FILL_BOTH)); + group.setText("Emoticons"); + group.setLayout(new FillLayout()); + + emoticonsScroll = new ScrolledComposite(group, SWT.V_SCROLL); + emoticonsComposite = new Composite(emoticonsScroll, SWT.NONE); + emoticonsComposite.setLayout(new GridLayout(2, false)); + + createBoldLabel(emoticonsComposite, "Protocol:"); + createProtoCombo(emoticonsComposite, protocol, main, group); + + for (final Emoticon emo : mep.emoticons) + { + EmoticonImage icon = emo.icons.get(protocol); + if (icon == null) + continue; + + createEmoticonNameLabel(emoticonsComposite, emo); + + Composite attribs = new Composite(emoticonsComposite, SWT.NONE); + attribs.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + GridLayout gl = new GridLayout(2, false); + gl.marginWidth = 0; + attribs.setLayout(gl); + + createIconCombo(icon, attribs, emo, protocol); + createFramesHolder(emo, icon, attribs); + } + + emoticonsScroll.setContent(emoticonsComposite); + emoticonsScroll.setExpandHorizontal(true); + emoticonsScroll.setExpandVertical(true); + emoticonsScroll.addControlListener(new ControlAdapter() { + @Override + public void controlResized(ControlEvent e) + { + Rectangle r = emoticonsScroll.getClientArea(); + emoticonsScroll.setMinSize(emoticonsComposite.computeSize(r.width, SWT.DEFAULT)); + } + }); + + emoticonsComposite.pack(); + emoticonsScroll.setMinSize(emoticonsComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT, false)); + } + + private static void createEmoticonNameLabel(final Composite parent, final Emoticon emo) + { + Composite nameComposite = new Composite(parent, SWT.NONE); + nameComposite.setLayoutData(new GridData()); + nameComposite.setLayout(new GridLayout(2, false)); + + File defImage = new File("data/Defaults/" + emo.name + ".png"); + if (defImage.exists()) + { + try + { + Image image = new Image(Display.getCurrent(), defImage.getCanonicalPath()); + Label label = new Label(nameComposite, SWT.NONE); + label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + label.setImage(image); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + createBoldLabel(nameComposite, emo.name); + } + + private static void createProtoCombo(final Composite parent, String protocol, final Composite main, final Group group) + { + final Combo protoCombo = new Combo(parent, SWT.READ_ONLY); + protoCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + protoCombo.add("All protocols"); + for (String p : protocols) + protoCombo.add(p); + protoCombo.select(protocol == null ? 0 : protoCombo.indexOf(protocol)); + protoCombo.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event e) + { + runAllDelayedListeners(); + + String proto = protoCombo.getText(); + if (!protocols.contains(proto)) + proto = null; + + group.dispose(); + + createEmoticonsGroup(main, proto); + + shell.layout(); + } + }); + } + + private static void createIconCombo(final EmoticonImage icon, Composite parent, final Emoticon emo, final String protocol) + { + Label label = new Label(parent, SWT.NONE); + label.setText("Icon:"); + + final Combo combo = new Combo(parent, SWT.NONE); + combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + if (icon.image != null) + combo.setText(icon.image.path); + + combo.addListener(SWT.FocusIn, new Listener() { + public void handleEvent(Event event) + { + if (combo.getItemCount() > 0) + return; + + inGuiSetCommand = true; + + for (ImageFile file : mep.images) + combo.add(file.path); + + inGuiSetCommand = false; + } + }); + + DelayedListener listener = new DelayedListener(new Listener() { + public void handleEvent(Event e) + { + icon.image = mep.createTemporaryImage(combo.getText(), protocol); + fillFramesHolder(emo, icon); + } + }); + combo.addListener(SWT.Selection, listener.fast()); + combo.addListener(SWT.Modify, listener.delayed()); + } + + private static final Set delayedListeners = new HashSet(); + + private static void runAllDelayedListeners() + { + while (delayedListeners.size() > 0) + { + delayedListeners.iterator().next().run(); + } + } + + static class DelayedListener + { + private Event event; + private Listener listener; + private Color bkg; + private Runnable run = new Runnable() { + public void run() + { + DelayedListener.this.run(); + } + }; + + public DelayedListener(Listener listener) + { + this.listener = listener; + } + + private void run() + { + Display.getCurrent().timerExec(-1, run); + delayedListeners.remove(this); + ((Control) event.widget).setBackground(bkg); + listener.handleEvent(event); + } + + private void start(Event e) + { + event = e; + + if (bkg == null) + bkg = ((Control) e.widget).getBackground(); + ((Control) e.widget).setBackground(new Color(Display.getCurrent(), 255, 255, 200)); + + delayedListeners.add(this); + Display.getCurrent().timerExec(-1, run); + Display.getCurrent().timerExec(3000, run); + } + + public Listener delayed() + { + return new Listener() { + public void handleEvent(Event e) + { + if (inGuiSetCommand) + return; + + start(e); + } + }; + } + + public Listener fast() + { + return new Listener() { + public void handleEvent(Event e) + { + if (inGuiSetCommand) + return; + + event = e; + run(); + } + }; + } + }; + + private static void fillFramesHolder(final Emoticon emo, final EmoticonImage icon) + { + Display.getCurrent().asyncExec(new Runnable() { + public void run() + { + disposeAllChildren(emo.frames); + + if (icon.image == null) + return; + + icon.image.loadFrames(); + if (icon.image.frames == null) + return; + + Listener listener = new Listener() { + public void handleEvent(Event e) + { + Button button = (Button) e.widget; + + Control[] children = emo.frames.getChildren(); + for (int i = 0; i < children.length; i++) + { + Control child = children[i]; + if (e.widget != child && child instanceof Button && (child.getStyle() & SWT.TOGGLE) != 0) + { + ((Button) child).setSelection(false); + } + else if (child == button) + { + icon.image.frame = i; + } + } + button.setSelection(true); + } + }; + + Image[] frames = icon.image.frames; + for (int j = 0; j < frames.length; j++) + { + Button button = new Button(emo.frames, SWT.TOGGLE); + button.setImage(frames[j]); + if (j == icon.image.frame) + button.setSelection(true); + button.addListener(SWT.Selection, listener); + } + + emo.frames.layout(); + emoticonsComposite.pack(); + Rectangle r = emoticonsScroll.getClientArea(); + emoticonsScroll.setMinSize(emoticonsComposite.computeSize(r.width, SWT.DEFAULT)); + } + }); + } + + private static void disposeAllChildren(final Composite composite) + { + Control[] children = composite.getChildren(); + for (int i = 0; i < children.length; i++) + children[i].dispose(); + } + + private static void createFramesHolder(Emoticon emo, EmoticonImage icon, Composite parent) + { + Label label = new Label(parent, SWT.NONE); + label.setText("Frame:"); + + emo.frames = new Composite(parent, SWT.NONE); + emo.frames.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + RowLayout rowLayout = new RowLayout(SWT.HORIZONTAL); + rowLayout.wrap = true; + emo.frames.setLayout(rowLayout); + + fillFramesHolder(emo, icon); + } + + private static void createPackGroup(Composite main) + { + Group group = new Group(main, SWT.NONE); + group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + group.setText("Pack"); + group.setLayout(new GridLayout(2, false)); + + createBoldLabel(group, "Name:"); + Text text = new Text(group, SWT.BORDER); + text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + text.setText(mep.name); + text.addListener(SWT.Modify, new Listener() { + public void handleEvent(Event e) + { + mep.name = ((Text) e.widget).getText(); + } + }); + + createBoldLabel(group, "Creator:"); + text = new Text(group, SWT.BORDER); + text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + text.setText(mep.creator); + text.addListener(SWT.Modify, new Listener() { + public void handleEvent(Event e) + { + mep.creator = ((Text) e.widget).getText(); + } + }); + + createBoldLabel(group, "Updater URL:"); + text = new Text(group, SWT.BORDER); + text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + text.setText(mep.udaterURL); + text.addListener(SWT.Modify, new Listener() { + public void handleEvent(Event e) + { + mep.udaterURL = ((Text) e.widget).getText(); + } + }); + + } + + private static void createBoldLabel(Composite parent, String text) + { + Label label = new Label(parent, SWT.NONE); + label.setLayoutData(new GridData()); + label.setText(text); + setBoldFont(label); + } + + private static void setBoldFont(Label name) + { + Font initialFont = name.getFont(); + FontData[] fontData = initialFont.getFontData(); + for (int i = 0; i < fontData.length; i++) + fontData[i].setStyle(SWT.BOLD); + Font newFont = new Font(Display.getCurrent(), fontData); + name.setFont(newFont); + } + +} diff --git a/Plugins/emoticons/MepEditor/src/emoticons/MepFormat.java b/Plugins/emoticons/MepEditor/src/emoticons/MepFormat.java new file mode 100644 index 0000000..1b96c63 --- /dev/null +++ b/Plugins/emoticons/MepEditor/src/emoticons/MepFormat.java @@ -0,0 +1,256 @@ +package emoticons; + +import static java.lang.Math.max; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.List; + +public class MepFormat +{ + private Mep mep; + private final List protocols; + + public MepFormat(File path, List emoticons, List protocols) + { + mep = new Mep(); + mep.path = path; + mep.name = path.getName(); + mep.emoticons = emoticons; + this.protocols = protocols; + } + + public Mep load() throws IOException + { + addImages(mep.path, null); + + for (String protocol : protocols) + { + File path = new File(mep.path, protocol); + if (!path.exists()) + continue; + addImages(path, protocol); + } + + File mepFile = new File(mep.path, mep.path.getName() + ".mep"); + if (mepFile.exists()) + { + BufferedReader in = new BufferedReader(new FileReader(mepFile)); + String line; + while ((line = in.readLine()) != null) + { + line = line.trim(); + if (line.startsWith("#")) + { + continue; + } + else if (line.length() < 2) + { + continue; + } + else if (startsWithIgnoreCase(line, "Name:")) + { + mep.name = line.substring(5).trim(); + } + else if (startsWithIgnoreCase(line, "Creator:")) + { + mep.creator = line.substring(8).trim(); + } + else if (startsWithIgnoreCase(line, "Updater URL:")) + { + mep.udaterURL = line.substring(12).trim(); + } + else if (line.startsWith("\"")) + { + handleMepLine(line); + } + } + } + + return mep; + } + + private boolean startsWithIgnoreCase(String line, String txt) + { + return line.length() > txt.length() && line.substring(0, txt.length()).compareToIgnoreCase(txt) == 0; + } + + private void handleMepLine(String line) + { + int len = line.length(); + int state = 0; + int pos = 0; + int module_pos = -1; + boolean noDelimiter = false; + + ImageFile img = null; + String name = null; + String protocol = null; + + for (int i = 0; i <= len && state < 6; i++) + { + char c = (i == len ? '\0' : line.charAt(i)); + if (c == ' ') + continue; + + if ((state % 2) == 0) + { + if (c == '"') + { + state++; + pos = i + 1; + noDelimiter = false; + } + else if (c != '=' && c != ',' && c != ' ' && c != '\t' && c != '\r' && c != '\n') + { + state++; + pos = i; + noDelimiter = true; + } + else + { + continue; + } + } + else + { + if (state == 1 && c == '\\') // Module name + module_pos = i; + + if (noDelimiter) + { + if (c != ' ' && c != ',' && c != '=' && c != '\0') + continue; + } + else + { + if (c != '"') + continue; + } + + String module; + String txt; + + if (state == 1 && module_pos >= 0) + { + module = line.substring(pos, module_pos); + txt = line.substring(module_pos + 1, i); + } + else + { + module = null; + txt = line.substring(pos, i); + } + + // Found something + switch (state) + { + case 1: + { + name = txt; + protocol = module; + break; + } + case 3: + { + if (isInvalidExension(new File(txt))) + return; + + img = mep.createImage(txt, protocol); + mep.setEmoticonImage(protocol, name, img); + + break; + } + case 5: + { + img.frame = max(0, Integer.parseInt(txt) - 1); + break; + } + } + + state++; + } + } + } + + private void addImages(File path, String protocol) + { + for (File file : path.listFiles()) + { + if (isInvalidExension(file)) + continue; + + String imagePath = (protocol == null ? "" : protocol + "\\") + file.getName(); + ImageFile image = mep.createImage(imagePath, protocol); + + String name = removeExtension(file.getName()); + mep.setEmoticonImage(protocol, name, image); + } + } + + private String removeExtension(String name) + { + return name.substring(0, name.lastIndexOf('.')); + } + + public static boolean isInvalidExension(File file) + { + return !file.getName().endsWith(".jpg") && !file.getName().endsWith(".jpeg") && !file.getName().endsWith(".png") + && !file.getName().endsWith(".gif") && !file.getName().endsWith(".swf"); + } + + public void save() throws IOException + { + mep.path.mkdirs(); + FileWriter out = new FileWriter(new File(mep.path, mep.path.getName() + ".mep")); + + if (!mep.name.isEmpty() && !mep.name.equals(mep.path.getName())) + out.write("Name: " + mep.name + "\r\n"); + if (!mep.creator.isEmpty()) + out.write("Creator: " + mep.creator + "\r\n"); + if (!mep.udaterURL.isEmpty()) + out.write("Updater URL: " + mep.udaterURL + "\r\n"); + + out.write("\r\n"); + + writeEmoticonsForProtocol(out, null); + for (String protocol : protocols) + writeEmoticonsForProtocol(out, protocol); + + out.close(); + } + + private void writeEmoticonsForProtocol(FileWriter out, String protocol) throws IOException + { + StringBuilder sb = new StringBuilder(); + fillBuffer(sb, protocol); + String txt = sb.toString(); + if (txt.isEmpty()) + return; + out.write("# " + (protocol == null ? "Global" : protocol) + "\r\n"); + out.write(txt); + out.write("\r\n"); + } + + private void fillBuffer(StringBuilder out, String protocol) throws IOException + { + for (Emoticon emo : mep.emoticons) + { + EmoticonImage image = emo.icons.get(protocol); + if (image == null || image.image == null) + continue; + String protoPrefix = (protocol == null ? "" : protocol + "\\"); + String pathWithoutExtension = removeExtension(image.image.path); + if (image.image.frame == 0 && pathWithoutExtension.equalsIgnoreCase(protoPrefix + emo.name)) + continue; + + out.append("\"" + protoPrefix + emo.name + "\" = \"" + image.image.path + "\""); + if (image.image.frame != 0) + out.append(", " + (image.image.frame + 1)); + out.append("\r\n"); + } + } +} -- cgit v1.2.3