001 /* 002 Copyright (C) 2003 Adam Olsen 003 This program is free software; you can redistribute it and/or modify 004 it under the terms of the GNU General Public License as published by 005 the Free Software Foundation; either version 1, or (at your option) 006 any later version. 007 This program is distributed in the hope that it will be useful, 008 but WITHOUT ANY WARRANTY; without even the implied warranty of 009 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 010 GNU General Public License for more details. 011 You should have received a copy of the GNU General Public License 012 along with this program; if not, write to the Free Software 013 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 014 */ 015 package com.valhalla.jbother; 016 017 import java.io.*; 018 import java.net.URL; 019 import java.util.*; 020 import javax.swing.*; 021 import java.awt.*; 022 import java.awt.event.*; 023 import javax.swing.event.*; 024 025 import com.valhalla.gui.*; 026 import com.valhalla.settings.*; 027 028 /** 029 * Replaces different emote symbols with images 030 * 031 * @author Adam Olsen 032 * @created October 30, 2004 033 * @version 1.0 034 */ 035 public class Emoticons 036 { 037 private String imageDir; 038 private static Emoticons instance; 039 private Properties map; 040 041 private String themeDir; 042 private InputStream emoticonStream; 043 private boolean switched = false; 044 045 /** 046 * Default constructor - opens the emoticon theme dir and reads in the 047 * data file containing the different emote definitions 048 */ 049 private Emoticons() { } 050 051 /** 052 * @return the Emoticons singleton 053 */ 054 public static Emoticons getInstance() 055 { 056 if( instance == null ) 057 { 058 instance = new Emoticons(); 059 } 060 if( !instance.switched ) 061 { 062 instance.switchTheme( Settings.getInstance().getProperty( "emoticonTheme" ) ); 063 } 064 return instance; 065 } 066 067 /** 068 * Switches the emoticon theme 069 * 070 * @param theme the theme to switch to 071 */ 072 public void switchTheme( String theme ) 073 { 074 switched = true; 075 076 map = new Properties(); 077 078 themeDir = theme; 079 if( themeDir == null ) 080 { 081 themeDir = "default"; 082 } 083 084 emoticonStream = getClass().getClassLoader().getResourceAsStream( "imagethemes/emoticons/" + themeDir + '/' + "index.dat" ); 085 086 if( emoticonStream == null ) 087 { 088 com.valhalla.Logger.debug( "Bad Emoticon File" ); 089 return; 090 } 091 092 InputStreamReader in = new InputStreamReader( emoticonStream ); 093 BufferedReader reader = new BufferedReader( in ); 094 095 String line; 096 String nameValue[] = new String[2]; 097 098 try 099 { 100 101 while( ( line = reader.readLine() ) != null ) 102 { 103 nameValue = line.split( " " ); 104 if( nameValue[0] == null || nameValue[1] == null ) 105 { 106 break; 107 } 108 109 map.setProperty( nameValue[0], nameValue[1] ); 110 } 111 112 in.close(); 113 // close the file 114 } 115 catch( IOException e ) 116 { 117 com.valhalla.Logger.debug( "Couldn't read emoticon file." ); 118 } 119 } 120 121 /** 122 * Replaces the different symbols with the images defined in the emote data file 123 * 124 * @param text the text to modify 125 * @return the modified text 126 */ 127 public String replaceIcons( String text ) 128 { 129 if( emoticonStream == null ) 130 { 131 return text; 132 } 133 134 Iterator iterator = map.keySet().iterator(); 135 136 while( iterator.hasNext() ) 137 { 138 String symbol = (String)iterator.next(); 139 140 symbol = symbol.replaceAll( "<", "<" ); 141 symbol = symbol.replaceAll( ">", ">" ); 142 143 String image = map.getProperty( symbol ); 144 String imageLocation = "imagethemes/emoticons/" + themeDir + "/" + image; 145 146 int loc = -5; 147 148 while( ( loc = text.indexOf( " " + symbol + " " ) ) != -1 ) 149 { 150 String icon = appendIcon( imageLocation ); 151 text = text.substring( 0, loc ) + icon + text.substring( loc + symbol.length() + 1 ); 152 } 153 } 154 155 return text; 156 } 157 158 /** 159 * Appends an image tag onto a StringBuffer 160 * 161 * @param imageLocation the location of the image 162 * @return the string with the appended icon 163 */ 164 private String appendIcon( String imageLocation ) 165 { 166 URL imageUrl = getClass().getClassLoader().getResource( imageLocation ); 167 168 if( imageUrl == null ) 169 { 170 com.valhalla.Logger.debug( "No emoticon image found for " + imageLocation ); 171 return ""; 172 } 173 174 ImageIcon iconTest = new ImageIcon( imageUrl ); 175 int width = iconTest.getIconWidth(); 176 int height = iconTest.getIconHeight(); 177 178 return " <img border='0' width='" + width + "' height='" + 179 height + "' src='" + imageUrl + "'> "; 180 } 181 182 /** 183 * Shows a small window displaying all available emoticons. 184 * 185 * @param window the parent window 186 * @param component the Component to display this frame over 187 * @param area the text area that the emoticons will be placed on when the user clicks an image 188 */ 189 public void displayEmoticonChooser( JFrame window, Component component, JTextArea area ) 190 { 191 JDialog dialog = new JDialog( window ); 192 JPanel panel = (JPanel)dialog.getContentPane(); 193 panel.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) ); 194 panel.setLayout( new BoxLayout( panel, BoxLayout.Y_AXIS ) ); 195 EmoteClickListener listener = new EmoteClickListener( dialog, area ); 196 197 int columns = 6; 198 int current = 0; 199 JPanel cPanel = null; 200 201 Iterator i = map.keySet().iterator(); 202 203 Properties displayed = new Properties(); 204 while( i.hasNext() ) 205 { 206 String symbol = (String)i.next(); 207 208 if( symbol.equals( "(-)(-)" ) ) 209 { 210 continue; 211 } 212 213 String image = map.getProperty( symbol ); 214 215 if( displayed.getProperty( image ) != null ) continue; 216 displayed.setProperty( image, "True" ); 217 218 String imageLocation = "imagethemes/emoticons/" + themeDir + "/" + image; 219 ImageIcon icon = Standard.getIcon( imageLocation ); 220 if( icon == null ) 221 { 222 continue; 223 } 224 225 if( current > columns ) 226 { 227 panel.add( cPanel ); 228 current = 0; 229 } 230 231 if( current == 0 ) 232 { 233 cPanel = new JPanel(); 234 cPanel.setLayout( new BoxLayout( cPanel, BoxLayout.X_AXIS ) ); 235 } 236 237 JLabel label = new JLabel( icon ); 238 label.setName( symbol ); 239 label.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) ); 240 label.addMouseListener( listener ); 241 if( icon != null ) 242 { 243 cPanel.add( label ); 244 } 245 current++; 246 } 247 248 dialog.pack(); 249 dialog.setLocationRelativeTo( component ); 250 dialog.setVisible( true ); 251 dialog.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE ); 252 } 253 254 /** 255 * Listens for an emoticon to get clicked 256 * 257 * @author synic 258 * @created October 30, 2004 259 */ 260 class EmoteClickListener extends MouseAdapter 261 { 262 JDialog dialog; 263 JTextArea area; 264 265 /** 266 *Constructor for the EmoteClickListener object 267 * 268 * @param dialog the emote dialog that called this listener 269 * @param area the textarea to append the emote symbol to 270 */ 271 public EmoteClickListener( JDialog dialog, JTextArea area ) 272 { 273 this.dialog = dialog; 274 this.area = area; 275 } 276 277 /** 278 * Called by the mouse listener 279 * 280 * @param e the mouse event 281 */ 282 public void mouseReleased( MouseEvent e ) 283 { 284 dialog.dispose(); 285 JLabel label = (JLabel)e.getSource(); 286 String symbol = label.getName(); 287 area.setText( area.getText() + symbol + " " ); 288 area.grabFocus(); 289 } 290 } 291 } 292