/******************************************************************************* Jimm - Mobile Messaging - J2ME ICQ clone Copyright (C) 2003-05 Jimm Project 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ******************************************************************************** File: src/jimm/ContactList.java Version: ###VERSION### Date: ###DATE### Author(s): Manuel Linsmayer, Andreas Rossbacher, Artyomov Denis *******************************************************************************/ package jimm.cl; import jimm.chat.message.Message; import jimm.modules.*; import jimmui.model.chat.ChatModel; import jimmui.updater.MessageBuilder; import jimmui.updater.RosterUpdater; import jimmui.view.chat.Chat; import jimmui.view.icons.Icon; import jimmui.view.roster.*; import jimm.*; import jimm.forms.*; import jimmui.view.menu.*; import jimmui.view.base.*; import jimmui.view.roster.items.ProtocolBranch; import jimmui.view.roster.items.TreeNode; import protocol.*; import protocol.xmpp.*; import protocol.ui.ContactMenu; import protocol.ui.InfoFactory; import java.util.Vector; public final class ContactList implements ContactListListener { private final ProtocolMenu mainMenu = new ProtocolMenu(null, true); private VirtualContactList contactList; public ContactList() { } public void initUI() { contactList = new VirtualContactList(); contactList.setCLListener(this); } public void updateCl() { updateModel(); updateMainMenu(); } public void activate() { contactList.update(); contactList.showMain(); } public void _setActiveContact(Contact c) { if (null != c) { contactList.setActiveContact(c); } contactList.getModel().setAlwaysVisibleNode(c); } public void activate(Contact c) { contactList.updateOfflineStatus(); _setActiveContact(c); activate(); } public void activateWithMsg(String message) { activate(); new Popup(contactList, message).show(); } public void startUp() { if (0 == Options.getAccountCount()) { updateUnreadMessageCount(); contactList.update(); updateMainMenu(); mainMenu.setDefaultItemCode(ProtocolMenu.MENU_STATUS); Jimm.getJimm().getDisplay().pushWindow(contactList); Jimm.getJimm().getDisplay().pushWindow(mainMenu.getView()); new AccountsForm().showAccountEditor(null); } else { activate(); Jimm.getJimm().getChatUpdater().loadUnreadMessages(); updateUnreadMessageCount(); } } /* *********************************************************** */ final static public int SORT_BY_STATUS = 0; final static public int SORT_BY_ONLINE = 1; final static public int SORT_BY_NAME = 2; /* *********************************************************** */ public VirtualContactList getManager() { return contactList; } public RosterUpdater getUpdater() { return contactList.getUpdater(); } /** * Adds the given message to the message queue of the contact item * identified by the given UIN */ public void setActiveContact(Contact contact) { boolean isShown = (Jimm.getJimm().getDisplay().getCurrentDisplay() == contactList); if (isShown && (0 == cursorLock)) { contactList.setActiveContact(contact); } } private int cursorLock = 0; public final void userActivity() { cursorLock = 4 /* * 250 = 1 sec */; // #sijapp cond.if modules_ABSENCE is "true" # jimm.modules.AutoAbsence.instance.userActivity(); // #sijapp cond.end # } public final void timerAction() { // #sijapp cond.if modules_ABSENCE is "true" # jimm.modules.AutoAbsence.instance.updateTime(); // #sijapp cond.end # if (0 < cursorLock) { cursorLock--; } Jimm.getJimm().jimmModel.saveRostersIfNeed(); } public final void receivedMessage(Protocol protocol, Contact contact, Message message, boolean silent) { // Notify splash canvas if (Jimm.getJimm().isLocked()) { Jimm.getJimm().splash.messageAvailable(); } if (!silent) { addMessageNotify(protocol, protocol.getChatModel(contact), contact, message); if (Options.getBoolean(Options.OPTION_SORT_UP_WITH_MSG)) { getUpdater().updateContact(protocol, protocol.getGroup(contact), contact); } } updateUnreadMessageCount(); } private void addMessageNotify(Protocol p, ChatModel chat, Contact contact, Message message) { boolean isPersonal = contact.isSingleUserContact(); boolean isBlog = p.isBlogBot(contact.getUserId()); boolean isHuman = isBlog || chat.isHuman() || !contact.isSingleUserContact(); if (p.isBot(contact)) { isHuman = false; } boolean isMention = false; // #sijapp cond.if protocols_JABBER is "true" # if (!isPersonal && !message.isOffline() && (contact instanceof XmppContact)) { String msg = message.getText(); String myName = ((XmppServiceContact)contact).getMyName(); // regexp: "^nick. " isPersonal = msg.startsWith(myName) && msg.startsWith(" ", myName.length() + 1); isMention = MessageBuilder.isHighlight(msg, myName); } // #sijapp cond.end # boolean isPaused = Jimm.getJimm().isPaused() && Jimm.getJimm().phone.isCollapsible(); // #sijapp cond.if target is "MIDP2" # if (isPaused && isPersonal && isHuman) { if (Options.getBoolean(Options.OPTION_BRING_UP)) { Jimm.getJimm().maximize(getOrCreateChat(chat)); isPaused = false; } } // #sijapp cond.end # if (!isPaused && isHuman) { if (isPersonal) { setActiveContact(contact); } // #sijapp cond.if modules_LIGHT is "true" # if (isPersonal || isMention) { CustomLight.setLightMode(CustomLight.ACTION_MESSAGE); } // #sijapp cond.end# } // #sijapp cond.if modules_SOUND is "true" # // Offline messages don't play sound if (!message.isOffline()) { if (isPersonal) { if (contact.isSingleUserContact() && contact.isAuth() && !contact.isTemp() && message.isWakeUp()) { playNotification(p, Notify.NOTIFY_ALARM); } else if (isBlog) { playNotification(p, Notify.NOTIFY_BLOG); } else if (isHuman) { playNotification(p, Notify.NOTIFY_MESSAGE); } // #sijapp cond.if protocols_JABBER is "true" # } else if (isMention) { playNotification(p, Notify.NOTIFY_MULTIMESSAGE); // #sijapp cond.end # } } // #sijapp cond.end# } public final void playNotification(Protocol p, int type) { // #sijapp cond.if modules_SOUND is "true" # if (!p.isAway(p.getProfile().statusIndex) || Options.getBoolean(Options.OPTION_NOTIFY_IN_AWAY)) { Notify.getSound().playSoundNotification(type); } // #sijapp cond.end # } public final void markMessages(Protocol protocol, Contact contact) { if (null != contact) { if (Options.getBoolean(Options.OPTION_SORT_UP_WITH_MSG)) { getUpdater().updateContact(protocol, protocol.getGroup(contact), contact); } } if (null != MyActionBar.getMessageIcon()) { updateUnreadMessageCount(); } } private void updateUnreadMessageCount() { Icon icon = getUnreadMessageIcon(); if (icon != MyActionBar.getMessageIcon()) { MyActionBar.setMessageIcon(icon); Jimm.getJimm().getDisplay().getNativeCanvas().repaint(); } // #sijapp cond.if modules_ANDROID is "true" # ru.net.jimm.JimmActivity.getInstance().service.updateAppIcon(); // #sijapp cond.end # } public Icon getUnreadMessageIcon() { int icon = -1; Vector<ChatModel> chats = Jimm.getJimm().jimmModel.chats; for (int i = chats.size() - 1; 0 <= i; --i) { icon = InfoFactory.factory.getMoreImportant(icon, ((ChatModel)chats.elementAt(i)).getNewMessageIcon()); } return InfoFactory.msgIcons.iconAt(icon); } public Icon getUnreadMessageIcon(Vector contacts) { int icon = -1; Contact c; for (int i = contacts.size() - 1; 0 <= i; --i) { c = (Contact)contacts.elementAt(i); icon = InfoFactory.factory.getMoreImportant(icon, c.getUnreadMessageIcon()); } return InfoFactory.msgIcons.iconAt(icon); } public Icon getUnreadMessageIcon(Protocol p) { int icon = -1; ChatModel chat; Vector<ChatModel> chats = Jimm.getJimm().jimmModel.chats; for (int i = chats.size() - 1; 0 <= i; --i) { chat = (ChatModel)chats.elementAt(i); if (chat.getProtocol() == p) { icon = InfoFactory.factory.getMoreImportant(icon, chat.getNewMessageIcon()); } } return InfoFactory.msgIcons.iconAt(icon); } ///////////////////////////////////////////////////////////////// /** ************************************************************************* */ /* Builds the main menu (visual list) */ public void activateMainMenu() { if (contactList.getModel() == getUpdater().getChatModel()) { contactList.showMenu(new ChatMenu().getMenu()); } else { updateMainMenu(); mainMenu.setDefaultItemCode(ProtocolMenu.MENU_STATUS); mainMenu.getView().show(); } } public void updateMainMenu() { mainMenu.updateMenu(); } public final MenuModel getContextMenu(Protocol p, TreeNode node) { if (node instanceof Contact) { return new ContactMenu(p, (Contact) node).getContextMenu(); } if (node instanceof Group) { if (p.isConnected()) { return new ManageContactListForm(p, (Group) node).getMenu(); } return null; } if ((node instanceof ProtocolBranch) || (null == node)) { ProtocolMenu menu = new ProtocolMenu(p, false); menu.updateMenu(); return menu.getModel(); } return null; } public void updateModel() { contactList.setModel(contactList.getUpdater().createModel()); contactList.getUpdater().addProtocols(Jimm.getJimm().jimmModel.protocols); contactList.updateOption(); } public void typing(Protocol protocol, Contact item, boolean type) { // #sijapp cond.if modules_SOUND is "true" # if (type && protocol.isConnected()) { playNotification(protocol, Notify.NOTIFY_TYPING); } // #sijapp cond.end # getUpdater().typing(protocol, item); } public void setContactStatus(Protocol protocol, Contact contact, byte prev, byte curr) { if ((prev == curr) || !contact.isSingleUserContact()) { return; } // #sijapp cond.if protocols_JABBER is "true" # if (contact instanceof XmppServiceContact) { return; } // #sijapp cond.end # // #sijapp cond.if modules_SOUND is "true" # if (!protocol.isAway(curr) && protocol.isAway(prev)) { playNotification(protocol, Notify.NOTIFY_ONLINE); } // #sijapp cond.end # Jimm.getJimm().uiUpdater.showTopLine(protocol, contact, null, contact.getStatusIndex()); } public void setContactStatus(Protocol protocol, Contact contact, String nick, byte status) { Jimm.getJimm().uiUpdater.showTopLine(protocol, contact, nick, status); } public void disconnected(Protocol protocol) { // #sijapp cond.if modules_SOUND is "true" # playNotification(protocol, Notify.NOTIFY_RECONNECT); // #sijapp cond.end # } ////////////////////////////////////////////////////////////////// // chats public boolean isChats(Object canvas) { if (canvas instanceof VirtualContactList) { VirtualContactList vcl = ((VirtualContactList) canvas); return vcl.getModel() == vcl.getUpdater().getChatModel(); } return false; } public void showChatList(boolean forceGoToChat) { ChatModel current = getPreferredChat(); if (forceGoToChat && (null != current) && (0 < current.getUnreadMessageCount())) { Jimm.getJimm().getChatUpdater().activate(current); return; } getManager().setModel(getUpdater().getChatModel()); if (null != current) { getManager().setActiveContact(current.getContact()); } getManager().show(); } public void backFromChats() { getManager().setModel(getUpdater().getModel()); Jimm.getJimm().getDisplay().back(getManager()); } // shows next or previous chat public void showNextPrevChat(ChatModel item, boolean next) { int chatNum = Jimm.getJimm().jimmModel.chats.indexOf(item); if (-1 == chatNum) { return; } int total = Jimm.getJimm().jimmModel.chats.size(); int nextChatNum = (chatNum + (next ? 1 : -1) + total) % total; Vector<ChatModel> chats = Jimm.getJimm().jimmModel.chats; Jimm.getJimm().getChatUpdater().activate((ChatModel) chats.elementAt(nextChatNum)); } private ChatModel getPreferredChat() { Vector<ChatModel> chats = Jimm.getJimm().jimmModel.chats; for (int i = 0; i < chats.size(); ++i) { ChatModel chat = (ChatModel) chats.elementAt(i); if (0 < chat.getPersonalUnreadMessageCount()) { return chat; } } Contact currentContact = getUpdater().getCurrentContact(); int current = 0; for (int i = 0; i < chats.size(); ++i) { ChatModel chat = (ChatModel) chats.elementAt(i); if (0 < chat.getUnreadMessageCount()) { return chat; } if (currentContact == chat.getContact()) { current = i; } } return current < chats.size() ? (ChatModel) chats.elementAt(current) : null; } public Chat getChat(ChatModel c) { if (null == c) return null; Object view = Jimm.getJimm().getDisplay().getCurrentDisplay(); if (view instanceof Chat) { Chat chat = (Chat) view; if (chat.getModel() == c) { return chat; } } return null; } public Chat getOrCreateChat(ChatModel c) { Chat chat = getChat(c); if (null != c) { chat = new Chat(c); } return chat; } public void changeContactStatus(Protocol protocol, Contact contact) { ChatModel chat = Jimm.getJimm().jimmModel.getChatModel(contact); Chat view = getChat(chat); if (null != view) { view.updateStatus(); } getUpdater().updateContact(protocol, protocol.getGroup(contact), contact); } }