Package net.sphene.goim.rcp.ui

Source Code of net.sphene.goim.rcp.ui.ChatBrowserGUI

/*
* 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(" &lt;").append(jiddisplay).append("&gt; ");
        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("&","&amp;")
//    .replace("<", "&lt;")
//    .replace(">", "&gt;").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 = "&lt;";
        break;
      case '>':
        entity = "&gt;";
        break;
      case '&':
        entity = "&amp;";
        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 = "&quot;";
        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("&nbsp;");
          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();
  }
}
TOP

Related Classes of net.sphene.goim.rcp.ui.ChatBrowserGUI

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.