From e8fe100501c4724edfe9c24cdb3356c34fc635ae Mon Sep 17 00:00:00 2001 From: Yana Stamcheva Date: Wed, 10 Oct 2012 14:56:47 +0000 Subject: [PATCH] - Fixes status messages appearing as a broken user message - Makes history messages grey. - Makes available both chat themes: simple and advanced, that can be alternated from the Tools menu. - Groups message counting 1min from the last send message from the same user - Fixes history arrows. - Makes contact address available on hover for the simple theme. - Applies patch from Ivan Vergiliev removing yellow background from chat area when the corrected message will be send as a new message. - Fixes "edited at" appearing in the write area when editing an already edited message --- resources/styles/defaultStyle.css | 17 +- .../gui/main/chat/ChatConversationPanel.java | 303 ++++++++++-------- .../impl/gui/main/chat/ChatHtmlUtils.java | 207 +++++++----- .../impl/gui/main/chat/ChatPanel.java | 63 ++-- .../gui/main/chat/IncomingMessageStyle.java | 49 +++ .../gui/main/chat/history/DatesPanel.java | 4 +- .../impl/gui/main/chat/menus/OptionsMenu.java | 13 +- 7 files changed, 419 insertions(+), 237 deletions(-) diff --git a/resources/styles/defaultStyle.css b/resources/styles/defaultStyle.css index fae347128..80814fa5e 100644 --- a/resources/styles/defaultStyle.css +++ b/resources/styles/defaultStyle.css @@ -9,25 +9,15 @@ h1 h2 { - width: 100%; margin: 0px; - /* - padding-top: 4px; - padding-left: 10px; - */ - font-size: 9px; + font-size: 10px; color: #488fe7; } h3 { - width: 100%; margin: 0px; - /* - padding-top: 4px; - padding-left: 10px; - */ - font-size: 9px; + font-size: 10px; color: #535353; } @@ -54,6 +44,7 @@ h6 font-weight: bold; color: #990000; } + p { margin: 0px; @@ -71,4 +62,4 @@ div h7 { background-color: #FFF4AB; -} +} \ No newline at end of file diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java index 922c93985..23fc0b0f5 100755 --- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java @@ -331,7 +331,7 @@ public void setBounds(int x, int y, int width, int height) /** * Retrieves the contents of the sent message with the given ID. - * + * * @param messageUID The ID of the message to retrieve. * @return The contents of the message, or null if the message is not found. */ @@ -354,6 +354,18 @@ public String getMessageContents(String messageUID) try { res = document.getText(e.getStartOffset(), elemLen); + + // Check if an "edited at" tag has been added and remove it before + // returning the string + String editedAtString = GuiActivator.getResources() + .getI18NString( "service.gui.EDITED_AT"); + + int editedAtIndex + = res.indexOf("(" + editedAtString.substring( + 0, editedAtString.indexOf("{0}"))); + + if (editedAtIndex > 0) + res = res.substring(0, editedAtIndex); } catch (BadLocationException exc) { @@ -431,6 +443,7 @@ public String processMessage( ChatMessage chatMessage, date, formatMessage(message, contentType, keyword), contentType, + false, isSimpleTheme); } else if (messageType.equals(Chat.OUTGOING_MESSAGE)) @@ -443,6 +456,7 @@ else if (messageType.equals(Chat.OUTGOING_MESSAGE)) date, formatMessage(message, contentType, keyword), contentType, + false, isSimpleTheme); } else if (messageType.equals(Chat.HISTORY_INCOMING_MESSAGE)) @@ -457,6 +471,7 @@ else if (messageType.equals(Chat.HISTORY_INCOMING_MESSAGE)) date, formatMessage(message, contentType, keyword), contentType, + true, isSimpleTheme); } else if (messageType.equals(Chat.HISTORY_OUTGOING_MESSAGE)) @@ -469,6 +484,7 @@ else if (messageType.equals(Chat.HISTORY_OUTGOING_MESSAGE)) date, formatMessage(message, contentType, keyword), contentType, + true, isSimpleTheme); } else if (messageType.equals(Chat.SMS_MESSAGE)) @@ -481,6 +497,7 @@ else if (messageType.equals(Chat.SMS_MESSAGE)) date, formatMessage("SMS: " + message, contentType, keyword), contentType, + false, isSimpleTheme); } else if (messageType.equals(Chat.STATUS_MESSAGE)) @@ -558,6 +575,9 @@ public void appendConsecutiveMessage( final ChatMessage chatMessage, final String keyword, final String contentType) { + String previousMessageUID = lastMessageUID; + lastMessageUID = chatMessage.getMessageUID(); + if (!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeLater(new Runnable() @@ -573,12 +593,19 @@ public void run() } Element lastMsgElement = document.getElement( - ChatHtmlUtils.MESSAGE_TEXT_ID + lastMessageUID); + ChatHtmlUtils.MESSAGE_TEXT_ID + previousMessageUID); String contactAddress = (String) lastMsgElement.getAttributes() .getAttribute(Attribute.NAME); + boolean isHistory + = (chatMessage.getMessageType() + .equals(Chat.HISTORY_INCOMING_MESSAGE) + || chatMessage.getMessageType() + .equals(Chat.HISTORY_OUTGOING_MESSAGE)) + ? true : false; + String newMessage = ChatHtmlUtils.createMessageTag( chatMessage.getMessageUID(), contactAddress, @@ -588,6 +615,7 @@ public void run() contentType, chatMessage.getDate(), false, + isHistory, isSimpleTheme); synchronized (scrollToBottomRunnable) @@ -598,14 +626,6 @@ public void run() document.insertBeforeEnd(parentElement, newMessage); - replaceMessageDivID( - document.getElement( - ChatHtmlUtils.MESSAGE_DIV_ID + lastMessageUID), - lastMessageUID, - chatMessage.getMessageUID()); - - lastMessageUID = chatMessage.getMessageUID(); - // Need to call explicitly scrollToBottom, because for some // reason the componentResized event isn't fired every time // we add text. @@ -633,6 +653,8 @@ public void run() */ public void correctMessage(final ChatMessage chatMessage) { + lastMessageUID = chatMessage.getMessageUID(); + if (!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeLater(new Runnable() @@ -662,6 +684,13 @@ public void run() = (String) correctedMsgElement.getAttributes() .getAttribute(Attribute.NAME); + boolean isHistory + = (chatMessage.getMessageType() + .equals(Chat.HISTORY_INCOMING_MESSAGE) + || chatMessage.getMessageType() + .equals(Chat.HISTORY_OUTGOING_MESSAGE)) + ? true : false; + String newMessage = ChatHtmlUtils.createMessageTag( chatMessage.getMessageUID(), contactAddress, @@ -671,6 +700,7 @@ public void run() chatMessage.getContentType(), chatMessage.getDate(), true, + isHistory, isSimpleTheme); synchronized (scrollToBottomRunnable) @@ -679,8 +709,6 @@ public void run() { document.setOuterHTML(correctedMsgElement, newMessage); - lastMessageUID = chatMessage.getMessageUID(); - // Need to call explicitly scrollToBottom, because for some // reason the componentResized event isn't fired every time // we add text. @@ -750,14 +778,12 @@ public void run() } } - int lastMsgStartIndex = message.indexOf("
0) + String lastElemContent = getElementContent(lastMessageUID, message); + + if (lastElemContent != null) finishMessageAdd( - message.substring( - lastMsgStartIndex, - message.indexOf("
", lastMsgStartIndex) + 6), + getElementContent(lastMessageUID, message), contentType); } @@ -770,8 +796,6 @@ public void run() */ private void finishMessageAdd(String message, String contentType) { - Element root = document.getDefaultRootElement(); - // If we're not in chat history case we need to be sure the document // has not exceeded the required size (number of messages). if (!isHistory) @@ -941,47 +965,21 @@ private void ensureDocumentSize() { if (document.getLength() > Chat.CHAT_BUFFER_SIZE) { - int msgElementCount = 0; - - Element firstMsgElement = null; + String[] ids = new String[] + {ChatHtmlUtils.MESSAGE_TEXT_ID, + "statusMessage", + "systemMessage", + "actionMessage"}; - // The root element. - Element root = document.getDefaultRootElement(); + Element firstMsgElement = findElement(Attribute.ID, ids); - // The body element. - Element bodyElement = root.getElement(root.getElementCount() - 1); - - // Count how many messages we have in the document. - for (int i = 0; i < bodyElement.getElementCount(); i++) - { - String idAttr = (String) bodyElement.getElement(i) - .getAttributes().getAttribute(Attribute.ID); - - if(idAttr != null - && (idAttr.startsWith(ChatHtmlUtils.MESSAGE_DIV_ID) - || idAttr.equals("statusMessage") - || idAttr.equals("systemMessage") - || idAttr.equals("actionMessage"))) - { - if(firstMsgElement == null) - { - firstMsgElement = bodyElement.getElement(i); - } - - msgElementCount++; - } - } - // If we doesn't have any known elements in the document or if we - // have only one long message we don't want to remove it. - if(firstMsgElement == null || msgElementCount < 2) - return; + int startIndex = firstMsgElement.getStartOffset(); + int endIndex = firstMsgElement.getEndOffset(); try { // Remove the message. - this.document.remove(firstMsgElement.getStartOffset(), - firstMsgElement.getEndOffset() - - firstMsgElement.getStartOffset()); + this.document.remove(startIndex, endIndex - startIndex); } catch (BadLocationException e) { @@ -1350,6 +1348,7 @@ public void clear() this.document = (HTMLDocument) editorKit.createDefaultDocument(); Constants.loadSimpleStyle( document.getStyleSheet(), chatTextPane.getFont()); + this.isSimpleTheme = ConfigurationManager.isChatSimpleThemeEnabled(); } /** @@ -1440,17 +1439,9 @@ public Date getPageLastMsgTimestamp() return new Date(0); Element lastMsgElement = document.getElement( - ChatHtmlUtils.MESSAGE_DIV_ID + lastMessageUID); - - Element lastHeaderElement = document.getElement( - lastMsgElement, - Attribute.ID, - ChatHtmlUtils.MESSAGE_HEADER_ID); - - if(lastHeaderElement == null) - return new Date(0); + ChatHtmlUtils.MESSAGE_TEXT_ID + lastMessageUID); - String dateObject = lastHeaderElement + String dateObject = lastMsgElement .getAttributes().getAttribute(ChatHtmlUtils.DATE_ATTRIBUTE) .toString(); @@ -1592,8 +1583,8 @@ public void addComponent(ChatConversationComponent component) wrapPanel.add(component, BorderLayout.NORTH); style.addAttribute(StyleConstants.ComponentAttribute, wrapPanel); - style.addAttribute(Attribute.ID, ChatHtmlUtils.MESSAGE_DIV_ID); - style.addAttribute( ChatHtmlUtils.DATE_ATTRIBUTE, + style.addAttribute(Attribute.ID, ChatHtmlUtils.MESSAGE_TEXT_ID); + style.addAttribute(ChatHtmlUtils.DATE_ATTRIBUTE, component.getDate().getTime()); scrollToBottomIsPending = true; @@ -1809,65 +1800,6 @@ private static String getContactAvatar( "service.gui.DEFAULT_USER_PHOTO_SMALL").toString(); } - /** - * Replaces message div tag identifier. - * - * @param messageDivElement - * @param lastMessageUID - * @param newMessageUID - */ - private void replaceMessageDivID( Element messageDivElement, - String lastMessageUID, - String newMessageUID) - { - StringWriter msgDivWriter = new StringWriter(); - - try - { - editorKit.write(msgDivWriter, - document, - 0, - document.getLength()); - - String msgDivString = msgDivWriter.toString(); - String newMsgDivString - = msgDivString.replaceFirst( - ChatHtmlUtils.MESSAGE_DIV_ID + lastMessageUID, - ChatHtmlUtils.MESSAGE_DIV_ID + newMessageUID); - - // Find the first index of the element. - int msgStartIndex = newMsgDivString.indexOf( - "
0) - { - msgEndIndex = newMsgDivString - .substring(msgStartIndex, nextDivIndex) - .lastIndexOf("
"); - } - else - msgEndIndex = newMsgDivString.lastIndexOf(""); - - document.setOuterHTML( - messageDivElement, - newMsgDivString.substring(msgStartIndex, msgEndIndex + 6)); - } - catch (IOException e) - { - e.printStackTrace(); - } - catch (BadLocationException e) - { - e.printStackTrace(); - } - } - /** * Indicates if this is a consecutive message. * @@ -1894,11 +1826,21 @@ private boolean isConsecutiveMessage(ChatMessage chatMessage) .getAttribute(Attribute.NAME); if (contactAddress != null + && (chatMessage.getMessageType() + .equals(Chat.INCOMING_MESSAGE) + || chatMessage.getMessageType() + .equals(Chat.OUTGOING_MESSAGE) + || chatMessage.getMessageType() + .equals(Chat.HISTORY_INCOMING_MESSAGE) + || chatMessage.getMessageType() + .equals(Chat.HISTORY_OUTGOING_MESSAGE)) && contactAddress.equals(chatMessage.getContactName()) // And if the new message is within a minute from the last one. && ((chatMessage.getDate() - lastMessageTimestamp) < 60000)) { + lastMessageTimestamp = chatMessage.getDate(); + return true; } @@ -1915,4 +1857,113 @@ public void dispose() clear(); } + + /** + * + * @param attribute + * @param matchStrings + * @return + */ + private Element findElement(HTML.Attribute attribute, + String[] matchStrings) + { + return findFirstElement(document.getDefaultRootElement(), + attribute, + matchStrings); + } + + /** + * + * @param attribute + * @param matchStrings + * @return + */ + private Element findFirstElement(String name) + { + return findFirstElement(document.getDefaultRootElement(), name); + } + + /** + * + * @param element + * @param attrName + * @param matchStrings + * @return + */ + private Element findFirstElement( Element element, + HTML.Attribute attrName, + String[] matchStrings) + { + String attr = (String) element.getAttributes().getAttribute(attrName); + + if(attr != null) + for (String matchString : matchStrings) + if (attr.startsWith(matchString)) + return element; + + Element resultElement = null; + + // Count how many messages we have in the document. + for (int i = 0; i < element.getElementCount(); i++) + { + resultElement = findFirstElement(element.getElement(i), + attrName, + matchStrings); + if (resultElement != null) + return resultElement; + } + + return null; + } + + /** + * + * @param element + * @param attrName + * @param matchStrings + * @return + */ + private Element findFirstElement( Element element, + String name) + { + if (element.getName().equalsIgnoreCase(name)) + return element; + + Element resultElement = null; + + // Count how many messages we have in the document. + for (int i = 0; i < element.getElementCount(); i++) + { + resultElement = findFirstElement(element.getElement(i), name); + + if (resultElement != null) + return resultElement; + } + + return null; + } + + /** + * + * @param elementId + * @param message + * @return + */ + private String getElementContent(String elementId, String message) + { + Pattern p = Pattern.compile( + ".*()", Pattern.DOTALL); + + Matcher m = p.matcher(message); + + if (m.find()) + { + return m.group(1); + } + + return null; + } } \ No newline at end of file diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatHtmlUtils.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatHtmlUtils.java index 52269865f..0179d3d1d 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatHtmlUtils.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatHtmlUtils.java @@ -5,6 +5,8 @@ */ package net.java.sip.communicator.impl.gui.main.chat; +import javax.swing.text.html.HTML.Tag; + import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.util.*; @@ -24,11 +26,6 @@ public class ChatHtmlUtils */ public final static String DATE_ATTRIBUTE = "date"; - /** - * The identifier of the message div. - */ - public final static String MESSAGE_DIV_ID = "messageDiv"; - /** * The message header identifier attribute. */ @@ -70,6 +67,7 @@ public class ChatHtmlUtils * @param date the date, when the message was sent * @param message the message content * @param contentType the content type HTML or PLAIN_TEXT + * @param isHistory indicates if this is a message coming from history * @param isSimpleTheme indicates if the simple or the advance theme should * be used * @return the created incoming message tag @@ -82,14 +80,27 @@ public static String createIncomingMessageTag( long date, String message, String contentType, + boolean isHistory, boolean isSimpleTheme) { if (isSimpleTheme) - return createSimpleIncomingMessageTag(messageID, contactName, - contactDisplayName, avatarPath, date, message, contentType); + return createSimpleIncomingMessageTag( messageID, + contactName, + contactDisplayName, + avatarPath, + date, + message, + contentType, + isHistory); else - return createAdvancedIncomingMessageTag(messageID, contactName, - contactDisplayName, avatarPath, date, message, contentType); + return createAdvancedIncomingMessageTag(messageID, + contactName, + contactDisplayName, + avatarPath, + date, + message, + contentType, + isHistory); } /** @@ -103,6 +114,7 @@ public static String createIncomingMessageTag( * @param date the date, when the message was sent * @param message the content of the message * @param contentType the content type HTML or PLAIN_TEXT + * @param isHistory indicates if this is a message coming from history * @param isSimpleTheme indicates if the simple or the advance theme should * be used * @return the created outgoing message tag @@ -114,14 +126,27 @@ public static String createOutgoingMessageTag( String messageID, long date, String message, String contentType, + boolean isHistory, boolean isSimpleTheme) { if (isSimpleTheme) - return createSimpleOutgoingMessageTag(messageID, contactName, - contactDisplayName, avatarPath, date, message, contentType); + return createSimpleOutgoingMessageTag( messageID, + contactName, + contactDisplayName, + avatarPath, + date, + message, + contentType, + isHistory); else - return createAdvancedOutgoingMessageTag(messageID, contactName, - contactDisplayName, avatarPath, date, message, contentType); + return createAdvancedOutgoingMessageTag(messageID, + contactName, + contactDisplayName, + avatarPath, + date, + message, + contentType, + isHistory); } /** @@ -133,6 +158,7 @@ public static String createOutgoingMessageTag( String messageID, * @param contentType the content type (html or plain text) * @param date the date on which the message was sent * @param isEdited indicates if the given message has been edited + * @param isHistory indicates if this is a message coming from history * @param isSimpleTheme indicates if the simple or the advance theme should * be used * @return the newly constructed message tag @@ -143,14 +169,25 @@ public static String createMessageTag( String messageID, String contentType, long date, boolean isEdited, + boolean isHistory, boolean isSimpleTheme) { if (isSimpleTheme) - return createSimpleMessageTag(messageID, contactName, message, - contentType, date, isEdited); + return createSimpleMessageTag( messageID, + contactName, + message, + contentType, + date, + isEdited, + isHistory); else - return createAdvancedMessageTag(messageID, contactName, message, - contentType, date, isEdited); + return createAdvancedMessageTag(messageID, + contactName, + message, + contentType, + date, + isEdited, + isHistory); } /** @@ -164,6 +201,7 @@ public static String createMessageTag( String messageID, * @param date the date, when the message was sent * @param message the message content * @param contentType the content type HTML or PLAIN_TEXT + * @param isHistory indicates if this is a message coming from history * @return the created incoming message tag */ private static String createSimpleIncomingMessageTag( @@ -173,25 +211,27 @@ private static String createSimpleIncomingMessageTag( String avatarPath, long date, String message, - String contentType) + String contentType, + boolean isHistory) { StringBuffer headerBuffer = new StringBuffer(); headerBuffer.append("

"); -// headerBuffer.append(""); + headerBuffer.append(""); headerBuffer.append( contactDisplayName + createEditedAtTag(messageID, -1)); -// headerBuffer.append(""); + headerBuffer.append(""); headerBuffer.append("

"); StringBuffer messageBuff = new StringBuffer(); - messageBuff.append("
"); messageBuff.append(""); messageBuff.append(""); messageBuff.append("
"); @@ -208,9 +248,8 @@ private static String createSimpleIncomingMessageTag( message, contentType, date, - false)); - messageBuff.append(""); - messageBuff.append("
"); + false, + isHistory)); return messageBuff.toString(); } @@ -226,6 +265,7 @@ private static String createSimpleIncomingMessageTag( * @param date the date, when the message was sent * @param message the content of the message * @param contentType the content type HTML or PLAIN_TEXT + * @param isHistory indicates if this is a message coming from history * @return the created outgoing message tag */ private static String createSimpleOutgoingMessageTag( String messageID, @@ -234,25 +274,27 @@ private static String createSimpleOutgoingMessageTag( String messageID, String avatarPath, long date, String message, - String contentType) + String contentType, + boolean isHistory) { StringBuffer headerBuffer = new StringBuffer(); - headerBuffer.append("

"); -// headerBuffer.append(""); + headerBuffer.append(""); headerBuffer.append(contactDisplayName + createEditedAtTag(messageID, -1)); -// headerBuffer.append(""); + headerBuffer.append(""); headerBuffer.append("

"); StringBuffer messageBuff = new StringBuffer(); - messageBuff.append("
"); messageBuff.append(""); messageBuff.append(""); messageBuff.append("
"); @@ -269,9 +311,8 @@ private static String createSimpleOutgoingMessageTag( String messageID, message, contentType, date, - false)); - messageBuff.append(""); - messageBuff.append("
"); + false, + isHistory)); return messageBuff.toString(); } @@ -287,6 +328,7 @@ private static String createSimpleOutgoingMessageTag( String messageID, * @param date the date, when the message was sent * @param message the message content * @param contentType the content type HTML or PLAIN_TEXT + * @param isHistory indicates if this is a message coming from history * @return the created incoming message tag */ private static String createAdvancedIncomingMessageTag( @@ -296,12 +338,14 @@ private static String createAdvancedIncomingMessageTag( String avatarPath, long date, String message, - String contentType) + String contentType, + boolean isHistory) { StringBuffer headerBuffer = new StringBuffer(); headerBuffer.append("

"); + headerBuffer.append(DATE_ATTRIBUTE + "='" + date + "' "); + headerBuffer.append(IncomingMessageStyle.createHeaderStyle() + ">"); headerBuffer.append(""); - messageBuff.append(""); + messageBuff.append("
"); messageBuff.append(""); messageBuff.append(""); messageBuff.append(""); - messageBuff.append(""); messageBuff.append(""); messageBuff.append(""); messageBuff.append("
"); messageBuff.append( @@ -336,7 +380,6 @@ private static String createAdvancedIncomingMessageTag( messageBuff.append("
"); messageBuff.append(""); messageBuff.append("
"); - messageBuff.append(""); return messageBuff.toString(); } @@ -386,6 +429,7 @@ private static String createAdvancedIncomingMessageTag( * @param date the date, when the message was sent * @param message the content of the message * @param contentType the content type HTML or PLAIN_TEXT + * @param isHistory indicates if this is a message coming from history * @return the created outgoing message tag */ private static String createAdvancedOutgoingMessageTag( String messageID, @@ -394,12 +438,14 @@ private static String createAdvancedOutgoingMessageTag( String messageID, String avatarPath, long date, String message, - String contentType) + String contentType, + boolean isHistory) { StringBuffer headerBuffer = new StringBuffer(); - headerBuffer.append("

"); + headerBuffer.append("

"); headerBuffer.append(""); - messageBuff.append(""); + messageBuff.append("
"); messageBuff.append(""); messageBuff.append(""); messageBuff.append(""); - messageBuff.append(""); messageBuff.append(""); // Forth row. @@ -472,7 +518,6 @@ private static String createAdvancedOutgoingMessageTag( String messageID, messageBuff.append(""); messageBuff.append(""); messageBuff.append("
"); messageBuff.append( @@ -445,7 +491,8 @@ private static String createAdvancedOutgoingMessageTag( String messageID, message, contentType, date, - false)); + false, + isHistory)); messageBuff.append("
"); - messageBuff.append(""); return messageBuff.toString(); } @@ -584,6 +629,7 @@ public static String createEditedAtTag(String messageUID, long date) * @param contentType the content type (html or plain text) * @param date the date on which the message was sent * @param isEdited indicates if the given message has been edited + * @param isHistory indicates if this is a message coming from history * @return the newly constructed message tag */ private static String createSimpleMessageTag(String messageID, @@ -591,26 +637,23 @@ private static String createSimpleMessageTag(String messageID, String message, String contentType, long date, - boolean isEdited) + boolean isEdited, + boolean isHistory) { StringBuffer messageTag = new StringBuffer(); messageTag.append("
"); - } - else - messageTag.append(">"); - + messageTag.append(NAME_ATTRIBUTE + "=\"" + contactName + "\" "); + messageTag.append(DATE_ATTRIBUTE + "=\"" + date + "\" "); + messageTag.append(IncomingMessageStyle + .createSingleMessageStyle(isHistory, isEdited, true)); + messageTag.append(">"); messageTag.append(createStartPlainTextTag(contentType)); messageTag.append(message); if (isEdited) - messageTag.append(" (edited at " - + GuiUtils.formatTime(date) + ")"); + messageTag.append(" " + createEditedAt(date)); messageTag.append(createEndPlainTextTag(contentType)); messageTag.append("
"); @@ -626,6 +669,7 @@ private static String createSimpleMessageTag(String messageID, * @param contentType the content type (html or plain text) * @param date the date on which the message was sent * @param isEdited indicates if the given message has been edited + * @param isHistory indicates if this is a message coming from history * @return the newly constructed message tag */ private static String createAdvancedMessageTag( String messageID, @@ -633,24 +677,23 @@ private static String createAdvancedMessageTag( String messageID, String message, String contentType, long date, - boolean isEdited) + boolean isEdited, + boolean isHistory) { StringBuffer messageTag = new StringBuffer(); messageTag.append("
"); - else - messageTag.append("\">"); + messageTag.append(NAME_ATTRIBUTE + "=\"" + contactName + "\" "); + messageTag.append(DATE_ATTRIBUTE + "=\"" + date + "\" "); + messageTag.append(IncomingMessageStyle + .createSingleMessageStyle(isHistory, isEdited, false)); + messageTag.append(">"); messageTag.append(createStartPlainTextTag(contentType)); messageTag.append(message); if (isEdited) - messageTag.append(" (edited at " - + GuiUtils.formatTime(date) + ")"); + messageTag.append(" " + createEditedAt(date)); messageTag.append(createEndPlainTextTag(contentType)); messageTag.append("
"); @@ -676,4 +719,18 @@ public static String getDateString(long date) return ""; } + + /** + * Creates the edited at string. + * + * @param date the date of the re-edition + * @return the newly constructed string + */ + private static String createEditedAt(long date) + { + return "(" + GuiActivator.getResources() + .getI18NString( "service.gui.EDITED_AT", + new String[]{GuiUtils.formatTime(date)}) + + ")"; + } } diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java index 5fe8f7be3..f8e7acb8e 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java @@ -525,7 +525,8 @@ public void localUserRoleChanged(ChatRoomLocalUserRoleChangeEvent evt) * @return the ID of the last message sent in this chat, or null * if no messages have been sent yet. */ - public String getLastSentMessageUID() { + public String getLastSentMessageUID() + { return lastSentMessageUID; } @@ -1596,21 +1597,51 @@ public void startLastMessageCorrection() */ public void startMessageCorrection(String correctedMessageUID) { - this.correctedMessageUID = correctedMessageUID; - this.refreshWriteArea(); - String messageContents - = conversationPanel.getMessageContents(correctedMessageUID); - if (messageContents == null) + if (!showMessageInWriteArea(correctedMessageUID)) { - this.stopMessageCorrection(); return; } - Color bgColor = new Color(GuiActivator.getResources() + if (chatSession.getCurrentChatTransport().allowsMessageCorrections()) + { + this.correctedMessageUID = correctedMessageUID; + Color bgColor = new Color(GuiActivator.getResources() .getColor("service.gui.CHAT_EDIT_MESSAGE_BACKGROUND")); - this.writeMessagePanel.setEditorPaneBackground(bgColor); - this.setMessage(messageContents); + this.writeMessagePanel.setEditorPaneBackground(bgColor); + } + } + + /** + * Shows the last sent message in the write area, either in order to + * correct it or to send it again. + * + * @return true on success, false on failure. + */ + public boolean showLastMessageInWriteArea() + { + return showMessageInWriteArea(lastSentMessageUID); } + /** + * Shows the message with the specified ID in the write area, either + * in order to correct it or to send it again. + * + * @param messageUID The ID of the message to show. + * @return true on success, false on failure. + */ + public boolean showMessageInWriteArea(String messageUID) + { + String messageContents = conversationPanel.getMessageContents( + messageUID); + + if (messageContents == null) + { + return false; + } + this.refreshWriteArea(); + this.setMessage(messageContents); + return true; + } + /** * Exits editing mode, clears the write panel and the background. */ @@ -2761,17 +2792,9 @@ public void showFontChooserDialog() */ public void loadSkin() { - try - { - Document doc - = this.conversationPanel.getChatTextPane().getDocument(); - doc.remove(0, doc.getLength()); - } - catch (BadLocationException ex) - { - logger.error(ex); - } + getChatConversationPanel().clear(); loadHistory(); + getChatConversationPanel().setDefaultContent(); } /** diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/IncomingMessageStyle.java b/src/net/java/sip/communicator/impl/gui/main/chat/IncomingMessageStyle.java index e6e5b4e08..eb2574cfa 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/IncomingMessageStyle.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/IncomingMessageStyle.java @@ -51,6 +51,13 @@ public class IncomingMessageStyle = GuiActivator.getResources().getImageURL( "service.gui.lookandfeel.INCOMING_MESSAGE_CURVES_TOP").toString(); + /** + * The foreground color of history messages. + */ + private final static String HISTORY_FOREGROUND_COLOR + = GuiActivator.getResources().getColorString( + "service.gui.CHAT_HISTORY_FOREGROUND"); + /** * Creates the global message style. * @@ -64,6 +71,37 @@ public static String createMessageStyle() + "\""; } + public static String createSingleMessageStyle( boolean isHistory, + boolean isEdited, + boolean isSimpleTheme) + { + StringBuffer styleBuff = new StringBuffer(); + + if (isSimpleTheme) + styleBuff.append("style=\""); + else + styleBuff.append("style=\"padding-left:10px;"); + + if (isEdited) + { + styleBuff.append("font-style:italic;"); + + if (isHistory) + styleBuff.append("color:#" + HISTORY_FOREGROUND_COLOR + ";\""); + else + styleBuff.append("\""); + } + else + { + if (isHistory) + styleBuff.append("color:#" + HISTORY_FOREGROUND_COLOR + ";\""); + else + styleBuff.append("\""); + } + + return styleBuff.toString().replaceFirst(";\"", "\""); + } + /** * Creates the style of the table bubble right element. * @@ -200,4 +238,15 @@ public static String createAvatarStyle() + " height:26px;" + " float:left;\""; } + + /** + * Creates the header style. + * + * @return the header style. + */ + public static String createHeaderStyle() + { + return "style=\"padding-top: 4px;" + + " padding-left: 10px;\""; + } } diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/history/DatesPanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/history/DatesPanel.java index d7dc41df9..433acaf10 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/history/DatesPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/history/DatesPanel.java @@ -34,9 +34,9 @@ public class DatesPanel private final DefaultListModel listModel = new DefaultListModel(); private final HistoryWindow historyWindow; - + private int lastSelectedIndex = -1; - + /** * Creates an instance of DatesPanel. * diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/menus/OptionsMenu.java b/src/net/java/sip/communicator/impl/gui/main/chat/menus/OptionsMenu.java index e803c15a4..86cc8bfaa 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/menus/OptionsMenu.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/menus/OptionsMenu.java @@ -8,6 +8,7 @@ package net.java.sip.communicator.impl.gui.main.chat.menus; import java.awt.event.*; +import java.util.*; import javax.swing.*; @@ -63,7 +64,7 @@ public OptionsMenu(ChatWindow chatWindow) this.chatSimpleTheme.setActionCommand(ACTCMD_VIEW_SIMPLE_THEME); this.chatSimpleTheme.addActionListener(this); -// this.add(chatSimpleTheme); + this.add(chatSimpleTheme); initValues(); } @@ -106,6 +107,16 @@ else if (action.equals(ACTCMD_VIEW_SIMPLE_THEME)) { ConfigurationManager.setChatSimpleThemeEnabled( chatSimpleTheme.isSelected()); + + List currentChats = chatWindow.getChats(); + if (currentChats != null) + { + Iterator chatsIter = currentChats.iterator(); + while (chatsIter.hasNext()) + { + chatsIter.next().loadSkin(); + } + } } } }