View Javadoc

1   /*
2    * Created on 13 avr. 2005
3    * 
4    *   Firemox is a turn based strategy simulator
5    *   Copyright (C) 2003-2007 Fabrice Daugan
6    *
7    *   This program is free software; you can redistribute it and/or modify it 
8    * under the terms of the GNU General Public License as published by the Free 
9    * Software Foundation; either version 2 of the License, or (at your option) any
10   * later version.
11   *
12   *   This program is distributed in the hope that it will be useful, but WITHOUT 
13   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14   * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
15   * details.
16   *
17   *   You should have received a copy of the GNU General Public License along  
18   * with this program; if not, write to the Free Software Foundation, Inc., 
19   * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20   */
21  package net.sf.firemox.ui.component;
22  
23  import java.awt.Color;
24  import java.awt.Cursor;
25  import java.awt.LayoutManager;
26  import java.awt.event.MouseEvent;
27  import java.awt.event.MouseListener;
28  import java.awt.event.MouseMotionListener;
29  import java.util.HashMap;
30  import java.util.Map;
31  import java.util.TreeMap;
32  import java.util.Vector;
33  import java.util.Map.Entry;
34  
35  import javax.swing.text.BadLocationException;
36  import javax.swing.text.StyleConstants;
37  
38  import net.sf.firemox.tools.WebBrowser;
39  import net.sf.firemox.ui.UIHelper;
40  
41  /***
42   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
43   * @since 0.83
44   */
45  public class ChatArea extends EditorPane implements MouseListener,
46  		MouseMotionListener {
47  
48  	/***
49  	 * Path containing the smiles.
50  	 */
51  	private final static String FILE_ICON_PATH = "smilies/";
52  
53  	/***
54  	 * Create a new instance of this class.
55  	 * 
56  	 * @param layout
57  	 *          the specified layout manager
58  	 */
59  	public ChatArea(LayoutManager layout) {
60  		setLayout(layout);
61  		// Load style TODO Load these settings from a .properties file
62  		color = Color.BLACK;
63  		bold = false;
64  		italic = false;
65  		strikeThrough = false;
66  		StyleConstants.setForeground(style, color);
67  		StyleConstants.setFontSize(style, 12);
68  		StyleConstants.setBold(style, false);
69  		StyleConstants.setItalic(style, false);
70  		StyleConstants.setStrikeThrough(style, false);
71  		fEmoticonMap = new HashMap<String, String>();
72  		fEmoticonMap.put("(CHILL)", "chilled.gif");
73  		fEmoticonMap.put("(CHILLED)", "chilled.gif");
74  		fEmoticonMap.put("(CRAZY)", "crazy.gif");
75  		fEmoticonMap.put("%)", "crazy.gif");
76  		fEmoticonMap.put("%-)", "crazy.gif");
77  		fEmoticonMap.put("(G)", "google.gif");
78  		fEmoticonMap.put("(GOOGLE)", "google.gif");
79  		fEmoticonMap.put("O)", "google.gif");
80  		fEmoticonMap.put("0)", "google.gif");
81  		fEmoticonMap.put("(H)", "huh.gif");
82  		fEmoticonMap.put(":?", "rolleyes.gif");
83  		fEmoticonMap.put("(ROLL)", "rolleyes.gif");
84  		fEmoticonMap.put("8|", "what.gif");
85  		fEmoticonMap.put("8-|", "what.gif");
86  		fEmoticonMap.put(":|", "what.gif");
87  		fEmoticonMap.put(":-|", "what.gif");
88  		fEmoticonMap.put(":@", "worried.gif");
89  		fEmoticonMap.put(":-@", "worried.gif");
90  		fEmoticonMap.put(":P", "tongue.gif");
91  		fEmoticonMap.put(":-P", "tongue.gif");
92  		fEmoticonMap.put("(BLIND)", "blind.gif");
93  		fEmoticonMap.put("(WOW)", "ninja.gif");
94  		fEmoticonMap.put(":D", "wow.gif");
95  		fEmoticonMap.put(":-D", "wow.gif");
96  		fEmoticonMap.put("(NINJA)", "ninja.gif");
97  		fEmoticonMap.put("(CONF)", "confused.gif");
98  		fEmoticonMap.put(":S", "confused.gif");
99  		fEmoticonMap.put(":-S", "confused.gif");
100 		fEmoticonMap.put("(6)", "evil.gif");
101 		fEmoticonMap.put(":-)", "smile.gif");
102 		fEmoticonMap.put(":)", "smile.gif");
103 		fEmoticonMap.put(";)", "wink.gif");
104 		fEmoticonMap.put(";-)", "wink.gif");
105 		fEmoticonMap.put("(X)", "love.gif");
106 		fEmoticonMap.put(":O", "ohhmy.gif");
107 		fEmoticonMap.put(":-O", "ohhmy.gif");
108 		fEmoticonMap.put(":(", "cry.gif");
109 		fEmoticonMap.put(":-(", "cry.gif");
110 		fEmoticonMap.put(":'(", "cry.gif");
111 		fEmoticonMap.put(":'-(", "cry.gif");
112 		fEmoticonMap.put("(L)", "love.gif");
113 		fEmoticonMap.put("(ICOOL)", "cool.gif");
114 		fEmoticonMap.put("(COOL)", "cool.gif");
115 		fEmoticonMap.put("(LUV)", "love.gif");
116 		fEmoticonMap.put("(LOVE)", "love.gif");
117 	}
118 
119 	@Override
120 	public void append(int id, String text) {
121 		super.append(id, text);
122 		StyleConstants.setBold(style, bold);
123 		StyleConstants.setForeground(style, color);
124 		StyleConstants.setFontSize(style, 12);
125 		StyleConstants.setItalic(style, italic);
126 		StyleConstants.setStrikeThrough(style, strikeThrough);
127 		final Map<Integer, String> smiles = getSmiliesIndex(text);
128 		int currentIndex = 0;
129 		try {
130 			for (Entry<Integer, String> entry : smiles.entrySet()) {
131 				final int index = entry.getKey();
132 				getDocument().insertString(getDocument().getLength(),
133 						text.substring(currentIndex, index), style);
134 				insertIcon(UIHelper.getIcon(FILE_ICON_PATH
135 						+ fEmoticonMap.get(entry.getValue())));
136 				currentIndex = index + entry.getValue().length();
137 			}
138 			getDocument().insertString(getDocument().getLength(),
139 					text.substring(currentIndex), style);
140 			// replaceURL(d1);
141 		} catch (BadLocationException e) {
142 			e.printStackTrace();
143 		}
144 
145 		if (!locked) {
146 			setCaretPosition(getDocument().getLength());
147 		}
148 	}
149 
150 	/***
151 	 * Return a map linking indexes of smiles into the given message.
152 	 * 
153 	 * @param msg
154 	 *          the message that contain the smiles shortcuts.
155 	 * @return a map linking indexes of smiles into the given message.
156 	 */
157 	private Map<Integer, String> getSmiliesIndex(String msg) {
158 		final Map<Integer, String> result = new TreeMap<Integer, String>();
159 		for (Map.Entry<String, String> entry : fEmoticonMap.entrySet()) {
160 			final String key = entry.getKey();
161 			int index = msg.indexOf(key);
162 			while (index != -1) {
163 				result.put(index, key);
164 				index = msg.indexOf(key, index + 1);
165 			}
166 		}
167 		return result;
168 	}
169 
170 	public void mouseClicked(MouseEvent e) {
171 		int idx = viewToModel(e.getPoint());
172 		for (int i = 0; i < startIndex.size(); i++) {
173 			int sp = startIndex.elementAt(i);
174 			int ep = endIndex.elementAt(i);
175 			if (idx >= sp & idx <= ep) {
176 				String url = linkURL.elementAt(i);
177 				try {
178 					WebBrowser.launchBrowser(url);
179 				} catch (Exception e1) {
180 					// Ignore this error
181 				}
182 				break;
183 			}
184 		}
185 	}
186 
187 	public void mouseMoved(MouseEvent e) {
188 		int idx = viewToModel(e.getPoint());
189 		int a = 0;
190 		for (int i = 0; i < startIndex.size(); i++) {
191 			int sp = startIndex.elementAt(i);
192 			int ep = endIndex.elementAt(i);
193 			if (idx >= sp & idx <= ep) {
194 				setCursor(new Cursor(Cursor.HAND_CURSOR));
195 				a++;
196 				break;
197 			}
198 		}
199 		if (a == 0) {
200 			setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
201 		}
202 	}
203 
204 	public void mouseDragged(MouseEvent arg0) {
205 		// TODO D&D in chat --> not yet implemented
206 	}
207 
208 	public void mousePressed(MouseEvent e) {
209 		// Ignore this event
210 	}
211 
212 	public void mouseReleased(MouseEvent e) {
213 		// Ignore this event
214 	}
215 
216 	public void mouseEntered(MouseEvent e) {
217 		// Ignore this event
218 	}
219 
220 	public void mouseExited(MouseEvent e) {
221 		// Ignore this event
222 	}
223 
224 	Color color;
225 
226 	boolean italic;
227 
228 	boolean strikeThrough;
229 
230 	boolean underLine;
231 
232 	boolean bold;
233 
234 	private Map<String, String> fEmoticonMap = null;
235 
236 	private Vector<Integer> startIndex = new Vector<Integer>();
237 
238 	private Vector<Integer> endIndex = new Vector<Integer>();
239 
240 	private Vector<String> linkURL = new Vector<String>();
241 
242 }