/* * Contact.java * * Created on 6.01.2005, 19:16 * * Copyright (c) 2005-2007, Eugene Stahov (evgs), http://bombus-im.org * * 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. * * You can also redistribute and/or modify this program under the * terms of the Psi License, specified in the accompanied COPYING * file, as published by the Psi Project; either dated January 1st, * 2005, 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 library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package Client; import com.alsutton.jabber.JabberDataBlock; import images.MoodIcons; import images.RosterIcons; import javax.microedition.lcdui.Graphics; //#if CLIPBOARD_EVGS //# import ui.ClipBoardString; //#endif import ui.Colors; import vcard.VCard; import java.util.*; import ui.IconTextElement; import ui.ImageList; import com.alsutton.jabber.datablocks.Presence; // import Client.Config; //#ifdef CLIENTS_ICONS import modules.ClientsIcons; //#endif // /** * Contact * @author Eugene Stahov */ public class Contact extends IconTextElement //#if CLIPBOARD_EVGS //# implements ClipBoardString //#endif { public final static byte ORIGIN_ROSTER=0; public final static byte ORIGIN_ROSTERRES=1; public final static byte ORIGIN_CLONE=2; public final static byte ORIGIN_PRESENCE=3; public final static byte ORIGIN_GROUPCHAT=4; public final static byte ORIGIN_GC_MEMBER=5; public final static byte ORIGIN_GC_MYSELF=6; /*public final static String XEP184_NS="http://www.xmpp.org/extensions/xep-0184.html#ns"; public final static int DELIVERY_NONE=0; public final static int DELIVERY_HANDSHAKE=1; public final static int DELIVERY_XEP184=2; public final static int DELIVERY_XEP22=3;*/ // private Config cf; public short incomingState=0; public final static short INC_NONE=0; public final static short INC_APPEARING=1; public final static short INC_VIEWING=2; //#if AUTOSCROLLING public boolean moveToLatest=false; //#endif //#ifdef LOGROTATE public boolean redraw=false; //#endif //#if PREV_MSG public String previousMessage; //#endif // /** Creates a new instance of Contact */ protected Contact (){ //lastReaded=0; super(RosterIcons.getInstance()); cf=Config.getInstance(); msgs=null; //<+voffk> msgs=new Vector(); key1=""; } public String nick; public Jid jid; public String bareJid; // for roster/subscription manipulating public int status; //<*voffk> public int priority; public Group group; //<*voffk> public int transport; public boolean acceptComposing; public Integer incomingComposing; public int deliveryType; //private boolean isActive; public String msgSuspended; //public int key1; protected int key0; protected String key1; public byte origin; //public boolean gcMyself; public String subscr; public int offline_type=Presence.PRESENCE_UNKNOWN; public boolean ask_subscribe; public Vector msgs; private int newMsgCnt=-1; public int unreadType; public int lastUnread; // /*int ilHeight; int maxImgHeight;*/ ///public int breakPoint; ///save cursor pos - voffk // public VCard vcard; //#if PEP public int pepMood=-1; //#if PEP_TUNE public boolean pepTune; //#endif //#endif //public long conferenceJoinTime; public int firstUnread(){ int unreadIndex=0; for (Enumeration e=msgs.elements(); e.hasMoreElements();) { if (((Msg)e.nextElement()).unread) break; unreadIndex++; } return unreadIndex; } public Contact(final String Nick, final String sJid, final int Status, String subscr) { this(); nick=Nick; jid= new Jid(sJid); status=Status; bareJid=sJid; this.subscr=subscr; setSortKey((Nick==null)?sJid:Nick); //msgs.removeAllElements(); //calculating transport transport=RosterIcons.getInstance().getTransportIndex(jid.getTransport()); } public Contact clone(Jid newjid, final int status) { Contact clone=new Contact(); clone.group=group; clone.jid=newjid; clone.nick=nick; clone.key1=key1; clone.subscr=subscr; clone.offline_type=offline_type; clone.vcard=vcard; //<+voffk> clone.origin=ORIGIN_CLONE; clone.status=status; clone.transport=RosterIcons.getInstance().getTransportIndex(newjid.getTransport()); //<<<< //#if PEP clone.pepMood=pepMood; //#if PEP_TUNE clone.pepTune=pepTune; //#endif //#endif clone.bareJid=bareJid; return clone; } public int getImageIndex() { if (getNewMsgsCount()>0) switch (unreadType) { case Msg.MESSAGE_TYPE_AUTH: return RosterIcons.ICON_AUTHRQ_INDEX; default: return RosterIcons.ICON_MESSAGE_INDEX; } if (incomingComposing!=null) return RosterIcons.ICON_COMPOSING_INDEX; if (incomingState>0) return incomingState; //<+voffk> int st=(status==Presence.PRESENCE_OFFLINE)?offline_type:status; if (st<8) st+=transport; return st; } //#if PEP || CLIENTS_ICONS public void drawItem(Graphics g, int ofs, boolean sel) { int w=g.getClipWidth(); int h=g.getClipHeight(); int xo=g.getClipX(); int yo=g.getClipY(); //#if CLIENTS_ICONS if (cf.showClientsIcons) if (client>-1) { ImageList clients=ClientsIcons.getInstance(); /*int clientImgSize=clients.getWidth(); w-=clientImgSize; clients.drawImage(g, client, w, (h-clientImgSize)/2); if (maxImgHeight=0 && pepMood<61) { //<*voffk> ImageList moods=MoodIcons.getInstance(); w-=moods.getWidth(); moods.drawImage(g, pepMood, w,0); } //#if PEP_TUNE if (pepTune) { w-=il.getWidth(); il.drawImage(g, RosterIcons.ICON_PROFILE_INDEX+3, w,0); } //#endif //#endif g.setClip(xo, yo, w, h); super.drawItem(g, ofs, sel); } //#endif //#if PEP || CLIENTS_ICONS public int getVWidth() { //<+voffk> int ofs=0; //#if PEP if (pepMood>=0 && pepMood<61) { ofs+=MoodIcons.getInstance().getWidth(); } //#if PEP_TUNE if (pepTune) { ofs+=il.getWidth(); } //#endif //#endif //#if CLIENTS_ICONS if (cf.showClientsIcons) if (client>-1) ofs+=ClientsIcons.getInstance().getWidth(); //#endif return super.getVWidth()+ofs; } //#endif public int getNewMsgsCount() { if (getGroupType()==Groups.TYPE_IGNORE) return 0; //return msgs.size()-lastReaded; if (newMsgCnt>-1) return newMsgCnt; int nm=0; unreadType=Msg.MESSAGE_TYPE_IN; for (Enumeration e=msgs.elements(); e.hasMoreElements(); ) { Msg m=(Msg)e.nextElement(); if (m.unread) { nm++; if (m.messageType==Msg.MESSAGE_TYPE_AUTH) unreadType=m.messageType; } } return newMsgCnt=nm; } //public boolean needsCount(){ return (newMsgCnt<0); } public boolean active(){ //<*voffk> if (msgSuspended!=null) return true; //if (msgs.size()>1) return true; if (msgs.size()==0) return false; //return (((Msg)msgs.elementAt(0)).messageType!=Msg.MESSAGE_TYPE_PRESENCE); for (Enumeration e=msgs.elements(); e.hasMoreElements(); ) { Msg m=(Msg)e.nextElement(); if (m.messageType!=Msg.MESSAGE_TYPE_PRESENCE //#if PEP && m.messageType!=Msg.MESSAGE_TYPE_MOOD //#endif ) return true; } return false; //return isActive; //<-voffk> } public void resetNewMsgCnt() { newMsgCnt=-1; newHighLitedMsgCnt=-1; } //<*voffk> public void setComposing (boolean state) { incomingComposing=(state)? new Integer(RosterIcons.ICON_COMPOSING_INDEX):null; //System.out.println("Composing:"+state); } public int compare(IconTextElement right){ Contact c=(Contact) right; //1. status int cmp; //if (origin>=ORIGIN_GROUPCHAT && c.origin>=ORIGIN_GROUPCHAT) { // if ((cmp=origin-c.origin) !=0) return cmp; //} else { // if ((cmp=status-c.status) !=0) return cmp; //} if ((cmp=key0-c.key0) !=0) return cmp; if ((cmp=status-c.status) !=0) return cmp; if ((cmp=key1.compareTo(c.key1)) !=0) return cmp; if ((cmp=c.priority-priority) !=0) return cmp; return c.transport-transport; //return 0; }; public void addMessage(Msg m) { //<*voffk> //m.body=util.strconv.shuffler(m.body); boolean first_replace=false; if (origin!=ORIGIN_GROUPCHAT) { if (m.isPresence()) if (msgs.size()==1) if ( ((Msg)msgs.firstElement()).isPresence()) /*if (origin!=ORIGIN_GROUPCHAT)*/ first_replace=true; } //#ifdef LOGROTATE else { redraw=deleteOldMessages(); } //#endif if (first_replace) { msgs.setElementAt(m,0); return; } //#if AUTOSCROLLING if (cf.autoScrolling) moveToLatest=true; //#endif msgs.addElement(m); /*if ( (m.messageType!=Msg.MESSAGE_TYPE_PRESENCE) && (m.messageType!=Msg.MESSAGE_TYPE_MOOD) ) { isActive=true; }*/ //<-voffk> if (m.unread) { lastUnread=msgs.size()-1; if (m.messageType>unreadType) unreadType=m.messageType; if (newMsgCnt>=0) newMsgCnt++; if (m.isHighlited()) //<+voffk> if (newHighLitedMsgCnt>=0) newHighLitedMsgCnt++; } } public int getColor() { switch (status) { case Presence.PRESENCE_CHAT: return Colors.CONTACT_CHAT; case Presence.PRESENCE_AWAY: return Colors.CONTACT_AWAY; case Presence.PRESENCE_XA: return Colors.CONTACT_XA; case Presence.PRESENCE_DND: return Colors.CONTACT_DND; } return Colors.CONTACT_DEFAULT; }; public int getFontIndex() { //<*voffk> if (cf.rosterBoldFont) { return (status<5)?1:0; } return (active() && !(cf.ghostMotor))?1:0; } public String toString() { if (origin>ORIGIN_GROUPCHAT) return nick; if (origin==ORIGIN_GROUPCHAT) return getJid(); return (nick==null)?getJid():nick+jid.getResource(); } public final String getName(){ return (nick==null)?bareJid:nick; } //<*voffk> //public void onSelect(){} public final String getJid() { return jid.getJid(); } /*public final String getBareJid() { return bareJid; }*/ //<-voffk> /*public String getNickJid() { if (nick==null) return bareJid; return nick+" <"+bareJid+">"; }*/ //<-voffk> /** * Splits string like "name@jabber.ru/resource" to vector * containing 2 substrings * @return Vector.elementAt(0)="name@jabber.ru" * Vector.elementAt(1)="resource" */ /* public static final Vector SplitJid(final String jid) { Vector result=new Vector(); int i=jid.lastIndexOf('/'); if (i==-1){ result.addElement(jid); result.addElement(null); } else { result.addElement(jid.substring(0,i)); result.addElement(jid.substring(i+1)); } return result; } */ public final void purge() { //<*voffk> msgs=null; msgs=new Vector(); vcard=null; //#if PREV_MSG previousMessage=null; //#endif resetNewMsgCnt(); //isActive=false; } public final void setSortKey(String sortKey){ key1=(sortKey==null)? "": sortKey.toLowerCase(); } public String getTipString() { int nm=getNewMsgsCount(); if (nm!=0) return String.valueOf(nm); if (nick!=null) return bareJid; return null; } //public Group getGroup() { return group; } <-voffk> public int getGroupType() { if (group==null) return 0; return group.type; } // /*public boolean inGroup(Group ingroup) { return group==ingroup; } public void setGroup(Group group) { this.group = group; } */ public void setStatus(int status) { //setComposing(false); //#if !ReleaseZVOFFK setIncoming(0); //#endif this.status = status; if (status>=Presence.PRESENCE_OFFLINE) acceptComposing=false; } /*public int getStatus() { return status; }*/ void markDelivered(String id) { if (id==null) return; for (Enumeration e=msgs.elements(); e.hasMoreElements();) { Msg m=(Msg)e.nextElement(); if (m.id!=null) if (m.id.equals(id)) m.delivered=true; } } //#if CLIPBOARD_EVGS //# public String toClipBoardString() { return getJid(); } //#endif public final void smartPurge(int cursor) { try { if (cursor==msgs.size()) { msgs=null; msgs=new Vector(); } else for (int i=0; i0) return newHighLitedMsgCnt; int nhm=0; if (getGroupType()!=Groups.TYPE_IGNORE) { for (Enumeration e=msgs.elements(); e.hasMoreElements(); ) { Msg m=(Msg)e.nextElement(); if (m.unread && m.isHighlited()) { nhm++; } } } return newHighLitedMsgCnt=nhm; } //#ifdef LOGROTATE public final boolean deleteOldMessages() { int limit=cf.msgCountLimit; if (msgs.size() }