package jimmui.updater; import jimm.Jimm; import jimm.Options; import jimm.comm.StringUtils; import jimmui.view.chat.Chat; import jimmui.model.chat.ChatModel; import jimmui.model.chat.MessData; import jimm.chat.message.Message; import jimm.chat.message.PlainMessage; import jimm.chat.message.SystemNotice; import jimm.comm.Util; import jimm.history.CachedRecord; import jimm.history.HistoryStorage; import jimm.modules.MagicEye; import jimmui.view.base.CanvasEx; import jimmui.view.icons.Icon; import jimmui.view.text.Par; import jimmui.view.text.Parser; import protocol.ui.InfoFactory; /** * Created with IntelliJ IDEA. * <p/> * Date: 05.07.13 22:50 * * @author vladimir */ public class MessageBuilder { public void addMessage(ChatModel model, Message message, boolean toHistory) { Chat chat = Jimm.getJimm().getCL().getChat(model); boolean inc = (null == chat) || !chat.isVisibleChat(); if (message instanceof PlainMessage) { buildMessage(model, message); // #sijapp cond.if modules_HISTORY is "true" # if (toHistory && Options.getBoolean(Options.OPTION_HISTORY)) { final String nick = getFrom(model, message); addToHistory(model, message.getText(), true, nick, message.getNewDate()); } // #sijapp cond.end# if (inc) { model.messageCounter = inc(model.messageCounter); // #sijapp cond.if protocols_JABBER is "true" # if (!model.getContact().isSingleUserContact() && !MessageBuilder.isHighlight(message.getProcessedText(), model.getMyName())) { model.otherMessageCounter = inc(model.otherMessageCounter); model.messageCounter--; } // #sijapp cond.end# } } else if (message instanceof SystemNotice) { SystemNotice notice = (SystemNotice) message; if (SystemNotice.TYPE_NOTICE_AUTHREQ == notice.getMessageType()) { inc = true; model.authRequestCounter = inc(model.authRequestCounter); } else if (inc) { model.sysNoticeCounter = inc(model.sysNoticeCounter); } // #sijapp cond.if modules_MAGIC_EYE is "true" # MagicEye.addAction(model.getProtocol(), model.getContact().getUserId(), message.getText()); // #sijapp cond.end # buildMessage(model, message); } if (inc) { model.getContact().updateChatState(model); } } public void addMyMessage(ChatModel chat, PlainMessage message) { chat.resetUnreadMessages(); buildMessage(chat, message); // #sijapp cond.if modules_HISTORY is "true" # if (Options.getBoolean(Options.OPTION_HISTORY)) { addToHistory(chat, message.getText(), false, getFrom(chat, message), message.getNewDate()); } // #sijapp cond.end# } public MessData buildMessage(ChatModel chat, Message message) { String from = getFrom(chat, message); boolean incoming = message.isIncoming(); String messageText = message.getProcessedText(); messageText = StringUtils.removeCr(messageText); if (StringUtils.isEmpty(messageText)) { return null; } boolean isMe = messageText.startsWith(PlainMessage.CMD_ME); if (isMe) { messageText = messageText.substring(4); if (0 == messageText.length()) { return null; } } Parser parser = createParser(chat, null); final byte captColor = getInOutColor(incoming); final byte plain = CanvasEx.FONT_STYLE_PLAIN; if (isMe) { Icon icon = InfoFactory.msgIcons.iconAt(getIcon(chat, message)); if (null != icon) { parser.addImage(icon); } parser.addText("*", captColor, plain); parser.addText(from, captColor, plain); parser.addText(" ", captColor, plain); parser.addTextWithSmiles(messageText, captColor, plain); } else { byte color = CanvasEx.THEME_TEXT; // #sijapp cond.if protocols_JABBER is "true" # if (incoming && !chat.getContact().isSingleUserContact() && isHighlight(messageText, chat.getMyName())) { color = CanvasEx.THEME_CHAT_HIGHLIGHT_MSG; } // #sijapp cond.end# parser.addTextWithSmiles(messageText, color, plain); } short flags = 0; if (SystemNotice.TYPE_FILE == message.getMessageType()) { parser.addProgress(CanvasEx.THEME_TEXT); flags |= MessData.PROGRESS; } if (incoming) { flags |= MessData.INCOMING; } if (isMe) { flags |= MessData.ME; } if (Util.hasURL(messageText)) { flags |= MessData.URLS; } if (message instanceof SystemNotice) { flags |= MessData.SERVICE; } Par par = parser.getPar(); MessData mData = new MessData(message.getNewDate(), messageText, from, flags, getIcon(chat, message), par); if (!incoming) { message.setVisibleIcon(par, mData); } Chat view = Jimm.getJimm().getCL().getChat(chat); synchronized (chat) { boolean atTheEnd = chatAtTheEnd(view); if (null != view) { view.lock(); } chat.add(mData); setCursor(chat, view, incoming, atTheEnd); Jimm.getJimm().getChatUpdater().removeOldMessages(chat); if (null != view) { Jimm.getJimm().getChatUpdater().restoreTopPositionToUI(chat, view); view.unlock(); } } return mData; } private boolean chatAtTheEnd(Chat chat) { try { return (null == chat) || (chat.getContent().getFullSize() - chat.getContent().getTopOffset() <= chat.getContentHeight()); } catch (Exception ignored) { return true; } } private void setCursor(ChatModel chat, Chat view, boolean incoming, boolean atTheEnd) { int size = chat.size(); if (incoming) { int currentMessageIndex = chat.current; if ((null != view) && view.isVisibleChat()) { // #sijapp cond.if modules_TOUCH is "true"# if (atTheEnd) { atTheEnd = (currentMessageIndex == size - 2); if (view.touchUsed) { atTheEnd = true; } } // #sijapp cond.end# if (atTheEnd) { chat.current = chat.size() - 1; } } else { int unread = chat.getUnreadMessageCount(); if (size - unread - 2 <= currentMessageIndex) { chat.current = Math.max(0, size - 1 - unread); chat.bottomOffset = -1; } } } else if (chat.isBlogBot()) { if (atTheEnd) { chat.current = chat.size() - 1; } } else { chat.bottomOffset = -1; chat.current = chat.size() - 1; } } private int getIcon(ChatModel chat, Message message) { if (message instanceof SystemNotice) { int type = ((SystemNotice)message).getMessageType(); if (SystemNotice.TYPE_NOTICE_MESSAGE == type) { return Message.ICON_NONE; } if (SystemNotice.TYPE_FILE == type) { return Message.ICON_NONE; } return Message.ICON_SYSREQ; } if (message.isIncoming()) { // #sijapp cond.if protocols_JABBER is "true" # if (!chat.getContact().isSingleUserContact() && !isHighlight(message.getProcessedText(), chat.getMyName())) { return Message.ICON_IN_MSG; } // #sijapp cond.end# return Message.ICON_IN_MSG_HI; } return Message.ICON_OUT_MSG; } private byte getInOutColor(boolean incoming) { return incoming ? CanvasEx.THEME_CHAT_INMSG : CanvasEx.THEME_CHAT_OUTMSG; } private Parser createParser(ChatModel chat, Par par) { if (null == par) { return new Parser(chat.fontSet, Jimm.getJimm().getDisplay().getMinScreenMetrics() - 3); } else { return new Parser(par, chat.fontSet, Jimm.getJimm().getDisplay().getMinScreenMetrics() - 3); } } private String getFrom(ChatModel chat, Message message) { String senderName = message.getName(); if (null == senderName) { senderName = message.isIncoming() ? chat.getContact().getName() : chat.getMyName(); } return senderName; } // #sijapp cond.if protocols_JABBER is "true" # public static boolean isHighlight(String text, String nick) { if (null == nick) { return false; } for (int index = text.indexOf(nick); -1 != index; index = text.indexOf(nick, index + 1)) { if (0 < index) { char before = text.charAt(index - 1); if ((' ' != before) && ('\n' != before) && ('\t' != before)) { continue; } } if (index + nick.length() + 2 < text.length()) { // Calculate space char... // ' a': min(' ', 'a') is ' ' // 'a ': min('a', ' ') is ' ' char after = (char) Math.min(text.charAt(index + nick.length()), text.charAt(index + nick.length() + 1)); if ((' ' != after) && ('\n' != after) && ('\t' != after)) { continue; } } return true; } return false; } // #sijapp cond.end# // #sijapp cond.if modules_HISTORY is "true" # public void fillFromHistory(ChatModel chat) { if (!chat.contact.hasHistory()) { return; } if (chat.isBlogBot()) { return; } if (Options.getBoolean(Options.OPTION_HISTORY)) { if (0 != chat.size()) { return; } HistoryStorage hist = HistoryStorage.getHistory(chat.contact); hist.openHistory(); int recCount = hist.getHistorySize(); if (0 == recCount) { return; } int loadOffset = Math.max(recCount - ChatModel.MAX_HIST_LAST_MESS, 0); for (int i = loadOffset; i < recCount; ++i) { CachedRecord rec = hist.getRecord(i); if (null == rec) { continue; } long date = Util.createLocalDate(rec.date); PlainMessage message; if (rec.isIncoming()) { message = new PlainMessage(rec.from, chat.getProtocol(), date, rec.text, true); } else { message = new PlainMessage(chat.getProtocol(), chat.getContact(), date, rec.text); } buildMessage(chat, message); } hist.closeHistory(); } } private void addToHistory(ChatModel chat, String msg, boolean incoming, String nick, long time) { if (chat.getContact().hasHistory()) { HistoryStorage.getHistory(chat.contact).addText(msg, incoming, nick, time); } } // #sijapp cond.end# private short inc(short val) { return (short) ((val < Short.MAX_VALUE) ? (val + 1) : val); } private byte inc(byte val) { return (byte) ((val < Byte.MAX_VALUE) ? (val + 1) : val); } // #sijapp cond.if modules_FILES="true"# public MessData addFileProgress(ChatModel model, String caption, String text) { SystemNotice notice = new SystemNotice(model.protocol, SystemNotice.TYPE_FILE, model.getContact().getUserId(), text); notice.setName(caption); return buildMessage(model, notice); } public void changeFileProgress(ChatModel model, MessData mData, String caption, String text) { Parser parser = createParser(model, mData.par); parser.addText(text, CanvasEx.THEME_TEXT, CanvasEx.FONT_STYLE_PLAIN); long time = Jimm.getCurrentGmtTime(); short flags = (short)(mData.rowData & ~MessData.PROGRESS); synchronized (this) { int index = model.getIndex(mData); if ((0 < model.size()) && (0 <= index)) { Chat view = Jimm.getJimm().getCL().getChat(model); if (null != view) view.lock(); mData.init(time, text, caption, flags, Message.ICON_NONE); parser.commit(); if (null != view) view.unlock(); } } } // #sijapp cond.end# }