Add formatting facilities in the gui and formatting support in ICQ, AIM.(Yahoo and SIP already support html content).

cusax-fix
Yana Stamcheva 18 years ago
parent 11ecd5fae5
commit 6fe16927f0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 732 B

After

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 661 B

After

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 637 B

After

Width:  |  Height:  |  Size: 305 B

@ -65,7 +65,7 @@ font-size:12;
color:#000000
}
i
h7
{
background-color:#FFF4AB
}

@ -569,7 +569,7 @@ private String processKeyword(String message, String contentType,
String matchGroup = m.group().trim();
String replacement = endPlainTextTag + "<I>" + matchGroup + "</I>"
String replacement = endPlainTextTag + "<h7>" + matchGroup + "</h7>"
+ startPlainTextTag;
m.appendReplacement(msgBuffer, GuiUtils

@ -50,13 +50,13 @@ public abstract class ChatPanel
private JSplitPane messagePane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
private ChatConversationPanel conversationPanel;
protected ChatConversationPanel conversationPanel;
private ChatWritePanel writeMessagePanel;
protected ChatWritePanel writeMessagePanel;
private ChatContactListPanel chatContactListPanel;
protected ChatContactListPanel chatContactListPanel;
private ChatSendPanel sendPanel;
protected ChatSendPanel sendPanel;
private ChatWindow chatWindow;
@ -185,7 +185,7 @@ public ChatPanel(ChatWindow chatWindow)
*
* @param text the text to send
*/
protected abstract void sendMessage(String text);
protected abstract void sendMessage();
/**
* This method should be implemented in case additional treatment is needed
@ -405,11 +405,21 @@ public boolean isWriteAreaEmpty()
{
JEditorPane editorPane = getChatWritePanel().getEditorPane();
if (editorPane.getText() == null
|| editorPane.getText().equals(""))
return true;
else
return false;
Document doc = editorPane.getDocument();
try
{
String text = doc.getText(0, doc.getLength());
if (text == null || text.equals(""))
return true;
}
catch (BadLocationException e)
{
logger.error("Failed to obtain document text.", e);
}
return false;
}
/**
@ -548,10 +558,9 @@ public String processHistoryMessage(String contactName,
* Refreshes write area editor pane. Deletes all existing text
* content.
*/
public void refreshWriteArea(){
JEditorPane writeMsgPane = this.writeMessagePanel.getEditorPane();
writeMsgPane.setText("");
public void refreshWriteArea()
{
this.writeMessagePanel.clearWriteArea();
}
/**
@ -569,10 +578,17 @@ public void addTextInWriteArea(String text){
* Returns the text contained in the write area editor.
* @return The text contained in the write area editor.
*/
public String getTextFromWriteArea(){
JEditorPane editorPane = this.writeMessagePanel.getEditorPane();
return editorPane.getText();
public String getTextFromWriteArea(String mimeType)
{
if (mimeType.equals(
OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE))
{
return writeMessagePanel.getText();
}
else
{
return writeMessagePanel.getTextAsHtml();
}
}
/**

@ -73,20 +73,14 @@ public void actionPerformed(ActionEvent evt)
{
if (!chatPanel.isWriteAreaEmpty())
{
final String text = chatPanel.getTextFromWriteArea();
chatPanel.refreshWriteArea();
new Thread()
{
public void run()
{
chatPanel.sendMessage(text);
chatPanel.sendMessage();
}
}.start();
}
//make sure the focus goes back to the write area
chatPanel.requestFocusInWriteArea();
}
/**

@ -1,8 +1,7 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*
* Distributable under LGPL license. See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.gui.main.chat;
@ -13,28 +12,31 @@
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import javax.swing.undo.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.i18n.*;
import net.java.sip.communicator.impl.gui.lookandfeel.*;
import net.java.sip.communicator.impl.gui.main.chat.menus.*;
import net.java.sip.communicator.impl.gui.main.chat.toolBars.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.configuration.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.*;
/**
* The <tt>ChatWritePanel</tt> is the panel, where user writes her messages.
* It is located at the bottom of the split in the <tt>ChatPanel</tt> and
* it contains an editor, where user writes the text.
* It is located at the bottom of the split in the <tt>ChatPanel</tt> and it
* contains an editor, where user writes the text.
*
* @author Yana Stamcheva
*/
public class ChatWritePanel
extends JScrollPane
extends JPanel
implements UndoableEditListener,
KeyListener,
MouseListener
MouseListener
{
private Logger logger = Logger.getLogger(ChatWritePanel.class);
@ -44,58 +46,72 @@ public class ChatWritePanel
private ChatPanel chatPanel;
private Timer stoppedTypingTimer = new Timer(2 * 1000,
new Timer1ActionListener());
private Timer stoppedTypingTimer =
new Timer(2 * 1000, new Timer1ActionListener());
private Timer typingTimer = new Timer(5 * 1000, new Timer2ActionListener());
private int typingState = -1;
private StyledEditorKit styledEditor = new StyledEditorKit();
private HTMLEditorKit htmlEditor = new HTMLEditorKit();
private WritePanelRightButtonMenu rightButtonMenu;
private EditTextToolBar editTextToolBar;
private JScrollPane scrollPane = new JScrollPane();
/**
* Creates an instance of <tt>ChatWritePanel</tt>.
*
* @param panel The parent <tt>ChatPanel</tt>.
*/
public ChatWritePanel(ChatPanel panel) {
public ChatWritePanel(ChatPanel panel)
{
super();
super(new BorderLayout());
this.chatPanel = panel;
this.rightButtonMenu
= new WritePanelRightButtonMenu(chatPanel.getChatWindow());
this.setHorizontalScrollBarPolicy(
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
this.editTextToolBar = new EditTextToolBar(editorPane);
this.add(editTextToolBar, BorderLayout.NORTH);
this.add(scrollPane, BorderLayout.CENTER);
this.rightButtonMenu =
new WritePanelRightButtonMenu(chatPanel.getChatWindow());
this.scrollPane
.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
this.editorPane.setContentType("text/html");
this.editorPane.setFont(Constants.FONT);
this.editorPane.setEditorKit(styledEditor);
this.editorPane.setCaretPosition(0);
this.editorPane.setEditorKit(htmlEditor);
this.editorPane.getDocument().addUndoableEditListener(this);
this.editorPane.addKeyListener(this);
this.editorPane.addMouseListener(this);
this.getViewport().add(editorPane, BorderLayout.CENTER);
this.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(3, 3, 3, 3),
this.scrollPane.getViewport().add(editorPane, BorderLayout.CENTER);
this.scrollPane.setBorder(BorderFactory
.createCompoundBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3),
SIPCommBorders.getBoldRoundBorder()));
this.getVerticalScrollBar().setUnitIncrement(30);
this.scrollPane.getVerticalScrollBar().setUnitIncrement(30);
this.typingTimer.setRepeats(true);
//initialize send command to Ctrl+Enter
ConfigurationService configService
= GuiActivator.getConfigurationService();
String messageCommand = configService.getString(
"net.java.sip.communicator.impl.gui.sendMessageCommand");
if(messageCommand == null || messageCommand.equalsIgnoreCase("enter"))
// initialize send command to Ctrl+Enter
ConfigurationService configService =
GuiActivator.getConfigurationService();
String messageCommand =
configService
.getString("net.java.sip.communicator.impl.gui.sendMessageCommand");
if (messageCommand == null || messageCommand.equalsIgnoreCase("enter"))
this.changeSendCommand(true);
else
this.changeSendCommand(false);
@ -103,48 +119,51 @@ public ChatWritePanel(ChatPanel panel) {
/**
* Returns the editor panel, contained in this <tt>ChatWritePanel</tt>.
*
* @return The editor panel, contained in this <tt>ChatWritePanel</tt>.
*/
public JEditorPane getEditorPane() {
public JEditorPane getEditorPane()
{
return editorPane;
}
/**
* Replaces the Ctrl+Enter send command with simple Enter.
*/
public void changeSendCommand(boolean isEnter)
public void changeSendCommand(boolean isEnter)
{
this.editorPane.getActionMap().put("send", new SendMessageAction());
this.editorPane.getActionMap().put("newLine", new NewLineAction());
InputMap im = this.editorPane.getInputMap();
if(isEnter) {
if (isEnter)
{
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "send");
im.put(KeyStroke.getKeyStroke(
KeyEvent.VK_ENTER, KeyEvent.CTRL_DOWN_MASK), "newLine");
im.put(KeyStroke.getKeyStroke(
KeyEvent.VK_ENTER, KeyEvent.SHIFT_DOWN_MASK), "newLine");
chatPanel.getChatSendPanel().getSendButton()
.setToolTipText("<html>"
+ Messages.getI18NString("sendMessage").getText()
+ " - Enter <br> "
+ "Use Ctrl-Enter or Shift-Enter to make a new line"
+ "</html>");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
KeyEvent.CTRL_DOWN_MASK), "newLine");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
KeyEvent.SHIFT_DOWN_MASK), "newLine");
chatPanel.getChatSendPanel().getSendButton().setToolTipText(
"<html>" + Messages.getI18NString("sendMessage").getText()
+ " - Enter <br> "
+ "Use Ctrl-Enter or Shift-Enter to make a new line"
+ "</html>");
}
else {
im.put(KeyStroke.getKeyStroke(
KeyEvent.VK_ENTER, KeyEvent.CTRL_DOWN_MASK), "send");
im.put(KeyStroke.getKeyStroke(
KeyEvent.VK_ENTER, 0), "newLine");
else
{
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
KeyEvent.CTRL_DOWN_MASK), "send");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "newLine");
chatPanel.getChatSendPanel().getSendButton()
.setToolTipText(Messages.getI18NString("sendMessage").getText()
+ " Ctrl-Enter");
.setToolTipText(
Messages.getI18NString("sendMessage").getText()
+ " Ctrl-Enter");
}
}
/**
* The <tt>SendMessageAction</tt> is an <tt>AbstractAction</tt> that
* sends the text that is currently in the write message area.
@ -153,15 +172,15 @@ private class SendMessageAction
extends AbstractAction
{
public void actionPerformed(ActionEvent e)
{
{
// chatPanel.stopTypingNotifications();
chatPanel.sendButtonDoClick();
}
}
/**
* The <tt>NewLineAction</tt> is an <tt>AbstractAction</tt> that
* types an enter in the write message area.
* The <tt>NewLineAction</tt> is an <tt>AbstractAction</tt> that types
* an enter in the write message area.
*/
private class NewLineAction
extends AbstractAction
@ -169,32 +188,43 @@ private class NewLineAction
public void actionPerformed(ActionEvent e)
{
int caretPosition = editorPane.getCaretPosition();
String editorText = editorPane.getText();
editorPane.setText(editorText.substring(0, caretPosition)
+ "\n"
+ editorText.substring(caretPosition));
HTMLDocument doc = (HTMLDocument) editorPane.getDocument();
try
{
doc.insertString(caretPosition, "\n", null);
}
catch (BadLocationException e1)
{
logger.error("Could not insert <br> to the document.", e1);
}
editorPane.setCaretPosition(caretPosition + 1);
}
}
/**
* Handles the <tt>UndoableEditEvent</tt>, by adding the content edit
* to the <tt>UndoManager</tt>.
* Handles the <tt>UndoableEditEvent</tt>, by adding the content edit to
* the <tt>UndoManager</tt>.
*
* @param e The <tt>UndoableEditEvent</tt>.
*/
public void undoableEditHappened(UndoableEditEvent e) {
public void undoableEditHappened(UndoableEditEvent e)
{
this.undo.addEdit(e.getEdit());
}
/**
* Implements the undo operation.
*/
private void undo() {
try {
private void undo()
{
try
{
undo.undo();
} catch (CannotUndoException e) {
}
catch (CannotUndoException e)
{
logger.error("Unable to undo.", e);
}
}
@ -202,15 +232,20 @@ private void undo() {
/**
* Implements the redo operation.
*/
private void redo() {
try {
private void redo()
{
try
{
undo.redo();
} catch (CannotRedoException e) {
}
catch (CannotRedoException e)
{
logger.error("Unable to redo.", e);
}
}
public void keyTyped(KeyEvent e) {
public void keyTyped(KeyEvent e)
{
}
/**
@ -221,30 +256,30 @@ public void keyTyped(KeyEvent e) {
* Sends typing notifications when user types.
*/
public void keyPressed(KeyEvent e)
{
{
if ((e.getModifiers() & KeyEvent.CTRL_MASK) == KeyEvent.CTRL_MASK
&& (e.getKeyCode() == KeyEvent.VK_Z))
&& (e.getKeyCode() == KeyEvent.VK_Z))
{
if (undo.canUndo())
undo();
}
else if ((e.getModifiers() & KeyEvent.CTRL_MASK) == KeyEvent.CTRL_MASK
&& (e.getKeyCode() == KeyEvent.VK_R))
&& (e.getKeyCode() == KeyEvent.VK_R))
{
if (undo.canRedo())
redo();
}
else if (ConfigurationManager.isSendTypingNotifications()
&& e.getKeyCode() != KeyEvent.VK_ESCAPE)
{
&& e.getKeyCode() != KeyEvent.VK_ESCAPE)
{
if (typingState != OperationSetTypingNotifications.STATE_TYPING)
{
stoppedTypingTimer.setDelay(2 * 1000);
{
stoppedTypingTimer.setDelay(2 * 1000);
typingState = OperationSetTypingNotifications.STATE_TYPING;
int result = chatPanel.sendTypingNotification(typingState);
if(result == ChatPanel.TYPING_NOTIFICATION_SUCCESSFULLY_SENT)
if (result == ChatPanel.TYPING_NOTIFICATION_SUCCESSFULLY_SENT)
typingTimer.start();
}
@ -256,25 +291,27 @@ else if (ConfigurationManager.isSendTypingNotifications()
}
public void keyReleased(KeyEvent e)
{}
{
}
/**
* Listens for <code>stoppedTypingTimer</tt> events.
*/
private class Timer1ActionListener implements ActionListener
private class Timer1ActionListener
implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
{
typingTimer.stop();
if (typingState == OperationSetTypingNotifications.STATE_TYPING)
{
try
{
typingState = OperationSetTypingNotifications.STATE_PAUSED;
int result = chatPanel.sendTypingNotification(typingState);
if(result == ChatPanel.TYPING_NOTIFICATION_SUCCESSFULLY_SENT)
if (result == ChatPanel.TYPING_NOTIFICATION_SUCCESSFULLY_SENT)
stoppedTypingTimer.setDelay(3 * 1000);
}
catch (Exception ex)
@ -282,8 +319,7 @@ public void actionPerformed(ActionEvent e)
logger.error("Failed to send typing notifications.", ex);
}
}
else if (typingState
== OperationSetTypingNotifications.STATE_PAUSED)
else if (typingState == OperationSetTypingNotifications.STATE_PAUSED)
{
stopTypingTimer();
}
@ -293,14 +329,15 @@ else if (typingState
/**
* Listens for <code>typingTimer</tt> events.
*/
private class Timer2ActionListener implements ActionListener
private class Timer2ActionListener
implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if (typingState == OperationSetTypingNotifications.STATE_TYPING)
{
chatPanel.sendTypingNotification(
OperationSetTypingNotifications.STATE_TYPING);
{
chatPanel
.sendTypingNotification(OperationSetTypingNotifications.STATE_TYPING);
}
}
}
@ -311,10 +348,10 @@ public void actionPerformed(ActionEvent e)
public void stopTypingTimer()
{
typingState = OperationSetTypingNotifications.STATE_STOPPED;
int result = chatPanel.sendTypingNotification(typingState);
if(result == ChatPanel.TYPING_NOTIFICATION_SUCCESSFULLY_SENT)
if (result == ChatPanel.TYPING_NOTIFICATION_SUCCESSFULLY_SENT)
stoppedTypingTimer.stop();
}
@ -322,38 +359,126 @@ public void stopTypingTimer()
* Opens the <tt>WritePanelRightButtonMenu</tt> whe user clicks with the
* right mouse button on the editor area.
*/
public void mouseClicked(MouseEvent e) {
public void mouseClicked(MouseEvent e)
{
if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0
|| (e.isControlDown() && !e.isMetaDown())) {
|| (e.isControlDown() && !e.isMetaDown()))
{
Point p = e.getPoint();
SwingUtilities.convertPointToScreen(p, e.getComponent());
rightButtonMenu.setInvoker(editorPane);
rightButtonMenu.setLocation(p.x, p.y);
rightButtonMenu.setVisible(true);
}
}
public void mousePressed(MouseEvent e) {
public void mousePressed(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e) {
public void mouseReleased(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e) {
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e) {
public void mouseExited(MouseEvent e)
{
}
/**
* Returns the <tt>WritePanelRightButtonMenu</tt> opened in this panel.
* Used by the <tt>ChatWindow</tt>, when the ESC button is pressed, to check
* if there is an open menu, which should be closed.
* Used by the <tt>ChatWindow</tt>, when the ESC button is pressed, to
* check if there is an open menu, which should be closed.
*
* @return the <tt>WritePanelRightButtonMenu</tt> opened in this panel
*/
public WritePanelRightButtonMenu getRightButtonMenu()
{
return rightButtonMenu;
}
}
/**
* Returns the write area text as an html text.
*
* @return the write area text as an html text.
*/
public String getTextAsHtml()
{
String msgText = editorPane.getText();
String formattedString = extractFormattedText(msgText);
return formattedString
.substring(0, formattedString.lastIndexOf("\n"));
}
/**
* Returns the write area text as a plain text without any formatting.
*
* @return the write area text as a plain text without any formatting.
*/
public String getText()
{
try
{
Document doc = editorPane.getDocument();
return doc.getText(0, doc.getLength());
}
catch (BadLocationException e)
{
logger.error("Could not obtain write area text.", e);
}
return null;
}
/**
* Clears write message area.
*/
public void clearWriteArea()
{
try
{
this.editorPane.getDocument()
.remove(0, editorPane.getDocument().getLength());
}
catch (BadLocationException e)
{
logger.error("Failed to obtain write panel document content.", e);
}
}
/**
* Return all html paragraph content separated by <BR/> tags.
*
* @param msgText the html text.
* @return the string containing only paragraph content.
*/
private String extractFormattedText(String msgText)
{
int firstIndex = msgText.indexOf("<p");
if (firstIndex != -1)
{
int lastIndex = msgText.indexOf("</p>", firstIndex);
if (lastIndex < 0)
lastIndex = msgText.length();
int firstTagClosureIndex = msgText.indexOf('>', firstIndex);
String pString = msgText
.substring(firstTagClosureIndex+1, lastIndex).trim();
return pString + "\n"
+ extractFormattedText(msgText.substring(lastIndex+1));
}
return "";
}
}

@ -26,8 +26,6 @@ public class MenusPanel
{
private MessageWindowMenuBar menuBar;
private EditTextToolBar editTextToolBar = new EditTextToolBar();
private MainToolBar mainToolBar;
private ChatWindow parentWindow;
@ -58,7 +56,6 @@ public MenusPanel(ChatWindow parentWindow)
parentWindow.setJMenuBar(menuBar);
this.add(mainToolBar, BorderLayout.CENTER);
// this.add(editTextToolBar);
}
/**

@ -375,16 +375,19 @@ public void updateContactStatus(Contact contact, PresenceStatus newStatus)
* appropriate operation set and sends the message, contained in the write
* area, through it.
*/
protected void sendMessage(String text)
protected void sendMessage()
{
if (sendSmsCheckBox.isSelected())
{
this.sendSmsMessage(text);
this.sendSmsMessage();
return;
}
this.sendInstantMessage(text);
this.sendInstantMessage();
//make sure the focus goes back to the write area
this.requestFocusInWriteArea();
}
/**
@ -456,7 +459,7 @@ public void protoContactMoved(ProtoContactEvent evt)
}
if (evt.getNewParent().equals(metaContact))
{
{
contactSelectorBox.addProtoContact(evt.getProtoContact());
}
}
@ -765,8 +768,13 @@ public void inviteChatContact(String contactAddress, String reason)
{
}
private void sendSmsMessage(String text)
private void sendSmsMessage()
{
final String text = this.getTextFromWriteArea(
OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
this.refreshWriteArea();
OperationSetSmsMessaging smsOpSet = null;
/*
Contact contact = null;
@ -888,7 +896,7 @@ private void sendSmsMessage(String text)
smsDialog.setVisible(true);
}
private void sendInstantMessage(String text)
private void sendInstantMessage()
{
Contact contact = (Contact) contactSelectorBox.getMenu()
.getSelectedObject();
@ -901,7 +909,27 @@ private void sendInstantMessage(String text)
= (OperationSetTypingNotifications) contact.getProtocolProvider()
.getOperationSet(OperationSetTypingNotifications.class);
Message msg = im.createMessage(text);
String htmlText = getTextFromWriteArea("text/html");
String plainText = getTextFromWriteArea(
OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
System.out.println("HTML==========" + htmlText);
System.out.println("HTML==========" + plainText);
Message msg;
if (im.isContentTypeSupported("text/html")
&& !htmlText.equals(plainText))
{
msg = im.createMessage( htmlText.getBytes(),
"text/html",
"utf-8",
"");
}
else
{
msg = im.createMessage(plainText);
}
this.refreshWriteArea();
if (tn != null)
{
@ -1066,4 +1094,19 @@ else if (evt.getErrorCode()
public void messageReceived(MessageReceivedEvent evt)
{}
}
/**
* Returns the selected protocol contact.
*
* @return the selected protocol contact
*/
public Contact getSelectedProtocolContact()
{
return contactSelectorBox.getSelectedProtocolContact();
}
public ProtocolContactSelectorBox getProtocolContactSelectorBox()
{
return contactSelectorBox;
}
}

@ -282,29 +282,31 @@ public void run()
* <br>
* Sends a message to the chat room.
*/
protected void sendMessage(String text)
protected void sendMessage()
{
ChatRoom chatRoom = chatRoomWrapper.getChatRoom();
Message msg = chatRoom.createMessage(text);
String msgText = this.getTextFromWriteArea(
OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
Message msg = chatRoom.createMessage(msgText);
try
{
{
chatRoom.sendMessage(msg);
}
catch (IllegalStateException ex)
{
logger.error("Failed to send message.", ex);
this.refreshWriteArea();
this.processMessage(
chatRoom.getName(),
new Date(System.currentTimeMillis()),
Constants.OUTGOING_MESSAGE,
msg.getContent(),
msg.getContentType());
this.processMessage(
chatRoom.getName(),
new Date(System.currentTimeMillis()),
@ -315,16 +317,16 @@ protected void sendMessage(String text)
catch (Exception ex)
{
logger.error("Failed to send message.", ex);
this.refreshWriteArea();
this.processMessage(
chatRoom.getName(),
new Date(System.currentTimeMillis()),
Constants.OUTGOING_MESSAGE,
msg.getContent(),
msg.getContentType());
this.processMessage(
chatRoom.getName(),
new Date(System.currentTimeMillis()),

@ -1,61 +1,69 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*
* Distributable under LGPL license. See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.gui.main.chat.toolBars;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import net.java.sip.communicator.impl.gui.customcontrols.*;
import net.java.sip.communicator.impl.gui.main.chat.*;
import net.java.sip.communicator.impl.gui.utils.*;
/**
* The <tt>EditTextToolBar</tt> is a <tt>JToolBar</tt> which contains buttons
* for formatting a text, like make text in bold or italic, change the font,
* etc. It contains only <tt>MsgToolbarButton</tt>s, which have a specific
* background icon and rollover behaviour to differentiates them from normal
* buttons.
*
* The <tt>EditTextToolBar</tt> is a <tt>JToolBar</tt> which contains
* buttons for formatting a text, like make text in bold or italic, change the
* font, etc. It contains only <tt>MsgToolbarButton</tt>s, which have a
* specific background icon and rollover behaviour to differentiates them from
* normal buttons.
*
* @author Yana Stamcheva
*/
public class EditTextToolBar extends SIPCommToolBar {
private SIPCommButton textBoldButton = new SIPCommButton(ImageLoader
.getImage(ImageLoader.TEXT_BOLD_BUTTON), ImageLoader
.getImage(ImageLoader.TEXT_BOLD_ROLLOVER_BUTTON));
public class EditTextToolBar
extends SIPCommToolBar
{
private JLabel colorLabel = new JLabel();
private SIPCommButton textItalicButton = new SIPCommButton(ImageLoader
.getImage(ImageLoader.TEXT_ITALIC_BUTTON), ImageLoader
.getImage(ImageLoader.TEXT_ITALIC_ROLLOVER_BUTTON));
private String[] fontSizeConstants =
new String[]
{ "9", "10", "11", "12", "13", "14", "18", "24", "36", "48", "64",
"72", "96", "144", "288" };
private SIPCommButton textUnderlinedButton = new SIPCommButton(ImageLoader
.getImage(ImageLoader.TEXT_UNDERLINED_BUTTON), ImageLoader
.getImage(ImageLoader.TEXT_UNDERLINED_ROLLOVER_BUTTON));
private JComboBox fontSizeCombo = new JComboBox(fontSizeConstants);
private SIPCommButton alignLeftButton = new SIPCommButton(ImageLoader
.getImage(ImageLoader.ALIGN_LEFT_BUTTON), ImageLoader
.getImage(ImageLoader.ALIGN_LEFT_ROLLOVER_BUTTON));
private JComboBox fontNameCombo;
private SIPCommButton alignRightButton = new SIPCommButton(ImageLoader
.getImage(ImageLoader.ALIGN_RIGHT_BUTTON), ImageLoader
.getImage(ImageLoader.ALIGN_RIGHT_ROLLOVER_BUTTON));
private JEditorPane chatEditorPane;
private SIPCommButton alignCenterButton = new SIPCommButton(ImageLoader
.getImage(ImageLoader.ALIGN_CENTER_BUTTON), ImageLoader
.getImage(ImageLoader.ALIGN_CENTER_ROLLOVER_BUTTON));
Action boldAction = new HTMLEditorKit.BoldAction();
private JComboBox fontSizeCombo = new JComboBox();
Action italicAction = new HTMLEditorKit.ItalicAction();
private JComboBox fontNameCombo = new JComboBox();
Action underlineAction = new HTMLEditorKit.UnderlineAction();
/**
* Creates an instance and constructs the <tt>EditTextToolBar</tt>.
*/
public EditTextToolBar() {
public EditTextToolBar(JEditorPane panel)
{
this.chatEditorPane = panel;
this.fontNameCombo = new JComboBox(getSystemFontFamilies());
this.fontSizeCombo.setEditable(true);
fontNameCombo.setSelectedItem(ApplicationProperties
.getProperty("fontName"));
fontSizeCombo.setSelectedItem(ApplicationProperties
.getProperty("fontSize"));
this.setRollover(true);
this.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 0));
@ -63,9 +71,9 @@ public EditTextToolBar() {
this.fontSizeCombo.setPreferredSize(new Dimension(55, 21));
this.add(textBoldButton);
this.add(textItalicButton);
this.add(textUnderlinedButton);
colorLabel.setPreferredSize(new Dimension(25, 25));
this.initToolbarButtons();
this.addSeparator();
@ -74,8 +82,224 @@ public EditTextToolBar() {
this.addSeparator();
this.add(alignLeftButton);
this.add(alignCenterButton);
this.add(alignRightButton);
this.add(colorLabel);
fontNameCombo.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent evt)
{
String fontName = (String) evt.getItem();
ActionEvent actionEvent =
new ActionEvent(chatEditorPane,
ActionEvent.ACTION_PERFORMED, "");
Action action =
new HTMLEditorKit.FontFamilyAction(fontName, fontName);
action.actionPerformed(actionEvent);
chatEditorPane.requestFocus();
}
});
fontSizeCombo.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
ActionEvent evt =
new ActionEvent(chatEditorPane,
ActionEvent.ACTION_PERFORMED, "");
String fontSizeString =
(String) fontSizeCombo.getSelectedItem();
Action action =
new HTMLEditorKit.FontSizeAction(fontSizeString,
new Integer(fontSizeString).intValue());
action.actionPerformed(evt);
chatEditorPane.requestFocus();
}
});
colorLabel.setOpaque(true);
colorLabel.setBackground(Color.BLACK);
colorLabel.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent arg0)
{
Color newColor =
JColorChooser.showDialog(new JColorChooser(),
"Choose a colour", colorLabel.getBackground());
colorLabel.setBackground(newColor);
ActionEvent evt =
new ActionEvent(chatEditorPane,
ActionEvent.ACTION_PERFORMED, "");
Action action =
new HTMLEditorKit.ForegroundAction(new Integer(newColor
.getRGB()).toString(), newColor);
action.actionPerformed(evt);
chatEditorPane.requestFocus();
}
});
}
private void initToolbarButtons()
{
JToggleButton boldButton =
initStyleToggleButton(boldAction, StyleConstants.Bold);
boldButton.setIcon(new ImageIcon(ImageLoader
.getImage(ImageLoader.TEXT_BOLD_BUTTON)));
this.add(boldButton);
JToggleButton italicButton =
initStyleToggleButton(italicAction, StyleConstants.Italic);
italicButton.setIcon(new ImageIcon(ImageLoader
.getImage(ImageLoader.TEXT_ITALIC_BUTTON)));
this.add(italicButton);
JToggleButton underlineButton =
initStyleToggleButton(underlineAction, StyleConstants.Underline);
underlineButton.setIcon(new ImageIcon(ImageLoader
.getImage(ImageLoader.TEXT_UNDERLINED_BUTTON)));
this.add(underlineButton);
this.addBindings();
}
private JToggleButton initStyleToggleButton(final Action action,
final Object styleConstant)
{
final JToggleButton button = new JToggleButton();
button.setPreferredSize(new Dimension(25, 25));
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
action.actionPerformed(e);
}
});
chatEditorPane.addCaretListener(new CaretListener()
{
public void caretUpdate(CaretEvent e)
{
selectButton(styleConstant, button);
}
});
chatEditorPane.addKeyListener(new KeyAdapter()
{
public void keyTyped(KeyEvent e)
{
button.setSelected(((HTMLEditorKit) chatEditorPane
.getEditorKit()).getInputAttributes().containsAttribute(
styleConstant, true));
}
});
chatEditorPane.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
selectButton(styleConstant, button);
}
});
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
chatEditorPane.requestFocus();
}
});
return button;
}
/**
* Selects or deselects the given toggle button depending on the given
* <tt>styleConstant</tt>.
*
* @param styleConstant
* @param button
*/
private void selectButton( final Object styleConstant,
final JToggleButton button)
{
boolean selected = false;
if (chatEditorPane.getSelectedText() == null)
{
int index = chatEditorPane.getCaretPosition();
selected =
((HTMLDocument) chatEditorPane.getDocument())
.getCharacterElement(index - 1).getAttributes()
.containsAttribute(styleConstant, true);
}
else
{
for (int index = chatEditorPane.getSelectionStart();
index < chatEditorPane.getSelectionEnd(); index++)
{
AttributeSet attributes =
((HTMLDocument) chatEditorPane.getDocument())
.getCharacterElement(index).getAttributes();
selected =
selected
|| attributes.containsAttribute(styleConstant, true);
}
}
button.setSelected(selected);
}
/**
* Adds key bindings for formatting actions.
*/
private void addBindings()
{
InputMap inputMap = chatEditorPane.getInputMap();
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE,
Event.SHIFT_MASK), DefaultEditorKit.deletePrevCharAction);
// styles
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_B, Event.CTRL_MASK),
"font-bold"); //$NON-NLS-1$
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_F, Event.CTRL_MASK),
"font-bold"); //$NON-NLS-1$
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_I, Event.CTRL_MASK),
"font-italic"); //$NON-NLS-1$
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_K, Event.CTRL_MASK),
"font-italic"); //$NON-NLS-1$
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_U, Event.CTRL_MASK),
"font-underline"); //$NON-NLS-1$
}
/**
* Returns all supported local system font names.
*
* @return an array containing all supported local system font names.
*/
private String[] getSystemFontFamilies()
{
// Get all font family names
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
return ge.getAvailableFontFamilyNames();
}
}

@ -403,7 +403,8 @@ public void messageDelivered(MessageDeliveredEvent evt)
.getDestinationContact().getProtocolProvider();
logger.trace("MESSAGE DELIVERED: process message to chat for contact: "
+ evt.getDestinationContact().getAddress());
+ evt.getDestinationContact().getAddress()
+ " MESSAGE: " + msg.getContent());
chatPanel.processMessage(this.mainFrame
.getAccount(protocolProvider), evt.getTimestamp(),

@ -100,6 +100,10 @@ public class OperationSetBasicInstantMessagingIcqImpl
*/
private final static long KEEPALIVE_WAIT = 20000l; //20 secs
private final String defaultHtmlStartTag = "<HTML><BODY>";
private final String defaultHtmlEndTag = "</BODY></HTML>";
/**
* The task sending packets
*/
@ -176,8 +180,11 @@ public void removeMessageListener(MessageListener listener)
public Message createMessage(byte[] content, String contentType,
String contentEncoding, String subject)
{
return new MessageIcqImpl(new String(content), contentType
, contentEncoding, subject, null);
return new MessageIcqImpl( new String(content),
contentType,
contentEncoding,
subject,
null);
}
/**
@ -219,18 +226,26 @@ public void sendInstantMessage(Contact to, Message message)
getImConversation(
new Screenname(to.getAddress()));
String messageContent = null;
if (message.getContentType().equals(CONTENT_TYPE_HTML)
&& !message.getContent().startsWith(defaultHtmlStartTag))
{
messageContent = defaultHtmlStartTag
+ message.getContent()
+ defaultHtmlEndTag;
}
else
messageContent = message.getContent();
if (to.getPresenceStatus().isOnline())
{
//do not add the conversation listener in here. we'll add it
//inside the icbm listener
imConversation.sendMessage(new SimpleMessage(message.getContent()));
imConversation.sendMessage(new SimpleMessage(messageContent));
}
else
imConversation.sendMessage(new SimpleMessage(message.getContent())
, true);
imConversation.sendMessage(new SimpleMessage(messageContent), true);
//temporarily and uglity fire the sent event here.
/** @todo move elsewhaere */
MessageDeliveredEvent msgDeliveredEvt
= new MessageDeliveredEvent(
message, to, new Date());
@ -388,7 +403,7 @@ public boolean isOfflineMessagingSupported()
public boolean isContentTypeSupported(String contentType)
{
if(contentType.equals(DEFAULT_MIME_TYPE) ||
(contentType.equals(CONTENT_TYPE_HTML) && !icqProvider.USING_ICQ) )
(contentType.equals(CONTENT_TYPE_HTML)))
return true;
else
return false;
@ -568,12 +583,18 @@ public void gotMessage(Conversation conversation, MessageInfo minfo)
return;
}
Message newMessage = null;
if(icqProvider.USING_ICQ)
newMessage = createMessage(msgBody);
String msgContent;
if (msgBody.startsWith(defaultHtmlStartTag))
{
msgContent = msgBody.substring(
msgBody.indexOf(defaultHtmlStartTag)
+ defaultHtmlStartTag.length(),
msgBody.indexOf(defaultHtmlEndTag));
}
else
newMessage = createMessage(msgBody.getBytes(),
msgContent = msgBody;
Message newMessage = createMessage(msgContent.getBytes(),
CONTENT_TYPE_HTML, DEFAULT_MIME_ENCODING, null);
Contact sourceContact =

Loading…
Cancel
Save