/*
* Gamers Own Instant Messenger
* Copyright (C) 2005-2006 Herbert Poul (kahless@sphene.net)
* http://goim.sphene.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package net.sphene.goim.rcp.ui;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import net.sphene.goim.rcp.GOIMPlugin;
import net.sphene.goim.rcp.beans.GOIMAccount;
import net.sphene.goim.rcp.extensionpoints.IChatGUI;
import net.sphene.goim.rcp.extensionpoints.IconSetExtensionPoint;
import net.sphene.goim.rcp.extensionpoints.IconSetExtensionPoint.IconSetExtension;
import net.sphene.goim.rcp.extensionpoints.IconSetExtensionPoint.IconSetExtension.IconDef;
import net.sphene.goim.rcp.history.HistoryViewer;
import net.sphene.goim.rcp.preferences.PreferenceConstants;
import net.sphene.goim.rcp.ui.ChatBrowserGUI.Word.WordType;
import net.sphene.goim.rcp.ui.ContactList.EntryMenu;
import net.sphene.goim.rcp.ui.chat.GOIMChatObject;
import net.sphene.goim.rcp.xmpp.StatusChangedEvent;
import net.sphene.libs.SpheneEvent;
import net.sphene.libs.SpheneListener;
import net.sphene.libs.SpheneListenerList;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.LocationEvent;
import org.eclipse.swt.custom.PaintObjectEvent;
import org.eclipse.swt.custom.PaintObjectListener;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.GlyphMetrics;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
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.widgets.Composite;
import org.eclipse.swt.widgets.CoolBar;
import org.eclipse.swt.widgets.CoolItem;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.FormText;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterListener;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.MessageEventManager;
import org.jivesoftware.smackx.XHTMLManager;
import org.jivesoftware.smackx.packet.DelayInformation;
import org.jivesoftware.smackx.packet.MessageEvent;
import org.osgi.framework.Bundle;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class ChatBrowserGUI extends Composite implements IChatGUI {
public static SimpleDateFormat historyDateFormat = new SimpleDateFormat(
"[HH:mm:ss]");
SashForm sashForm = null;
private Browser chatHistory = null;
private StyledText chatInput = null;
protected GOIMAccount account;
private GOIMChatObject chat;
public GOIMChatObject getChat() {
return chat;
}
private Composite topComposite;
private Composite bottomComposite;
private RosterListener rosterListener;
public static final String EVENT_PARAM_ALREADYHANDLED = "alreadyhandled";
public SpheneListenerList<SpheneEvent, SpheneListener<SpheneEvent>> changeListener = new SpheneListenerList<SpheneEvent, SpheneListener<SpheneEvent>>();
protected Composite chatParticipantStatus = null;
IconSetExtension emoticons;
protected Listener focusInListener;
protected Label statusLabel;
private MessageEvent lastMessageEventRequest;
private Message lastReceivedMessage;
private boolean sentComposing;
private ScrolledForm historyForm;
private FormToolkit tk;
protected String selectedUser;
protected ToolItem toolItemHistory;
protected ToolItem toolItemVCard;
ConnectionListener connectionListener;
private StyledText styledTextHistory;
static MessageEvent messageEvent = new MessageEvent();
public ChatBrowserGUI(Composite parent, int style) {
super(parent, style);
emoticons = IconSetExtensionPoint
.getActiveIconSet(IconSetExtensionPoint.ICONSET_TYPE_EMOTICONS);
GOIMPlugin.getDefault().getMyPreferenceStore()
.addPropertyChangeListener(new IPropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
if (event.getProperty().equals(
PreferenceConstants.P_EMOTICONSET)) {
emoticons = IconSetExtensionPoint
.getActiveIconSet(IconSetExtensionPoint.ICONSET_TYPE_EMOTICONS);
}
}
});
focusInListener = new Listener() {
public void handleEvent(Event event) {
System.out.println(event.widget.toString()
+ ".FocusIn ... forwarding focus to chatInput");
if (!chatInput.setFocus())
System.out.println("setFocus returned false ?!");
}
};
try {
initialize();
myInit();
} catch (SWTError error) {
ErrorDialog.openError(this.getShell(),
"Error while opening Chat Window",
"Could not open Chat Window " + error.toString(),
new Status(Status.ERROR, GOIMPlugin.ID, Status.OK,
"Error while opening Chat Window", error));
}
}
protected void myInit() {
if (chatHistory != null) {
Bundle bundle = Platform.getBundle(GOIMPlugin.ID);
URL css = FileLocator.find(bundle, new Path(
"libs/chatbrowser/history.css"),null);
StringBuffer html = new StringBuffer(
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">")
.append("<html><head><style type=\"text/css\"><!--\n");
try {
InputStream in = css.openStream();
byte[] buf = new byte[1024];
int read;
while ((read = in.read(buf)) > 0) {
html.append(new String(buf, 0, read));
}
} catch (IOException e) {
e.printStackTrace();
}
html.append("\n//--></style>");
html.append("</head><body>").append(
"<div class=\"chathistory\" id=\"chathistory\">")
// .append("<p><span class=\"date\">date span</span>")
// .append("<span class=\"from\">someone@somewhere</span>")
// .append("<span class=\"message\">Just some message
// here</span></p>")
.append("</div>")
.append("</body></html>");
chatHistory.setText(html.toString());
}
}
protected void createBottomComposite() {
bottomComposite = new Composite(sashForm, SWT.NULL);
statusLabel = new Label(bottomComposite, SWT.NULL);
statusLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
false));
createButtonComposite();
createChatInput();
bottomComposite.setLayout(new GridLayout(2,false));
}
protected void createChatGUI(Composite parent) {
sashForm = new SashForm(parent, SWT.VERTICAL);
topComposite = new Composite(sashForm, SWT.NULL);
GridLayout topCompositeLayout = new GridLayout();
topCompositeLayout.marginHeight = 0;
topComposite.setLayout(topCompositeLayout);
createChatParticipantStatus();
createChatHistory();
createBottomComposite();
sashForm.setWeights(new int[] { 70, 30 });
}
protected void createChatInput() {
GridData gridData2 = new org.eclipse.swt.layout.GridData();
gridData2.grabExcessHorizontalSpace = true;
gridData2.grabExcessVerticalSpace = true;
gridData2.heightHint = 40;
gridData2.horizontalAlignment = org.eclipse.swt.layout.GridData.FILL;
gridData2.horizontalSpan = 2;
gridData2.verticalAlignment = org.eclipse.swt.layout.GridData.FILL;
gridData2.minimumHeight = 10;
gridData2.minimumWidth = 50;
chatInput = new StyledText(bottomComposite, SWT.BORDER | SWT.V_SCROLL);
chatInput.setLayoutData(gridData2);
chatInput.addListener(SWT.Verify,new Listener() {
public void handleEvent(Event e) {
if((e.text.equals("\r\n") || e.text.equals("\n") || e.text.equals("\r")) &&
(e.stateMask & SWT.ALT) == 0 &&
(e.stateMask & SWT.SHIFT) == 0) {
sendUserInput();
chatInput.setFocus();
e.doit = false;
}
}
});
chatInput.addKeyListener(new org.eclipse.swt.events.KeyAdapter() {
public void keyPressed(org.eclipse.swt.events.KeyEvent e) {
if ((e.stateMask & SWT.ALT) != 0 && e.keyCode == 's') {
sendUserInput();
} else if (lastReceivedMessage != null
&& lastMessageEventRequest != null
&& lastMessageEventRequest.isComposing()) {
if (chatInput.getText().equals("")) {
if (sentComposing) {
sentComposing = false;
Message reply = new Message(lastReceivedMessage
.getFrom());
MessageEvent replyEvent = new MessageEvent();
replyEvent.setPacketID(lastReceivedMessage
.getPacketID());
replyEvent.setComposing(false);
reply.addExtension(replyEvent);
account.xmpp.getConnection().sendPacket(reply);
}
} else {
if (!sentComposing) {
sentComposing = true;
Message reply = new Message(lastReceivedMessage
.getFrom());
MessageEvent replyEvent = new MessageEvent();
replyEvent.setPacketID(lastReceivedMessage
.getPacketID());
replyEvent.setComposing(true);
reply.addExtension(replyEvent);
account.xmpp.getConnection().sendPacket(reply);
}
}
} else if ((e.stateMask & SWT.CONTROL) != 0 && e.keyCode == 'b') {
makeInputSelectionBold();
} else if ((e.stateMask & SWT.CONTROL) != 0 && e.keyCode == 'u') {
makeInputSelectionUnderlined();
}
}
});
}
protected void initialize() {
this.setLayout(new FillLayout());
createChatGUI(this);
setSize(new Point(400, 200));
this.layout(true);
//this.getParent().layout(true);
}
protected static class Word {
public static enum WordType {
URL (Pattern.compile("\\w+://(\\S+.)+(?=[.\\s\\)$])")),
JID (Pattern.compile("[\\p{Graph}&&[^<>]]+?@[\\p{Graph}&&[^<>]]+"))
;
private final Pattern pattern;
WordType(Pattern pattern) {
this.pattern = pattern;
}
public Pattern pattern() {
return pattern;
}
}
/*
public static Pattern WORDTYPE_URL_PATTERN = Pattern.compile("\\w+://(\\S+.)+(?=[.\\s\\)$])");
//public static Pattern WORDTYPE_JID_MATCHER = Pattern.compile("[\\x021\\x023-\\x025\\x028-\\x02E\\x030-\\x039\\x03B\\x03D\\x03F\\x041-\\x07E\\x080-\\xD7FF\\xE000-\\xFFFD\\x10000-\\x10FFFF]+@[")
public static Pattern WORDTYPE_JID_PATTERN = Pattern.compile("[\\p{Graph}&&[^<>]]+?@[\\p{Graph}&&[^<>]]+?");
public static Pattern[] WORDTYPE_PATTERNS = new Pattern[] { WORDTYPE_URL_PATTERN, WORDTYPE_JID_PATTERN };
*/
protected String word;
protected WordType type;
protected int start;
protected int end;
public Word(String word, WordType type, int start, int end) {
this.word = word;
this.type = type;
this.start = start;
this.end = end;
}
}
private Word getWordTypeOfEvent(MouseEvent e) {
try {
int offset = styledTextHistory.getOffsetAtLocation(new Point(e.x,e.y));
String text = styledTextHistory.getText();
//String word = getWordFromOffset(allText,offset);
// First of all .. get the whole word ...
if(text.charAt(offset) == ' ') return null;
int i;
for(i = offset ; i > 0 ; i--) {
if(text.charAt(i) == ' ') {
i++;
break;
}
}
int index = text.indexOf(' ',offset);
if(index < 0) index = text.length();
String substr = text.substring(i,index);
Word word = null;
// Now see what we've got ..
for(WordType type : WordType.values()) {
Matcher matcher = type.pattern().matcher(substr);
if(!matcher.find()) continue;
word = new Word(matcher.group(),type,i+matcher.start(),i+matcher.end());
}
return word;
} catch(IllegalArgumentException ex) {
return null;
}
}
private void createStyledTextChatHistory() {
styledTextHistory = new StyledText(topComposite,SWT.BORDER | SWT.READ_ONLY | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.WRAP);
GridData gridData = new GridData(SWT.FILL,SWT.FILL,true,true);
gridData.horizontalIndent = 5;
gridData.verticalIndent = 5;
styledTextHistory.setLayoutData(gridData);
StyledTextHelper.setLeftMargin(styledTextHistory,5);
// StyledTextHelper.setTopMargin(styledTextHistory,5);
// StyledTextHelper.setRightMargin(styledTextHistory,5);
final Cursor defaultCursor = new Cursor(topComposite.getDisplay(),SWT.CURSOR_ARROW);
final Cursor handCursor = new Cursor(topComposite.getDisplay(),SWT.CURSOR_HAND);
styledTextHistory.setCursor(defaultCursor);
styledTextHistory.addMouseListener(new MouseListener() {
public void mouseUp(MouseEvent e) {
}
public void mouseDown(MouseEvent e) {
Word word = getWordTypeOfEvent(e);
if(word != null) {
if(word.type == Word.WordType.JID) {
if(!isMe(word.word)) {
EntryMenu menu = (EntryMenu) chatParticipantStatus
.getParent().getData("entryMenu");
RosterEntry entry = account.xmpp.getRoster().getEntry(
StringUtils.parseBareAddress(word.word));
menu.open(account,entry,word.word);
}
}
// ...
}
}
public void mouseDoubleClick(MouseEvent e) {
}
});
styledTextHistory.addMouseMoveListener(new MouseMoveListener() {
// protected int original_start;
// protected int original_length;
// protected int[] originalRanges = null;
// protected StyleRange[] originalStyleRanges = null;
public void mouseMove(MouseEvent e) {
try {
Word word = getWordTypeOfEvent(e);
if(word != null) {
styledTextHistory.setCursor(handCursor);
styledTextHistory.setToolTipText(word.word);
/*
int start = word.start;
int length = word.end - word.start;
if(originalStyleRanges != null && original_start == start && original_length == length) {
return;
}
if(originalStyleRanges != null) {
styledTextHistory.setStyleRanges(original_start,original_length,originalRanges,originalStyleRanges);
}
originalStyleRanges = styledTextHistory.getStyleRanges(start, length, true);
originalRanges = styledTextHistory.getRanges(start, length);
original_start = start;
original_length = length;
StyleRange[] newStyleRanges = new StyleRange[originalStyleRanges.length];
for(int i = 0 ; i < newStyleRanges.length ; i++) {
newStyleRanges[i] = (StyleRange) originalStyleRanges[i].clone();
newStyleRanges[i].underline = true;
}
styledTextHistory.setStyleRanges(start,length,originalRanges,newStyleRanges);
*/
} else {
styledTextHistory.setCursor(defaultCursor);
styledTextHistory.setToolTipText(null);
/*
if(originalStyleRanges != null) {
styledTextHistory.setStyleRanges(original_start,original_length,originalRanges,originalStyleRanges);
originalStyleRanges = null;
originalRanges = null;
}
*/
}
} catch(IllegalArgumentException ex) {
// Catch exception if there is no character at offset ..
// originalStyleRanges = null;
styledTextHistory.setCursor(defaultCursor);
ex.printStackTrace();
}
}
});
// Simple listener to draw emoticons.
styledTextHistory.addPaintObjectListener(new PaintObjectListener() {
public void paintObject(PaintObjectEvent event) {
if(emoticons == null) {
return;
}
GC gc = event.gc;
StyleRange style = event.style;
String text = styledTextHistory.getText(style.start,style.start + style.length);
for(IconDef icon : emoticons.getIcons()) {
for(String iconstr : icon.text) {
if(iconstr.equals(text)) {
gc.drawImage(icon.getImage(), event.x, event.y + event.ascent - style.metrics.ascent);
}
}
}
}
});
}
/**
* This method initializes chatParticipantStatus
*
*/
protected void createChatParticipantStatus() {
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 3;
GridData gridData3 = new org.eclipse.swt.layout.GridData();
gridData3.grabExcessHorizontalSpace = true;
gridData3.verticalAlignment = org.eclipse.swt.layout.GridData.CENTER;
gridData3.horizontalAlignment = org.eclipse.swt.layout.GridData.FILL;
chatParticipantStatus = new Composite(topComposite, SWT.NONE);
chatParticipantStatus.setLayoutData(gridData3);
chatParticipantStatus.setLayout(gridLayout);
}
/**
* This method initializes chatHistory
*
*/
private void createChatHistory() {
if (!GOIMPlugin.getDefault().getMyPreferenceStore().getBoolean(
PreferenceConstants.P_CHAT_USE_BROWSER_WIDGET)) {
createStyledTextChatHistory();
//createFormChatHistory();
return;
}
try {
chatHistory = new Browser(topComposite, SWT.NONE);
} catch (SWTError error) {
createStyledTextChatHistory();
//createFormChatHistory();
return;
}
GridData gridData = new org.eclipse.swt.layout.GridData();
gridData.grabExcessHorizontalSpace = true;
gridData.horizontalAlignment = org.eclipse.swt.layout.GridData.FILL;
gridData.verticalAlignment = org.eclipse.swt.layout.GridData.FILL;
gridData.grabExcessVerticalSpace = true;
chatHistory.setLayoutData(gridData);
chatHistory
.addLocationListener(new org.eclipse.swt.browser.LocationAdapter() {
public void changing(LocationEvent event) {
// event.doit = false;
System.out.println("hmm.. " + event.data + " ... "
+ event.location + " ... "
+ chatHistory.getUrl());
if (event.location.startsWith("user://")) {
event.doit = false;
String user = event.location.substring(7);
// System.out.println(user + " vs. " +
// chat.getParticipant());
if (chat != null && StringUtils.parseBareAddress(user)
.equals(StringUtils.parseBareAddress(chat.getJID()))) {
EntryMenu menu = (EntryMenu) chatParticipantStatus
.getParent().getData("entryMenu");
menu
.open(
account,
account.xmpp
.getRoster()
.getEntry(
StringUtils
.parseBareAddress(user)),
null);
}
} else if (event.location.startsWith("http://")) {
try {
PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser().openURL(new URL(event.location));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
event.doit = false;
}
}
});
chatHistory.addMouseListener(new org.eclipse.swt.events.MouseAdapter() {
public void mouseUp(org.eclipse.swt.events.MouseEvent e) {
System.out.println("Data: " + e.data);
}
});
Menu menu = new Menu(chatHistory.getShell(),SWT.POP_UP);
// TODO add context menu to chat history ..
menu.addListener(SWT.Show, new Listener() {
public void handleEvent(Event event) {
}
});
chatHistory.setMenu(menu);
topComposite.addListener(SWT.FocusIn, focusInListener);
sashForm.addListener(SWT.FocusIn, focusInListener);
this.addListener(SWT.FocusIn, focusInListener);
chatHistory.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
System.out
.println("chatHistory: gained focus .. giving it up..");
if (!chatInput.setFocus())
System.out.println("setFocus returned false ?!");
}
public void focusLost(FocusEvent e) {
}
});
}
/**
* This method initializes buttonComposite
*
*/
private void createButtonComposite() {
// RowLayout rowLayout = new RowLayout();
// rowLayout.spacing = 6;
GridData gridData1 = new org.eclipse.swt.layout.GridData();
gridData1.grabExcessHorizontalSpace = false;
gridData1.verticalAlignment = org.eclipse.swt.layout.GridData.CENTER;
gridData1.horizontalAlignment = org.eclipse.swt.layout.GridData.END;
CoolBar buttonCoolBar = new CoolBar(bottomComposite, SWT.FLAT);
buttonCoolBar.setLayoutData(gridData1);
final ToolBar toolBar = new ToolBar(buttonCoolBar, SWT.FLAT);
toolItemHistory = new ToolItem(toolBar,SWT.PUSH);
toolItemHistory.setImage(GOIMIcons.getImage(GOIMIcons.CONTACT_HISTORY));
toolItemHistory.setToolTipText("Open Chat History");
toolItemHistory.addListener(SWT.Selection,new Listener() {
public void handleEvent(Event event) {
HistoryViewer.showHistoryOf(account,StringUtils.parseBareAddress(chat.getJID()));
}
});
toolItemVCard = new ToolItem(toolBar,SWT.PUSH);
toolItemVCard.setImage(GOIMIcons.getImage(GOIMIcons.CONTACT_VCARD));
toolItemVCard.setToolTipText("Show VCard");
toolItemVCard.addListener(SWT.Selection,new Listener() {
public void handleEvent(Event event) {
new vCardGUI(account, StringUtils.parseBareAddress(chat.getJID()));
}
});
if(emoticons != null && emoticons.getIcons().size() > 0) {
ToolItem toolItemSmileys = new ToolItem(toolBar, SWT.DROP_DOWN);
toolItemSmileys.setImage(emoticons.getIcons().get(0).getImage());
toolItemSmileys.setToolTipText("Add Emoticon");
//toolItemSmileys.setText("abc");
toolItemSmileys.addListener(SWT.Selection,new Listener() {
public void handleEvent(Event event) {
Rectangle bounds = ((ToolItem)event.widget).getBounds();
Point loc = toolBar.toDisplay(bounds.x,bounds.y);
final Shell shell = new Shell(toolBar.getShell(),SWT.RESIZE | SWT.BORDER);
shell.setBounds(loc.x,loc.y,150,200);
shell.setLayout(new FillLayout());
final Tree tree = new Tree(shell,SWT.BORDER);
for(IconDef iconDef : emoticons.getIcons()) {
TreeItem item = new TreeItem(tree,SWT.NULL);
item.setImage(iconDef.getImage());
item.setText(iconDef.text.get(0));
// item.setData("iconDef",iconDef);
item.setData("text",iconDef.text.get(0));
}
shell.open();
tree.forceFocus();
tree.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if(tree.getSelectionCount() < 1) return;
TreeItem item = tree.getSelection()[0];
// IconDef iconDef = (IconDef)item.getData("iconDef");
// chatInput.insert(iconDef.text.get(0));
String text = (String)item.getData("text");
chatInput.insert(text);
chatInput.setSelection(chatInput.getSelection().x+text.length());
shell.close();
} });
tree.addListener(SWT.FocusOut, new Listener() {
public void handleEvent(Event event) {
shell.close();
}
});
// Menu menu = new Menu(((ToolItem)event.widget).getParent());
// for(IconDef iconDef : emoticons.getIcons()) {
// MenuItem menuItem = new MenuItem(menu,SWT.PUSH);
// menuItem.setText(iconDef.text.get(0));
// menuItem.setImage(iconDef.getImage());
// }
// menu.setVisible(true);
} });
}
ToolItem toolItemBold = new ToolItem(toolBar, SWT.PUSH);
toolItemBold.setToolTipText("Make Selected Text Bold");
toolItemBold.setImage(GOIMIcons.getImage(GOIMIcons.CHATWINDOW_BOLD));
ToolItem toolItemUnderline = new ToolItem(toolBar, SWT.PUSH);
toolItemBold.setToolTipText("Make Selected Text Underlined");
toolItemUnderline.setImage(GOIMIcons.getImage(GOIMIcons.CHATWINDOW_UNDERLINE));
int totalx = 0;
CoolItem coolItem = new CoolItem(buttonCoolBar, SWT.NULL);
coolItem.setControl(toolBar);
toolBar.pack();
Point size = toolBar.getSize();
size = coolItem.computeSize(size.x,size.y);
totalx+=size.x;
coolItem.setMinimumSize(size);
coolItem.setPreferredSize(size);
ToolBar sendToolBar = new ToolBar(buttonCoolBar, SWT.FLAT);
ToolItem toolItemSend = new ToolItem(sendToolBar, SWT.PUSH);
toolItemSend.setToolTipText("Send Input");
toolItemSend.setText("Send");
CoolItem sendCoolItem = new CoolItem(buttonCoolBar, SWT.NULL);
sendCoolItem.setControl(sendToolBar);
sendToolBar.pack();
size = sendToolBar.getSize();
size = sendCoolItem.computeSize(size.x, size.y);
totalx+=size.x;
sendCoolItem.setMinimumSize(size);
sendCoolItem.setPreferredSize(size);
//gridData1.minimumWidth = totalx + 30;
gridData1.widthHint = totalx + 30;
buttonCoolBar.pack();
/*
buttonComposite = new Composite(bottomComposite, SWT.NONE);
buttonComposite.setLayoutData(gridData1);
buttonComposite.setLayout(rowLayout);
buttonBold = new Button(buttonComposite, SWT.NONE);
buttonBold.setText("Bold");
buttonBold */
toolItemBold
.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() {
public void widgetSelected(
org.eclipse.swt.events.SelectionEvent e) {
makeInputSelectionBold();
}
});
/*
// added by BInod
buttonUnderLine = new Button(buttonComposite, SWT.NONE);
buttonUnderLine.setText("UnderLine");
buttonUnderLine */
toolItemUnderline
.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() {
public void widgetSelected(
org.eclipse.swt.events.SelectionEvent e) {
makeInputSelectionUnderlined(); }
});
// end
/*
buttonSend = new Button(buttonComposite, SWT.NONE);
buttonSend.setText("Send");
buttonSend */
toolItemSend
.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() {
public void widgetSelected(
org.eclipse.swt.events.SelectionEvent e) {
sendUserInput();
chatInput.setFocus();
}
});
}
/**
*
*
*/
protected void sendUserInput() {
Message msg = createMessage();
if (msg != null) {
String input = chatInput.getText();
// System.out.println("Styles: " + chatInput.getStyleRanges());
if (input.equals("")) {
chatInput.setText("");
return;
}
StringBuffer xhtmlText = null;
StyleRange[] ranges = chatInput.getStyleRanges();
if (ranges != null && ranges.length > 0) {
int lastposition = 0;
xhtmlText = new StringBuffer();
// boolean hasOpenSpanTag = false;
for (StyleRange range : ranges) {
if (range.start > lastposition) {
appendToXHTMLText(xhtmlText,input.substring(lastposition,
range.start));
// xhtmlText.append(input.substring(lastposition,
// range.start).replace(GOIMPlugin.LINESEPARATOR,"<br />"));
lastposition = range.start;
}
// if(hasOpenSpanTag) xhtmlText.appendCloseSpanTag();
StringBuffer style = new StringBuffer();
if ((range.fontStyle & SWT.BOLD) != 0)
style.append("font-weight:bold;");
if ((range.fontStyle & SWT.ITALIC) != 0)
style.append("font-style:italic;");
if (range.underline)
style.append("text-decoration:underline;");
if (range.strikeout)
style.append("text-decoration:line-through;");
xhtmlText.append("<span style=\"").append(style).append("\">");
// xhtmlText.appendOpenSpanTag(style.toString());
// hasOpenSpanTag = true;
appendToXHTMLText(xhtmlText,input.substring(range.start, range.start
+ range.length));
// xhtmlText.append(input.substring(range.start, range.start
// + range.length));
xhtmlText.append("</span>");
// xhtmlText.appendCloseSpanTag();
lastposition = range.start + range.length;
}
// if(hasOpenSpanTag) xhtmlText.appendCloseSpanTag();
if (input.length() > lastposition) {
appendToXHTMLText(xhtmlText,input.substring(lastposition));
// xhtmlText.append(input.substring(lastposition).replace(GOIMPlugin.LINESEPARATOR,"<br />"));
}
}
MessageEventManager.addNotificationsRequests(msg, false, false,
true, true);
String text = input;
msg.setBody(text);
if (xhtmlText != null)
XHTMLManager.addBody(msg, xhtmlText.toString());
try {
sendMessage(msg);
} catch (XMPPException e) {
e.printStackTrace();
}
if(chat != null)
addMessageToHistory(account.jid, msg, false);
chatInput.setText("");
sentComposing = false;
chatInput.setStyleRanges(new StyleRange[0]);
}
}
protected Message createMessage() {
return chat.createMessage();
}
protected void sendMessage(Message msg) throws XMPPException {
if(chat != null)
chat.sendMessage(msg);
}
protected void appendToXHTMLText(StringBuffer xhtmlText, String string) {
xhtmlText.append(string.replace(GOIMPlugin.LINESEPARATOR,"<br />"));
// String[] strings = string.split(GOIMPlugin.LINESEPARATOR);
// boolean first = true;
// for(String s : strings) {
// if(first)
// xhtmlText.appendBrTag();
// else
// first = false;
// xhtmlText.append(s);
// }
}
protected void generalInit() {
final SpheneListener<StatusChangedEvent> ownPresenceChangeListener = new SpheneListener<StatusChangedEvent>() {
public void handleEvent(StatusChangedEvent event) {
if(event.previousPresence == null) {
// we need to recover the chat session ...
account.xmpp.getConnection().addConnectionListener(connectionListener);
// if(chat != null) {
// chat = account.xmpp.getConnection().createChat(chat.getParticipant());
// chat.addMessageListener(packetListener);
// }
}
asyncAppendToChatHistory(account.jid,"- You changed your status to " + GOIMIcons.getShowTextForPresence(account.xmpp.getOwnPresence()),false,"","* ");
} };
account.xmpp.ownPresenceChanged.addListener(ownPresenceChangeListener);
connectionListener = new ConnectionListener() {
public void connectionClosed() {
getDisplay().asyncExec(new Runnable() { public void run() {
appendToChatHistory(account.jid," - You disconnected from the Jabber Server",false,"","* "); // - You will need to reopen this Window when reconnecting.",false,"","* ");
}});
}
public void connectionClosedOnError(Exception e) {
connectionClosed();
}
};
account.xmpp.getConnection().addConnectionListener(connectionListener);
addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event event) {
if(account != null && account.xmpp != null) {
if(account.xmpp.getConnection() != null) {
account.xmpp.getConnection().removeConnectionListener(connectionListener);
}
account.xmpp.ownPresenceChanged.removeListener(ownPresenceChangeListener);
}
}
});
}
/**
* ?
*
*/
public void init(GOIMAccount account_, GOIMChatObject chat_) {
this.account = account_;
this.chat = chat_;
RosterEntry entry = account.xmpp.getRoster().getEntry(
chat.getJID());
if (entry == null)
entry = account.xmpp.getRoster().getEntry(
StringUtils.parseBareAddress(chat.getJID()));
final FormToolkit tk = GOIMPlugin.getFormToolkit(this.getDisplay());
/* Section entrySection = */
final Section entrySection =
ContactList.createRosterEntry(tk, account, account.xmpp.getRoster(),
chatParticipantStatus, entry, chat.getJID());
// EntryMenu menu = (EntryMenu)
// chatParticipantStatus.getParent().getData("entryMenu");
// chatHistory.setMenu(menu.entryMenu);
// chatHistory.setMenu(null);
// section.setText("Chat with " + chat.getParticipant());
// section.layout();
if (rosterListener != null) {
System.err.println("RosterListener != null ?! error ?!");
account.xmpp.getRoster().removeRosterListener(rosterListener);
}
account.xmpp.getRoster().addRosterListener(
rosterListener = new RosterListener() {
public void presenceChanged(final String jid) {
final String id = StringUtils.parseBareAddress(jid);
if (ChatBrowserGUI.this.chat.getJID().startsWith(id)) {
chatParticipantStatus.getDisplay().asyncExec(new Runnable() {
public void run() {
ContactList.updateRosterEntryPresence(
tk,
ChatBrowserGUI.this.account,
id,
/*chatParticipantStatus*/entrySection);
appendToChatHistory(jid,"changed his status to " + GOIMIcons.getShowTextForPresence(ChatBrowserGUI.this.account.xmpp.getRoster().getPresence(jid)),false,"","* ");
}
});
}
}
public void entriesAdded(Collection arg0) {
}
public void entriesUpdated(Collection arg0) {
}
public void entriesDeleted(Collection arg0) {
}
});
// chat.addMessageListener(new PacketListener() {
//
// public void processPacket(Packet packet) {
// //while(pollChat());
// processMessage((Message)packet);
// } });
// if (packetListener != null) {
// System.err.println("RosterListener != null ?! error ?!");
// account.xmpp.getConnection().removePacketListener(packetListener);
// }
// chat.addMessageListener(packetListener = new PacketListener() {
// public void processPacket(Packet packet) {
// if(packet instanceof Message)
// processMessage((Message) packet);
// }
// });
// account.xmpp.getConnection().addPacketListener(
// packetListener = new PacketListener() {
// public void processPacket(Packet packet) {
// if (packet instanceof Message)
// processMessage((Message) packet);
// }
// }, new FromContainsFilter(chat.getParticipant()));
addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event event) {
System.out.println("Disposing ChatBrowserGUI");
if(account != null && account.xmpp != null) {
if(account.xmpp.getRoster() != null)
account.xmpp.getRoster().removeRosterListener(rosterListener);
// if(account.xmpp.getConnection() != null) {
// account.xmpp.getConnection().removePacketListener(packetListener);
// }
}
// if(chat != null)
// chat.removeMessageListener(packetListener);
}
});
generalInit();
// while (pollChat())
// ;
}
// /**
// *
// * @return true if false if
// */
// private boolean pollChat() {
// if (chat == null)
// return false;
// Message msg = chat.pollMessage();
// if (msg == null)
// return false;
// processMessage(msg);
// return true;
// }
/**
*
*
* @param jid
* @param message
*/
private void addMessageToHistory(final String jid, final Message message, boolean alreadyHandled) {
SpheneEvent spheneEvent = new SpheneEvent(jid);
spheneEvent.setParam(EVENT_PARAM_ALREADYHANDLED,alreadyHandled);
changeListener.fireEvent(spheneEvent);
topComposite.getDisplay().asyncExec(new Runnable() {
public void run() {
String packetId = message.getPacketID();
DelayInformation delay = (DelayInformation) message
.getExtension("x", "jabber:x:delay");
Date date = null;
if (delay == null)
date = new Date();
else
date = delay.getStamp();
String msg = null;
if(styledTextHistory != null) {
msg = message.getBody();
} else {
msg = escapeMessageString(message.getBody());
msg = msg.replaceAll("(http://[^ ]+)","<a href=\"$1\">$1</a>");
}
if (chatHistory == null) {
if(styledTextHistory != null) {
Iterator i = XHTMLManager.getBodies(message);
boolean usesXHTML = false;
if(i != null && i.hasNext()) {
msg = (String)i.next();
usesXHTML = true;
}
String prefix = null;
if(msg.startsWith("/me ")) {
prefix = "* ";
msg = msg.substring(4);
}
appendToChatHistory(jid, msg, usesXHTML, packetId, prefix, date);
} else {
appendToChatHistory(jid, msg, true, packetId, null, date);
}
} else {
// String msg = message.getBody().replaceAll("[\r\n]{1,2}",
// "<br/>");
Iterator i = XHTMLManager.getBodies(message);
boolean usesXHTML = false;
if (i != null && i.hasNext()) {
String test = (String) i.next();
msg = test.replaceAll("[\r\n]{1,2}", "").replace('"',
'\'');
usesXHTML = true;
}
if (emoticons != null)
for (IconDef iconDef : emoticons.getIcons()) {
String url = emoticons.rootpath + "/"
+ iconDef.image;
for (String r : iconDef.text) {
r = escapeMessageString(r);
if (chatHistory == null) {
System.out.println("replacing all " + r
+ " with " + url);
msg = msg.replace(r, "<img href='" + url
+ "'></img>");
} else
msg = msg.replace(r, "<img src='" + url
+ "' />");
}
}
usesXHTML = true;
String prefix = null;
if(msg.startsWith("/me ")) {
prefix = "* ";
msg = msg.substring(4);
}
appendToChatHistory(jid, msg, usesXHTML, packetId, prefix,
date);
}
}
});
}
/**
*
* @param jid
* @return
*/
public boolean isMe(String jid) {
if (chat != null)
return StringUtils.parseBareAddress(jid).equals(
StringUtils.parseBareAddress(account.jid));
// System.out.println("Is that me: " + jid + " ... no idea ?!");
return false;
}
/**
*
*/
public void processMessage(Message message, boolean alreadyHandled) {
if(chat != null) {
if(!message.getFrom().equals(chat.getJID())) {
if(StringUtils.parseBareAddress(message.getFrom()).equals(chat.getJID()))
chat.setJID(message.getFrom());
}
}
MessageEvent event = getMessageEvent(message);
if (message.getBody() != null) {
setStatusLabelText("");
lastMessageEventRequest = event;
lastReceivedMessage = message;
sentComposing = false;
addMessageToHistory(message.getFrom(), message, alreadyHandled);
} else {
if (event == null)
return;
if (event.isComposing())
setStatusLabelText("User is composing a reply");
else if (event.isDisplayed())
setStatusLabelText("Your Message was displayed.");
else if (event.isDelivered())
setStatusLabelText("Your Message was delivered.");
else if (event.isCancelled())
setStatusLabelText("User cancelled reply.");
else if (event.isOffline())
setStatusLabelText("Your Message was stored for offline delivery");
else
setStatusLabelText("");
}
}
/**
*
* @param message
* @return
*/
protected MessageEvent getMessageEvent(Message message) {
PacketExtension extension = message.getExtension(messageEvent
.getElementName(), messageEvent.getNamespace());
if (extension == null || !(extension instanceof MessageEvent))
return null;
return (MessageEvent) extension;
}
/**
*
*/
public void addChangeListener(SpheneListener<SpheneEvent> listener) {
changeListener.addListener(listener);
}
/**
*
* @param jid
* @param msg
* @param usesXHTML
* @param packetId
* @param prefix
*/
void asyncAppendToChatHistory(final String jid, final String msg,
final boolean usesXHTML, final String packetId, final String prefix) {
topComposite.getDisplay().asyncExec(new Runnable() {
public void run() {
appendToChatHistory(jid, msg, usesXHTML, packetId, prefix);
}
});
}
/**
*
* @param jid
* @param msg
* @param usesXHTML
* @param packetId
* @param prefix
*/
void appendToChatHistory(final String jid, String msg,
boolean usesXHTML, String packetId, String prefix) {
appendToChatHistory(jid, msg, usesXHTML, packetId, prefix, null);
}
/**
*
* @param jid
* @param msg
* @param usesXHTML
* @param packetId
* @param prefix
* @param date
*/
private void appendToChatHistory(String jid, String msg, boolean usesXHTML,
String packetId, String prefix, Date date) {
String jiddisplay = jid;
if (chat == null) {
jiddisplay = StringUtils.parseResource(jid);
if (jiddisplay.equals(""))
jiddisplay = jid;
} else {
Roster roster = account.xmpp.getRoster();
if(roster != null) {
RosterEntry entry = roster.getEntry(StringUtils
.parseBareAddress(jid));
if (entry != null && entry.getName() != null)
jiddisplay = entry.getName();
}
}
if (chatHistory == null) {
if (styledTextHistory == null) {
FormText text = tk.createFormText(historyForm.getBody(), true);
if (isMe(jid)) {
text.setColor("jidcolor", text.getDisplay().getSystemColor(
SWT.COLOR_RED));
} else {
text.setColor("jidcolor", text.getDisplay().getSystemColor(
SWT.COLOR_BLUE));
}
if (emoticons != null)
for (IconDef def : emoticons.getIcons()) {
for (String iconstr : def.text) {
if (msg.contains(iconstr)) {
msg = msg.replace(iconstr, "<img href=\""
+ def.image + "\" />");
text.setImage(def.image, def.getImage());
}
}
}
StringBuffer fullText = new StringBuffer("<form><p>");
fullText.append("<b>").append(
historyDateFormat.format(date == null ? new Date() : date))
.append("</b> ");
fullText.append("<span color=\"jidcolor\">");
if (prefix == null)
fullText.append(" <").append(jiddisplay).append("> ");
else
fullText.append(prefix).append(jiddisplay);
fullText.append("</span> ");
fullText.append(msg);
fullText.append("</p></form>");
System.out.println("Text: " + fullText.toString());
text.setText(fullText.toString(), true, false);
text.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
historyForm.reflow(true);
historyForm.setOrigin(0, text.getLocation().y);
} else {
if(styledTextHistory.getText().length() > 0) {
styledTextHistory.append("\n");
}
String historydate = historyDateFormat.format(date == null ? new Date() : date) + " ";
String prefixtext = (prefix == null ? "<" + jiddisplay + "> " : prefix + jiddisplay + " ");
StyleRange dateRange = new StyleRange();
dateRange.start = styledTextHistory.getText().length();
dateRange.length = historydate.length();
dateRange.fontStyle = SWT.BOLD;
int msgStart = styledTextHistory.getText().length() + historydate.length();
StyleRange range = new StyleRange();
range.start = dateRange.start + dateRange.length;
range.length = prefixtext.length();
if(isMe(jid)) {
range.foreground = styledTextHistory.getDisplay().getSystemColor(SWT.COLOR_RED);
} else {
range.foreground = styledTextHistory.getDisplay().getSystemColor(SWT.COLOR_BLUE);
}
range.fontStyle = SWT.BOLD;
styledTextHistory.append(historydate + prefixtext);
styledTextHistory.setStyleRange(dateRange);
styledTextHistory.setStyleRange(range);
if(usesXHTML) {
SAXParserFactory fac = SAXParserFactory.newInstance();
try {
SAXParser parser = fac.newSAXParser();
parser.parse(new InputSource(new StringReader("<body>"+msg+"</body>")),new ParseXHTMLForStyledText(styledTextHistory));
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else {
styledTextHistory.append(msg);
}
String text = styledTextHistory.getText();
text = text.substring(msgStart,text.length());
if (emoticons != null) {
for (IconDef def : emoticons.getIcons()) {
for (String iconstr : def.text) {
int index = text.indexOf(iconstr);
if (index >= 0) {
StyleRange iconRange = new StyleRange();
iconRange.start = msgStart + index;
iconRange.length = iconstr.length();
Image image = def.getImage();
Rectangle rect = image.getBounds();
iconRange.metrics = new GlyphMetrics(rect.height,0,rect.width / iconstr.length());
System.out.println("Width: " + (rect.width / iconstr.length()));
styledTextHistory.setStyleRange(iconRange);
}
}
}
}
if(styledTextHistory.getSelectionText().length() == 0) {
styledTextHistory.setSelection(styledTextHistory.getText().length());
}
}
} else {
StringBuffer script = new StringBuffer().append(
"var toAdd = document.createElement(\"p\");").append(
"var date = document.createElement(\"span\");").append(
"var date_a = document.createElement(\"a\");");
if (packetId != null)
script.append("date_a.setAttribute(\"name\",\"msg").append(
packetId).append("\");");
script.append("var from = document.createElement(\"span\");")
.append("var from_a = document.createElement(\"a\");")
.append("from_a.setAttribute(\"href\",\"user://").append(
jid).append("\");").append(
"var message = document.createElement(\"span\");")
// .append("date.setAttribute(\"class\",\"date\");")
// .append("date.setAttribute(\"style\",\"font-weight:bold\");")
// .append("from.setAttribute(\"class\",\"from\");")
// .append("message.setAttribute(\"class\",\"message\");")
.append("date.className = \"date\";").append(
"from.className = \"from\";").append(
"message.className = \"message\";").append(
"date_a.appendChild(document.createTextNode(\"")
.append(
historyDateFormat.format(date == null ? new Date()
: date)).append("\"));").append(
"date.appendChild(date_a);").append(
"from_a.appendChild(document.createTextNode(\"")
.append(prefix == null ? "<" : prefix).append(jiddisplay)
.append(prefix == null ? ">" : "").append("\"));").append(
"from.appendChild(from_a);");
if (isMe(jid)) {
script.append("from_a.className = \"myself\";");
}
msg = msg.replace("\\", "\\\\").replace("\"", "\\\"");
if (usesXHTML) {
script.append("message.innerHTML = \"").append(msg).append(
"\";");
} else {
script.append("message.appendChild(document.createTextNode(\"")
.append(msg).append("\"));");
}
script
.append("toAdd.appendChild(date);")
.append("toAdd.appendChild(from);")
.append("toAdd.appendChild(message);")
.append(
"document.getElementById(\"chathistory\").appendChild(toAdd);")
// .append("location.hash =
// \"msg").append(message.getPacketID()).append("\";")
.append("toAdd.scrollIntoView();");
boolean result = chatHistory.execute(script.toString());
// System.out.println("Appanding message ... " + script.toString());
if (!result)
System.out.println("Script did not execute ?! "
+ script.toString());
}
}
public static class ParseXHTMLForStyledText extends DefaultHandler {
List<StyleRange> styleStack;
private StyledText text;
public ParseXHTMLForStyledText(StyledText text) {
this.text = text;
styleStack = new ArrayList<StyleRange>();
styleStack.add(new StyleRange());
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
StyleRange range = styleStack.get(styleStack.size()-1);
range = (StyleRange)range.clone();
styleStack.add(range);
String style = attributes.getValue("", "style");
if(style != null) {
String[] styles = style.split("\\s*;\\s*");
for(String s : styles) {
String[] args = s.split("\\s*:\\s*");
if(args.length < 2) continue;
if("font-weight".equals(args[0])) {
if("bold".equals(args[1])) {
range.fontStyle = range.fontStyle | SWT.BOLD;
}
} else if("text-decoration".equals(args[0])) {
if("underline".equals(args[1])) {
range.underline = true;
} else if("line-through".equals(args[1])) {
range.strikeout = true;
}
} else if("font-style".equals(args[0])) {
if("italic".equals(args[1]) || "oblique".equals(args[1])) {
range.fontStyle = range.fontStyle | SWT.ITALIC;
}
}
}
}
if("span".equals(qName)) {
}
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
StyleRange range = styleStack.get(styleStack.size()-1);
int startPos = text.getText().length();
text.append(new String(ch,start,length));
StyleRange newRange = (StyleRange)range.clone();
newRange.start = startPos;
newRange.length = length;
text.setStyleRange(newRange);
}
/* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
styleStack.remove(styleStack.size()-1);
}
}
/**
*
*
*/
public void setCustomFocus() {
System.out.println("setCustomFucos .. forwarding focus..");
if (!chatInput.setFocus())
System.out.println("setFocus returned false ?!");
}
/**
*
* @param text
*/
protected void setStatusLabelText(final String text) {
statusLabel.getDisplay().asyncExec(new Runnable() {
public void run() {
statusLabel.setText(text);
}
});
}
private void makeInputSelectionBold() {
Point range = chatInput.getSelectionRange();
StyleRange style = new StyleRange();
style.start = range.x;
style.length = range.y;
if (style.fontStyle == SWT.BOLD)
style.fontStyle = SWT.NORMAL;
else
style.fontStyle = SWT.BOLD;
chatInput.setStyleRange(style);
chatInput.setFocus();
}
private void makeInputSelectionUnderlined() {
Point range = chatInput.getSelectionRange();
StyleRange style = new StyleRange();
style.start = range.x;
style.length = range.y;
style.underline = !style.underline;
chatInput.setStyleRange(style);
chatInput.setFocus();
}
public String escapeMessageString(String msg) {
StringBuffer buf = new StringBuffer();
// String msg = message.getBody().replace("&","&")
// .replace("<", "<")
// .replace(">", ">").replaceAll("[\r\n]{1,2}",
// "<br/>");
char[] block = null;
int i;
int last = 0;
int size = msg.length();
int fakei;
StringBuffer entityBuf = new StringBuffer();
for (i = 0; i < size; i++) {
String entity = null;
char c = msg.charAt(i);
fakei = i;
switch(c) {
case '<':
entity = "<";
break;
case '>':
entity = ">";
break;
case '&':
entity = "&";
break;
case '\r':
case '\n':
if(i+1 < size) {
char nextc = msg.charAt(i+1);
if((nextc == '\r' || nextc == '\n') && c != nextc)
fakei++;
}
entity = "<br/>";
break;
case '"':
entity = """;
break;
case ' '://two spaces: hehe hehe hehe
if(i+1 < size && msg.charAt(i+1) == ' ') {
int j = 2;
for( ; i+j < size && msg.charAt(i+j) == ' ' ; j++);
for(int k = 0 ; k < j ; k++)
entityBuf.append(" ");
entity = entityBuf.toString();
entityBuf.setLength(0);
fakei+=(j-1);
}
break;
}
if (entity != null) {
if (block == null) {
block = msg.toCharArray();
}
buf.append(block, last, i - last);
buf.append(entity);
last = fakei + 1;
}
i = fakei;
}
if (last == 0) {
return msg;
}
if (last < size) {
if (block == null) {
block = msg.toCharArray();
}
buf.append(block, last, i - last);
}
return buf.toString();
}
public String getJID() {
return chat.getJID();
}
}