Extends contact source apis to support editable contact sources. Fixes internationalization issues with contact source details. Adds additional categories and sub-categories of contact details.

cusax-fix
Yana Stamcheva 13 years ago
parent 02acd44641
commit 8b6b45aa53

@ -51,6 +51,7 @@ service.gui.ADD_GROUP_ERROR=Failed to add group with name: {0}.
service.gui.ADD_GROUP_EMPTY_NAME=The group name must not be empty. service.gui.ADD_GROUP_EMPTY_NAME=The group name must not be empty.
service.gui.ADD_GROUP=Create group service.gui.ADD_GROUP=Create group
service.gui.ADD_SUBCONTACT=&Add subcontact service.gui.ADD_SUBCONTACT=&Add subcontact
service.gui.ADDRESS=Address
service.gui.ADMINISTRATOR=administrator service.gui.ADMINISTRATOR=administrator
service.gui.ADVANCED=&Advanced service.gui.ADVANCED=&Advanced
service.gui.ALL=&All service.gui.ALL=&All
@ -122,6 +123,8 @@ service.gui.CHAT_ROOMS=Chat rooms
service.gui.CHAT_ROOM_SUBJECT_CHANGED={0} has changed the subject to {1} service.gui.CHAT_ROOM_SUBJECT_CHANGED={0} has changed the subject to {1}
service.gui.CHOOSE_CONTACT=Choose contact service.gui.CHOOSE_CONTACT=Choose contact
service.gui.CHOOSE_ACCOUNT=Please select one of the listed accounts. service.gui.CHOOSE_ACCOUNT=Please select one of the listed accounts.
service.gui.CITY=City
service.gui.COUNTRY=Country
service.gui.SHOW_MORE_TOOLTIP=Click to show more results service.gui.SHOW_MORE_TOOLTIP=Click to show more results
service.gui.CLEAR=Clear service.gui.CLEAR=Clear
service.gui.CLOSE=Cl&ose service.gui.CLOSE=Cl&ose
@ -175,6 +178,8 @@ service.gui.DRAG_FOR_SHARING=Drag here anything you want to share...
service.gui.DURATION=duration service.gui.DURATION=duration
service.gui.EDIT=&Edit service.gui.EDIT=&Edit
service.gui.EDITED_AT=edited at {0} service.gui.EDITED_AT=edited at {0}
service.gui.EMAIL=Email
service.gui.EMAILS=Emails
service.gui.EMPTY_HISTORY=&Empty history service.gui.EMPTY_HISTORY=&Empty history
service.gui.ENABLE_DESKTOP_REMOTE_CONTROL=Enable desktop remote control service.gui.ENABLE_DESKTOP_REMOTE_CONTROL=Enable desktop remote control
service.gui.ENABLE_TYPING_NOTIFICATIONS=Tell others when we are writing to them (send chat activity) service.gui.ENABLE_TYPING_NOTIFICATIONS=Tell others when we are writing to them (send chat activity)
@ -191,6 +196,7 @@ service.gui.GENERAL_ERROR=General error
service.gui.GROUP_NAME=Group name service.gui.GROUP_NAME=Group name
service.gui.FAILED_STATUS=Call failed service.gui.FAILED_STATUS=Call failed
service.gui.FAILED_TO_JOIN_CHAT_ROOM=Failed to join chat room with name: {0}. service.gui.FAILED_TO_JOIN_CHAT_ROOM=Failed to join chat room with name: {0}.
service.gui.FAX=Fax
service.gui.FFC_STATUS=Free for chat service.gui.FFC_STATUS=Free for chat
service.gui.FILE=&File service.gui.FILE=&File
service.gui.FILE_WAITING_TO_ACCEPT=Waiting for {0} to accept your file. service.gui.FILE_WAITING_TO_ACCEPT=Waiting for {0} to accept your file.
@ -241,6 +247,8 @@ service.gui.HIDE_MAIN_WINDOW=<DIV>Clicking the X window button will not exit the
but only <BR> hide it. If you wish to exit the application choose File/Quit.</DIV> but only <BR> hide it. If you wish to exit the application choose File/Quit.</DIV>
service.gui.HISTORY=&History service.gui.HISTORY=&History
service.gui.HISTORY_CONTACT=History - {0} service.gui.HISTORY_CONTACT=History - {0}
service.gui.HOME=Home
service.gui.HOME_PAGE=Home page
service.gui.HOUR=Hour service.gui.HOUR=Hour
service.gui.ICE=ICE service.gui.ICE=ICE
service.gui.IDENTIFIER=Identifier service.gui.IDENTIFIER=Identifier
@ -248,6 +256,7 @@ service.gui.IGNORE=&Ignore
service.gui.INSERT_SMILEY=Insert smiley service.gui.INSERT_SMILEY=Insert smiley
service.gui.INCOMING_CALL=Incoming call received from: {0} service.gui.INCOMING_CALL=Incoming call received from: {0}
service.gui.INCOMING_CALL_STATUS=Incoming call service.gui.INCOMING_CALL_STATUS=Incoming call
service.gui.INSTANT_MESSAGINGS=IMs
service.gui.INITIATING_CALL_STATUS=Initiating call service.gui.INITIATING_CALL_STATUS=Initiating call
service.gui.INVITATION=Invitation text service.gui.INVITATION=Invitation text
service.gui.INVITATION_RECEIVED=Invitation received service.gui.INVITATION_RECEIVED=Invitation received
@ -269,6 +278,7 @@ service.gui.JITSI_WARNING_TITLE=SIP Communicator becomes Jitsi
service.gui.JOIN=&Join service.gui.JOIN=&Join
service.gui.JOIN_AS=J&oin as service.gui.JOIN_AS=J&oin as
service.gui.CLOSE_CHAT_ROOM_DIALOG=C&lose service.gui.CLOSE_CHAT_ROOM_DIALOG=C&lose
service.gui.JOB_TITLE=Job title
service.gui.JOIN_CHAT_ROOM=&Join chat room... service.gui.JOIN_CHAT_ROOM=&Join chat room...
service.gui.JOIN_CHAT_ROOM_TITLE=Join chat room service.gui.JOIN_CHAT_ROOM_TITLE=Join chat room
service.gui.JOIN_CHAT_ROOM_NAME=Please enter the name of the chat room you would like to join. service.gui.JOIN_CHAT_ROOM_NAME=Please enter the name of the chat room you would like to join.
@ -279,6 +289,7 @@ service.gui.KICK_FAILED_GENERAL_ERROR=Failed to kick {0}. A general server error
service.gui.KICK_FAILED_NOT_ALLOWED=Failed to kick {0}. The owner and the administrator of the room could not be kicked. service.gui.KICK_FAILED_NOT_ALLOWED=Failed to kick {0}. The owner and the administrator of the room could not be kicked.
service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Failed to kick {0}. You don''t have enough privileges to do that. service.gui.KICK_FAILED_NOT_ENOUGH_PERMISSIONS=Failed to kick {0}. You don''t have enough privileges to do that.
service.gui.LAST=Last service.gui.LAST=Last
service.gui.LAST_NAME=Last name
service.gui.LEAVE=&Leave service.gui.LEAVE=&Leave
service.gui.LIMIT_REACHED_FOR_IP=You have too many existing registrations from the local IP address and the {0} server doesn''t allow to open any more of them. service.gui.LIMIT_REACHED_FOR_IP=You have too many existing registrations from the local IP address and the {0} server doesn''t allow to open any more of them.
service.gui.LOADING_ROOMS=Loading rooms... service.gui.LOADING_ROOMS=Loading rooms...
@ -321,6 +332,7 @@ service.gui.MY_CHAT_ROOMS=Go to chat room...
service.gui.MY_CHAT_ROOMS_TITLE=Go to chat room service.gui.MY_CHAT_ROOMS_TITLE=Go to chat room
service.gui.MUTE=Mute service.gui.MUTE=Mute
service.gui.MUTUALLY_ON_HOLD_STATUS=Mutually On Hold service.gui.MUTUALLY_ON_HOLD_STATUS=Mutually On Hold
service.gui.NAME=Name
service.gui.NETWORK=Network service.gui.NETWORK=Network
service.gui.NETWORK_FAILURE=Network failure service.gui.NETWORK_FAILURE=Network failure
service.gui.NEXT=&Next service.gui.NEXT=&Next
@ -329,6 +341,7 @@ service.gui.NEW_MESSAGE=New message
service.gui.NEW_NAME=New name service.gui.NEW_NAME=New name
service.gui.NEW_STATUS_MESSAGE=New status message service.gui.NEW_STATUS_MESSAGE=New status message
service.gui.NEW_STATUS_MESSAGE_SAVE=Save as custom message service.gui.NEW_STATUS_MESSAGE_SAVE=Save as custom message
service.gui.NICKNAME=Nickname
service.gui.NO=No service.gui.NO=No
service.gui.NONE=None service.gui.NONE=None
service.gui.NO_CAMERA_AVAILABLE=No camera available service.gui.NO_CAMERA_AVAILABLE=No camera available
@ -357,12 +370,16 @@ service.gui.OPEN_IN_BROWSER=Open in &browser
service.gui.OPTIONS=Options service.gui.OPTIONS=Options
service.gui.OR=or service.gui.OR=or
service.gui.OR_ENTER_PHONE_NUMBER=Or enter phone number here... service.gui.OR_ENTER_PHONE_NUMBER=Or enter phone number here...
service.gui.ORGANIZATION=Organization
service.gui.OTHER=Other
service.gui.OWNER=owner of the room service.gui.OWNER=owner of the room
service.gui.PASSWORD=Password service.gui.PASSWORD=Password
service.gui.PASSWORD_CHANGE_FAILURE=Password change failed service.gui.PASSWORD_CHANGE_FAILURE=Password change failed
service.gui.PASSWORD_CHANGE_SUCCESS=Password successfully changed service.gui.PASSWORD_CHANGE_SUCCESS=Password successfully changed
service.gui.PASTE=&Paste service.gui.PASTE=&Paste
service.gui.PERSONAL=Personal
service.gui.PORT=Port service.gui.PORT=Port
service.gui.POSTAL_CODE=Postal code
service.gui.PREFIX=Prefix service.gui.PREFIX=Prefix
service.gui.PRESENCE=Presence service.gui.PRESENCE=Presence
service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Enter' for suggestions service.gui.PRESS_ENTER_FOR_SUGGESTIONS='Enter' for suggestions
@ -460,6 +477,7 @@ service.gui.STATUS_CHANGE_GENERAL_ERROR=Failed to change status for account: Use
service.gui.STATUS_CHANGE_NETWORK_FAILURE=Failed to change status for account: User name: {0}, Server name: {1}, due to a network problem. service.gui.STATUS_CHANGE_NETWORK_FAILURE=Failed to change status for account: User name: {0}, Server name: {1}, due to a network problem.
service.gui.STATUS_MESSAGE_INFO=In the field below you can specify the new message you would like to use. service.gui.STATUS_MESSAGE_INFO=In the field below you can specify the new message you would like to use.
service.gui.STOP_SHARING=Stop sharing service.gui.STOP_SHARING=Stop sharing
service.gui.STREET=Street
service.gui.SUBJECT=Subject service.gui.SUBJECT=Subject
service.gui.SUMMARY=Summary service.gui.SUMMARY=Summary
service.gui.TELEPHONY=Telephony service.gui.TELEPHONY=Telephony
@ -531,7 +549,8 @@ service.gui.NON_SECURE_CONNECTION=No secure connection can be made for account {
service.gui.UPDATE=Update service.gui.UPDATE=Update
service.gui.MOBILE_PHONE=Mobile service.gui.MOBILE_PHONE=Mobile
service.gui.WORK_PHONE=Work service.gui.WORK_PHONE=Work
service.gui.PHONE=Home service.gui.PHONE=Phone
service.gui.PHONES=Phones
service.gui.EDIT_NOT_SUPPORTED=Editing this account is not supported service.gui.EDIT_NOT_SUPPORTED=Editing this account is not supported
service.gui.ZID_NAME_SET=ZRTP identifier's name: service.gui.ZID_NAME_SET=ZRTP identifier's name:
@ -1657,5 +1676,5 @@ plugin.certconfig.REVOCATION_TITLE=Certificate revocation options
plugin.certconfig.REVOCATION_CHECK_ENABLED=CRL (Certificate Revocation List) check enabled plugin.certconfig.REVOCATION_CHECK_ENABLED=CRL (Certificate Revocation List) check enabled
plugin.certconfig.REVOCATION_OCSP_ENABLED=OCSP (Online Certificate Status Protocol) check enabled plugin.certconfig.REVOCATION_OCSP_ENABLED=OCSP (Online Certificate Status Protocol) check enabled
#Phone number contact source plugin # Phone number contact source plugin
plugin.phonenumbercontactsource.DISPLAY_NAME=Phone numbers plugin.phonenumbercontactsource.DISPLAY_NAME=Phone numbers

@ -304,7 +304,8 @@ public List<ContactDetail> getContactDetails(
* @return a list of all <tt>ContactDetail</tt>s corresponding to the given * @return a list of all <tt>ContactDetail</tt>s corresponding to the given
* category * category
*/ */
public List<ContactDetail> getContactDetails(String category) public List<ContactDetail> getContactDetails(
ContactDetail.Category category)
throws OperationNotSupportedException throws OperationNotSupportedException
{ {
// We don't support category for call history details, so we return null. // We don't support category for call history details, so we return null.

@ -160,8 +160,10 @@ private List<ContactDetail> getContactDetails(GoogleContactsEntry entry)
// can be added as contacts // can be added as contacts
supportedOpSets.add(OperationSetPersistentPresence.class); supportedOpSets.add(OperationSetPersistentPresence.class);
detail = new ContactDetail(mail, ContactDetail.CATEGORY_EMAIL, detail = new ContactDetail(mail,
new String[]{ContactDetail.LABEL_HOME}); ContactDetail.Category.Email,
new ContactDetail.SubCategory[]{
ContactDetail.SubCategory.Home});
detail.setSupportedOpSets(supportedOpSets); detail.setSupportedOpSets(supportedOpSets);
ret.add(detail); ret.add(detail);
} }
@ -172,8 +174,10 @@ private List<ContactDetail> getContactDetails(GoogleContactsEntry entry)
// can be added as contacts // can be added as contacts
supportedOpSets.add(OperationSetPersistentPresence.class); supportedOpSets.add(OperationSetPersistentPresence.class);
detail = new ContactDetail(mail, ContactDetail.CATEGORY_EMAIL, detail = new ContactDetail(mail,
new String[]{ContactDetail.LABEL_WORK}); ContactDetail.Category.Email,
new ContactDetail.SubCategory[]{
ContactDetail.SubCategory.Work});
detail.setSupportedOpSets(supportedOpSets); detail.setSupportedOpSets(supportedOpSets);
ret.add(detail); ret.add(detail);
} }
@ -188,8 +192,9 @@ private List<ContactDetail> getContactDetails(GoogleContactsEntry entry)
supportedOpSets.add(OperationSetPersistentPresence.class); supportedOpSets.add(OperationSetPersistentPresence.class);
homePhone = PhoneNumberI18nService.normalize(homePhone); homePhone = PhoneNumberI18nService.normalize(homePhone);
detail = new ContactDetail(homePhone, detail = new ContactDetail(homePhone,
ContactDetail.CATEGORY_PHONE, ContactDetail.Category.Phone,
new String[]{ContactDetail.LABEL_HOME}); new ContactDetail.SubCategory[]{
ContactDetail.SubCategory.Home});
detail.setSupportedOpSets(supportedOpSets); detail.setSupportedOpSets(supportedOpSets);
ret.add(detail); ret.add(detail);
} }
@ -204,8 +209,9 @@ private List<ContactDetail> getContactDetails(GoogleContactsEntry entry)
supportedOpSets.add(OperationSetPersistentPresence.class); supportedOpSets.add(OperationSetPersistentPresence.class);
workPhone = PhoneNumberI18nService.normalize(workPhone); workPhone = PhoneNumberI18nService.normalize(workPhone);
detail = new ContactDetail(workPhone, detail = new ContactDetail(workPhone,
ContactDetail.CATEGORY_PHONE, ContactDetail.Category.Phone,
new String[]{ContactDetail.LABEL_WORK}); new ContactDetail.SubCategory[]{
ContactDetail.SubCategory.Work});
detail.setSupportedOpSets(supportedOpSets); detail.setSupportedOpSets(supportedOpSets);
ret.add(detail); ret.add(detail);
} }
@ -220,8 +226,9 @@ private List<ContactDetail> getContactDetails(GoogleContactsEntry entry)
supportedOpSets.add(OperationSetPersistentPresence.class); supportedOpSets.add(OperationSetPersistentPresence.class);
mobilePhone = PhoneNumberI18nService.normalize(mobilePhone); mobilePhone = PhoneNumberI18nService.normalize(mobilePhone);
detail = new ContactDetail(mobilePhone, detail = new ContactDetail(mobilePhone,
ContactDetail.CATEGORY_PHONE, ContactDetail.Category.Phone,
new String[]{ContactDetail.LABEL_MOBILE}); new ContactDetail.SubCategory[]{
ContactDetail.SubCategory.Mobile});
detail.setSupportedOpSets(supportedOpSets); detail.setSupportedOpSets(supportedOpSets);
ret.add(detail); ret.add(detail);
} }
@ -231,9 +238,33 @@ private List<ContactDetail> getContactDetails(GoogleContactsEntry entry)
{ {
if(im.getValue() != GoogleContactsEntry.IMProtocol.OTHER) if(im.getValue() != GoogleContactsEntry.IMProtocol.OTHER)
{ {
detail = new ContactDetail(im.getKey(), ContactDetail.SubCategory imSubCat = null;
ContactDetail.CATEGORY_INSTANT_MESSAGING, switch(im.getValue())
new String[]{im.getValue().toString()}); {
case AIM:
imSubCat = ContactDetail.SubCategory.AIM;
break;
case ICQ:
imSubCat = ContactDetail.SubCategory.ICQ;
break;
case YAHOO:
imSubCat = ContactDetail.SubCategory.Yahoo;
break;
case JABBER:
imSubCat = ContactDetail.SubCategory.Jabber;
break;
case MSN:
imSubCat = ContactDetail.SubCategory.MSN;
break;
case GOOGLETALK:
imSubCat = ContactDetail.SubCategory.GoogleTalk;
break;
}
detail = new ContactDetail(
im.getKey(),
ContactDetail.Category.InstantMessaging,
new ContactDetail.SubCategory[]{imSubCat});
setIMCapabilities(detail, im.getValue()); setIMCapabilities(detail, im.getValue());

@ -1654,7 +1654,7 @@ else if(d instanceof MobilePhoneDetail)
localizedType = localizedType =
GuiActivator.getResources(). GuiActivator.getResources().
getI18NString( getI18NString(
"service.gui.PHONE"); "service.gui.HOME");
} }
phones.add(pnd.getNumber()); phones.add(pnd.getNumber());

@ -284,7 +284,7 @@ else if (opSetClass.equals(
String category = telephonyContact.getCategory(); String category = telephonyContact.getCategory();
if (category != null && category.equals(ContactDetail.CATEGORY_PHONE)) if (category != null && category.equals(ContactDetail.Category.Phone))
{ {
int index = findPhoneItemIndex(); int index = findPhoneItemIndex();
if (index < 0) if (index < 0)
@ -299,7 +299,7 @@ else if (opSetClass.equals(
category = ((ContactMenuItem) lastComp).getCategory(); category = ((ContactMenuItem) lastComp).getCategory();
if (category != null if (category != null
&& category.equals(ContactDetail.CATEGORY_PHONE)) && category.equals(ContactDetail.Category.Phone))
addSeparator(); addSeparator();
add(contactItem); add(contactItem);
@ -322,7 +322,7 @@ private int findPhoneItemIndex()
{ {
String category = ((ContactMenuItem) c).getCategory(); String category = ((ContactMenuItem) c).getCategory();
if (category == null if (category == null
|| !category.equals(ContactDetail.CATEGORY_PHONE)) || !category.equals(ContactDetail.Category.Phone))
continue; continue;
} }
else if (c instanceof JSeparator) else if (c instanceof JSeparator)

@ -50,6 +50,11 @@ public class SourceContactRightButtonMenu
*/ */
private SIPCommMenu callContactMenu; private SIPCommMenu callContactMenu;
/**
* Contact details menu.
*/
private SIPCommMenu contactDetailsMenu;
/** /**
* Add contact component. * Add contact component.
*/ */
@ -111,7 +116,7 @@ private Component initCallMenu()
final ContactDetail detail = details.next(); final ContactDetail detail = details.next();
// add all the contacts that support telephony to the call menu // add all the contacts that support telephony to the call menu
JMenuItem callContactItem = new JMenuItem(); JMenuItem callContactItem = new JMenuItem();
callContactItem.setText(detail.getContactAddress()); callContactItem.setText(detail.getDetail());
callContactItem.addActionListener(new ActionListener() callContactItem.addActionListener(new ActionListener()
{ {
public void actionPerformed(ActionEvent e) public void actionPerformed(ActionEvent e)
@ -139,14 +144,14 @@ public void actionPerformed(ActionEvent e)
else if (providersCount > 1) else if (providersCount > 1)
{ {
new ChooseCallAccountDialog( new ChooseCallAccountDialog(
detail.getContactAddress(), detail.getDetail(),
OperationSetBasicTelephony.class, providers) OperationSetBasicTelephony.class, providers)
.setVisible(true); .setVisible(true);
} }
else // providersCount == 1 else // providersCount == 1
{ {
CallManager.createCall( CallManager.createCall(
providers.get(0), detail.getContactAddress()); providers.get(0), detail.getDetail());
} }
} }
}); });

@ -1955,7 +1955,7 @@ else if (details.size() > 1)
final ContactDetail detail = detailsIter.next(); final ContactDetail detail = detailsIter.next();
JMenuItem addMenuItem JMenuItem addMenuItem
= new JMenuItem(detail.getContactAddress()); = new JMenuItem(detail.getDetail());
((JMenu) addContactComponentTmp).add(addMenuItem); ((JMenu) addContactComponentTmp).add(addMenuItem);
addMenuItem.addActionListener(new ActionListener() addMenuItem.addActionListener(new ActionListener()
@ -1995,7 +1995,7 @@ public static void showAddContactDialog(ContactDetail contactDetail)
if (preferredProvider != null) if (preferredProvider != null)
dialog.setSelectedAccount(preferredProvider); dialog.setSelectedAccount(preferredProvider);
dialog.setContactAddress(contactDetail.getContactAddress()); dialog.setContactAddress(contactDetail.getDetail());
dialog.setVisible(true); dialog.setVisible(true);
} }

@ -549,7 +549,7 @@ else if(d instanceof MobilePhoneDetail)
localizedType = localizedType =
GuiActivator.getResources(). GuiActivator.getResources().
getI18NString( getI18NString(
"service.gui.PHONE"); "service.gui.HOME");
} }
tip.addLine(null, (pnd.getNumber() + tip.addLine(null, (pnd.getNumber() +

@ -12,6 +12,8 @@
import javax.swing.*; import javax.swing.*;
import org.jitsi.service.resources.*;
import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.contactlist.*; import net.java.sip.communicator.impl.gui.main.contactlist.*;
import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.impl.gui.utils.*;
@ -20,7 +22,6 @@
import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.globalstatus.*; import net.java.sip.communicator.service.protocol.globalstatus.*;
import net.java.sip.communicator.util.*;
/** /**
* The <tt>SourceUIContact</tt> is the implementation of the UIContact for the * The <tt>SourceUIContact</tt> is the implementation of the UIContact for the
@ -70,8 +71,8 @@ public SourceUIContact( SourceContact contact,
if(contact.getContactDetails() != null) if(contact.getContactDetails() != null)
for(ContactDetail detail : contact.getContactDetails()) for(ContactDetail detail : contact.getContactDetails())
{ {
if(detail.getContactAddress() != null) if(detail.getDetail() != null)
searchStrings.add(detail.getContactAddress()); searchStrings.add(detail.getDetail());
} }
searchStrings.add(contact.getDisplayName()); searchStrings.add(contact.getDisplayName());
@ -211,7 +212,12 @@ public List<UIContactDetail> getContactDetails()
{ {
ContactDetail detail = details.next(); ContactDetail detail = details.next();
resultList.add(new SourceContactDetail(detail, null, sourceContact)); resultList.add(new SourceContactDetail(
detail,
getInternationalizedLabel(detail.getCategory()),
getInternationalizedLabels(
detail.getSubCategories().iterator()),
null, sourceContact));
} }
return resultList; return resultList;
} }
@ -243,7 +249,12 @@ public List<UIContactDetail> getContactDetailsForOperationSet(
&& supportedOperationSets.contains(opSetClass)) && supportedOperationSets.contains(opSetClass))
{ {
resultList.add(new SourceContactDetail( resultList.add(new SourceContactDetail(
detail, opSetClass, sourceContact)); detail,
getInternationalizedLabel(detail.getCategory()),
getInternationalizedLabels(
detail.getSubCategories().iterator()),
opSetClass,
sourceContact));
} }
} }
return resultList; return resultList;
@ -292,17 +303,22 @@ protected static class SourceContactDetail
* the underlying <tt>detail</tt> and the <tt>OperationSet</tt> class * the underlying <tt>detail</tt> and the <tt>OperationSet</tt> class
* for it. * for it.
* @param detail the underlying <tt>ContactDetail</tt> * @param detail the underlying <tt>ContactDetail</tt>
* @param category detail category string
* @param subCategories the detail list of sub-categories
* @param opSetClass the <tt>OperationSet</tt> class for the * @param opSetClass the <tt>OperationSet</tt> class for the
* preferred protocol provider * preferred protocol provider
* @param sourceContact the source contact
*/ */
public SourceContactDetail( ContactDetail detail, public SourceContactDetail( ContactDetail detail,
String category,
Collection<String> subCategories,
Class<? extends OperationSet> opSetClass, Class<? extends OperationSet> opSetClass,
SourceContact sourceContact) SourceContact sourceContact)
{ {
super( detail.getContactAddress(), super( detail.getDetail(),
detail.getContactAddress(), detail.getDetail(),
detail.getCategory(), category,
detail.getLabels(), subCategories,
null, null,
null, null,
null, null,
@ -391,27 +407,33 @@ public ExtendedTooltip getToolTip()
try try
{ {
List<ContactDetail> details = sourceContact.getContactDetails( List<ContactDetail> details = sourceContact.getContactDetails(
ContactDetail.CATEGORY_PHONE); ContactDetail.Category.Phone);
if (details != null && details.size() > 0) if (details != null && details.size() > 0)
addDetailsToToolTip(details, addDetailsToToolTip(
ContactDetail.CATEGORY_PHONE + "s", details,
GuiActivator.getResources()
.getI18NString("service.gui.PHONES"),
tip); tip);
details = sourceContact.getContactDetails( details = sourceContact.getContactDetails(
ContactDetail.CATEGORY_EMAIL); ContactDetail.Category.Email);
if (details != null && details.size() > 0) if (details != null && details.size() > 0)
addDetailsToToolTip(details, addDetailsToToolTip(
ContactDetail.CATEGORY_EMAIL + "s", details,
GuiActivator.getResources()
.getI18NString("service.gui.EMAILS"),
tip); tip);
details = sourceContact.getContactDetails( details = sourceContact.getContactDetails(
ContactDetail.CATEGORY_INSTANT_MESSAGING); ContactDetail.Category.InstantMessaging);
if (details != null && details.size() > 0) if (details != null && details.size() > 0)
addDetailsToToolTip(details, addDetailsToToolTip(
ContactDetail.CATEGORY_INSTANT_MESSAGING + "s", details,
GuiActivator.getResources()
.getI18NString("service.gui.INSTANT_MESSAGINGS"),
tip); tip);
} }
catch (OperationNotSupportedException e) catch (OperationNotSupportedException e)
@ -445,16 +467,19 @@ private void addDetailsToToolTip( List<ContactDetail> details,
while (detailsIter.hasNext()) while (detailsIter.hasNext())
{ {
contactDetail = detailsIter.next(); contactDetail = detailsIter.next();
Collection<String> labels = contactDetail.getLabels(); Collection<ContactDetail.SubCategory> subCategories
= contactDetail.getSubCategories();
JLabel[] jLabels = new JLabel[labels.size() + 1]; JLabel[] jLabels = new JLabel[subCategories.size() + 1];
int i = 0; int i = 0;
if (labels != null && labels.size() > 0) if (subCategories != null && subCategories.size() > 0)
{ {
Iterator<String> labelsIter = labels.iterator(); Iterator<ContactDetail.SubCategory> labelsIter
= subCategories.iterator();
while(labelsIter.hasNext()) while(labelsIter.hasNext())
{ {
JLabel label = new JLabel(labelsIter.next().toLowerCase()); JLabel label = new JLabel(
getInternationalizedLabel(labelsIter.next()));
label.setFont(label.getFont().deriveFont(Font.BOLD)); label.setFont(label.getFont().deriveFont(Font.BOLD));
label.setForeground(Color.GRAY); label.setForeground(Color.GRAY);
@ -463,12 +488,152 @@ private void addDetailsToToolTip( List<ContactDetail> details,
} }
} }
jLabels[i] = new JLabel(contactDetail.getContactAddress()); jLabels[i] = new JLabel(contactDetail.getDetail());
toolTip.addLine(jLabels); toolTip.addLine(jLabels);
} }
} }
/**
* Returns the internationalized category corresponding to the given
* <tt>ContactDetail.Category</tt>.
*
* @param category the <tt>ContactDetail.SubCategory</tt>, for which we
* would like to obtain an internationalized label
* @return the internationalized label corresponding to the given category
*/
protected String getInternationalizedLabel(ContactDetail.Category category)
{
if (category == null)
return null;
String categoryString = null;
ResourceManagementService resources = GuiActivator.getResources();
switch(category)
{
case Address:
categoryString = resources.getI18NString("service.gui.ADDRESS");
break;
case Email:
categoryString = resources.getI18NString("service.gui.EMAIL");
break;
case Personal:
categoryString = resources.getI18NString("service.gui.PERSONAL");
break;
case Organization:
categoryString = resources.getI18NString("service.gui.ORGANIZATION");
break;
case Phone:
categoryString = resources.getI18NString("service.gui.PHONE");
break;
case InstantMessaging:
categoryString = resources.getI18NString("service.gui.IM");
break;
}
return categoryString;
}
/**
* Returns a collection of internationalized string corresponding to the
* given subCategories.
*
* @param subCategories an Iterator over a list of
* <tt>ContactDetail.SubCategory</tt>s
* @return a collection of internationalized string corresponding to the
* given subCategories
*/
protected Collection<String> getInternationalizedLabels(
Iterator<ContactDetail.SubCategory> subCategories)
{
Collection<String> labels = new LinkedList<String>();
while (subCategories.hasNext())
{
labels.add(getInternationalizedLabel(subCategories.next()));
}
return labels;
}
/**
* Returns the internationalized label corresponding to the given category.
*
* @param subCategory the <tt>ContactDetail.SubCategory</tt>, for which we
* would like to obtain an internationalized label
* @return the internationalized label corresponding to the given category
*/
protected String getInternationalizedLabel(
ContactDetail.SubCategory subCategory)
{
if (subCategory == null)
return null;
String label = null;
ResourceManagementService resources = GuiActivator.getResources();
switch(subCategory)
{
case City:
label = resources.getI18NString("service.gui.CITY");
break;
case Country:
label = resources.getI18NString("service.gui.COUNTRY");
break;
case Fax:
label = resources.getI18NString("service.gui.FAX");
break;
case Home:
label = resources.getI18NString("service.gui.HOME");
break;
case HomePage:
label = resources.getI18NString("service.gui.HOME_PAGE");
break;
case JobTitle:
label = resources.getI18NString("service.gui.JOB_TITLE");
break;
case LastName:
label = resources.getI18NString("service.gui.LAST_NAME");
break;
case Mobile:
label = resources.getI18NString("service.gui.MOBILE_PHONE");
break;
case Name:
label = resources.getI18NString("service.gui.NAME");
break;
case Nickname:
label = resources.getI18NString("service.gui.NICKNAME");
break;
case Other:
label = resources.getI18NString("service.gui.OTHER");
break;
case PostalCode:
label = resources.getI18NString("service.gui.POSTAL_CODE");
break;
case Street:
label = resources.getI18NString("service.gui.STREET");
break;
case Work:
label = resources.getI18NString("service.gui.WORK_PHONE");
break;
case AIM:
case ICQ:
case Jabber:
case MSN:
case Yahoo:
case Skype:
case GoogleTalk:
case Facebook:
label = subCategory.value();
break;
}
return label;
}
/** /**
* Returns all custom action buttons for this notification contact. * Returns all custom action buttons for this notification contact.
* *

@ -145,7 +145,7 @@ private List<ContactDetail> getContactDetails(LdapPersonFound person)
// can be added as contacts // can be added as contacts
supportedOpSets.add(OperationSetPersistentPresence.class); supportedOpSets.add(OperationSetPersistentPresence.class);
detail = new ContactDetail(mail, ContactDetail.CATEGORY_EMAIL, detail = new ContactDetail(mail, ContactDetail.Category.Email,
null); null);
detail.setSupportedOpSets(supportedOpSets); detail.setSupportedOpSets(supportedOpSets);
ret.add(detail); ret.add(detail);
@ -161,8 +161,9 @@ private List<ContactDetail> getContactDetails(LdapPersonFound person)
supportedOpSets.add(OperationSetPersistentPresence.class); supportedOpSets.add(OperationSetPersistentPresence.class);
homePhone = PhoneNumberI18nService.normalize(homePhone); homePhone = PhoneNumberI18nService.normalize(homePhone);
detail = new ContactDetail(homePhone, detail = new ContactDetail(homePhone,
ContactDetail.CATEGORY_PHONE, ContactDetail.Category.Phone,
new String[]{ContactDetail.LABEL_HOME}); new ContactDetail.SubCategory[]{
ContactDetail.SubCategory.Home});
detail.setSupportedOpSets(supportedOpSets); detail.setSupportedOpSets(supportedOpSets);
ret.add(detail); ret.add(detail);
} }
@ -177,8 +178,9 @@ private List<ContactDetail> getContactDetails(LdapPersonFound person)
supportedOpSets.add(OperationSetPersistentPresence.class); supportedOpSets.add(OperationSetPersistentPresence.class);
workPhone = PhoneNumberI18nService.normalize(workPhone); workPhone = PhoneNumberI18nService.normalize(workPhone);
detail = new ContactDetail(workPhone, detail = new ContactDetail(workPhone,
ContactDetail.CATEGORY_PHONE, ContactDetail.Category.Phone,
new String[]{ContactDetail.LABEL_WORK}); new ContactDetail.SubCategory[]{
ContactDetail.SubCategory.Work});
detail.setSupportedOpSets(supportedOpSets); detail.setSupportedOpSets(supportedOpSets);
ret.add(detail); ret.add(detail);
} }
@ -193,8 +195,9 @@ private List<ContactDetail> getContactDetails(LdapPersonFound person)
supportedOpSets.add(OperationSetPersistentPresence.class); supportedOpSets.add(OperationSetPersistentPresence.class);
mobilePhone = PhoneNumberI18nService.normalize(mobilePhone); mobilePhone = PhoneNumberI18nService.normalize(mobilePhone);
detail = new ContactDetail(mobilePhone, detail = new ContactDetail(mobilePhone,
ContactDetail.CATEGORY_PHONE, ContactDetail.Category.Phone,
new String[]{ContactDetail.LABEL_MOBILE}); new ContactDetail.SubCategory[]{
ContactDetail.SubCategory.Mobile});
detail.setSupportedOpSets(supportedOpSets); detail.setSupportedOpSets(supportedOpSets);
ret.add(detail); ret.add(detail);
} }

@ -248,38 +248,95 @@ private ContactDetail createContactDetail(
String contactAddress, String contactAddress,
Object label) Object label)
{ {
String c, l; ContactDetail.Category c;
ContactDetail.SubCategory sc = null;
switch (property) switch (property)
{ {
case kABEmailProperty: case kABEmailProperty:
c = ContactDetail.CATEGORY_EMAIL; c = ContactDetail.Category.Email;
break; break;
case kABPhoneProperty: case kABPhoneProperty:
c = ContactDetail.CATEGORY_PHONE; c = ContactDetail.Category.Phone;
break; break;
case kABAIMInstantProperty: case kABAIMInstantProperty:
sc = ContactDetail.SubCategory.AIM;
c = ContactDetail.Category.InstantMessaging;
break;
case kABICQInstantProperty: case kABICQInstantProperty:
sc = ContactDetail.SubCategory.ICQ;
c = ContactDetail.Category.InstantMessaging;
break;
case kABJabberInstantProperty: case kABJabberInstantProperty:
sc = ContactDetail.SubCategory.Jabber;
c = ContactDetail.Category.InstantMessaging;
break;
case kABMSNInstantProperty: case kABMSNInstantProperty:
sc = ContactDetail.SubCategory.MSN;
c = ContactDetail.Category.InstantMessaging;
break;
case kABYahooInstantProperty: case kABYahooInstantProperty:
c = ContactDetail.CATEGORY_INSTANT_MESSAGING; sc = ContactDetail.SubCategory.Yahoo;
c = ContactDetail.Category.InstantMessaging;
break; break;
default: default:
c = null; c = null;
break; break;
} }
if (label == null) if (sc == null)
l = null;
else
{ {
l = LABEL_PATTERN.matcher((String) label).replaceAll("").trim(); if (label == null)
if (l.length() < 1) sc = null;
l = null; else
{
sc = getSubCategoryFromLabel(label);
}
} }
return new ContactDetail(contactAddress, c, new String[] { l }); return new ContactDetail(contactAddress,
c, new ContactDetail.SubCategory[] { sc });
}
/**
* Returns the ContactDetail.SubCategory corresponding to the given label.
*
* @param label the label to match to a <tt>ContactDetail.SubDirectory</tt>
* @return the <tt>ContactDetail.SubDirectory</tt> corresponding to the
* given label
*/
private ContactDetail.SubCategory getSubCategoryFromLabel(Object label)
{
String labelString
= LABEL_PATTERN.matcher((String) label).replaceAll("").trim();
if (labelString.length() < 1)
return null;
ContactDetail.SubCategory subCategory = null;
if (labelString.equalsIgnoreCase("home"))
subCategory = ContactDetail.SubCategory.Home;
else if (labelString.equalsIgnoreCase("work"))
subCategory = ContactDetail.SubCategory.Work;
else if (labelString.equalsIgnoreCase("other"))
subCategory = ContactDetail.SubCategory.Other;
else if (labelString.equalsIgnoreCase("mobile"))
subCategory = ContactDetail.SubCategory.Mobile;
else if (labelString.equalsIgnoreCase("homepage"))
subCategory = ContactDetail.SubCategory.HomePage;
else if (labelString.equalsIgnoreCase("street"))
subCategory = ContactDetail.SubCategory.Street;
else if (labelString.equalsIgnoreCase("ZIP"))
subCategory = ContactDetail.SubCategory.PostalCode;
else if (labelString.equalsIgnoreCase("country"))
subCategory = ContactDetail.SubCategory.Country;
else if (labelString.equalsIgnoreCase("city"))
subCategory = ContactDetail.SubCategory.City;
else if (labelString.equalsIgnoreCase("InstantMessageUsername"))
subCategory = ContactDetail.SubCategory.Nickname;
return subCategory;
} }
/** /**

@ -215,6 +215,26 @@ private static native void foreachMailUser(
String query, String query,
PtrCallback callback); PtrCallback callback);
private ContactDetail.Category getCategory(int propIndex)
{
switch (propIndex)
{
case dispidEmail1EmailAddress:
case dispidEmail2EmailAddress:
case dispidEmail3EmailAddress:
case PR_EMAIL_ADDRESS:
return ContactDetail.Category.Email;
case PR_BUSINESS2_TELEPHONE_NUMBER:
case PR_BUSINESS_TELEPHONE_NUMBER:
case PR_HOME2_TELEPHONE_NUMBER:
case PR_HOME_TELEPHONE_NUMBER:
case PR_MOBILE_TELEPHONE_NUMBER:
return ContactDetail.Category.Phone;
default:
return null;
}
}
/** /**
* Gets the set of <tt>ContactDetail</tt> labels to be assigned to a * Gets the set of <tt>ContactDetail</tt> labels to be assigned to a
* property specified by its index in {@link #MAPI_MAILUSER_PROP_IDS}. * property specified by its index in {@link #MAPI_MAILUSER_PROP_IDS}.
@ -224,37 +244,29 @@ private static native void foreachMailUser(
* @return the set of <tt>ContactDetail</tt> labels to be assigned to the * @return the set of <tt>ContactDetail</tt> labels to be assigned to the
* property specified by its index in <tt>MAPI_MAILUSER_PROP_IDS</tt> * property specified by its index in <tt>MAPI_MAILUSER_PROP_IDS</tt>
*/ */
private String[] getLabels(int propIndex) private ContactDetail.SubCategory[] getSubCategories(int propIndex)
{ {
switch (propIndex) switch (propIndex)
{ {
case dispidEmail1EmailAddress:
case dispidEmail2EmailAddress:
case dispidEmail3EmailAddress:
case PR_EMAIL_ADDRESS:
return new String[] { ContactDetail.CATEGORY_EMAIL };
case PR_BUSINESS2_TELEPHONE_NUMBER: case PR_BUSINESS2_TELEPHONE_NUMBER:
case PR_BUSINESS_TELEPHONE_NUMBER: case PR_BUSINESS_TELEPHONE_NUMBER:
return return
new String[] new ContactDetail.SubCategory[]
{ {
ContactDetail.CATEGORY_PHONE, ContactDetail.SubCategory.Work
ContactDetail.LABEL_WORK
}; };
case PR_HOME2_TELEPHONE_NUMBER: case PR_HOME2_TELEPHONE_NUMBER:
case PR_HOME_TELEPHONE_NUMBER: case PR_HOME_TELEPHONE_NUMBER:
return return
new String[] new ContactDetail.SubCategory[]
{ {
ContactDetail.CATEGORY_PHONE, ContactDetail.SubCategory.Home
ContactDetail.LABEL_HOME
}; };
case PR_MOBILE_TELEPHONE_NUMBER: case PR_MOBILE_TELEPHONE_NUMBER:
return return
new String[] new ContactDetail.SubCategory[]
{ {
ContactDetail.CATEGORY_PHONE, ContactDetail.SubCategory.Mobile
ContactDetail.LABEL_MOBILE
}; };
default: default:
return null; return null;
@ -382,7 +394,8 @@ private boolean onMailUser(long iUnknown)
ContactDetail contactDetail ContactDetail contactDetail
= new ContactDetail( = new ContactDetail(
stringProp, stringProp,
getLabels(propIndex)); getCategory(propIndex),
getSubCategories(propIndex));
contactDetail.setSupportedOpSets(supportedOpSets); contactDetail.setSupportedOpSets(supportedOpSets);
contactDetails.add(contactDetail); contactDetails.add(contactDetail);

@ -282,7 +282,7 @@ private SourceContact createSourceContact( SourceContact sourceContact,
sourceContact.getDisplayName(), sourceContact.getDisplayName(),
contactDetails); contactDetails);
genericContact.setDisplayDetails(contactDetail.getContactAddress()); genericContact.setDisplayDetails(contactDetail.getDetail());
return genericContact; return genericContact;
} }

@ -169,7 +169,7 @@ else if(d instanceof MobilePhoneDetail)
{ {
localizedType = localizedType =
PNContactSourceActivator.getResources() PNContactSourceActivator.getResources()
.getI18NString("service.gui.PHONE"); .getI18NString("service.gui.HOME");
} }
String contactName = contact.getDisplayName(); String contactName = contact.getDisplayName();

@ -36,138 +36,266 @@
public class ContactDetail public class ContactDetail
{ {
/** /**
* The standard/well-known category of a <tt>ContactDetail</tt> representing * Defines all possible categories for a <tt>ContactDetail</tt>.
* personal details, like name, last name, nickname.
*/ */
public static final String CATEGORY_PERSONAL = "Personal"; public enum Category
{
/** /**
* The standard/well-known category of a <tt>ContactDetail</tt> representing * The standard/well-known category of a <tt>ContactDetail</tt>
* organization details, like organization name and job title. * representing personal details, like name, last name, nickname.
*/ */
public static final String CATEGORY_ORGANIZATION = "Organisation"; Personal("Personal"),
/** /**
* The standard/well-known category of a <tt>ContactDetail</tt> representing * The standard/well-known category of a <tt>ContactDetail</tt>
* an e-mail address. * representing organization details, like organization name and job
*/ * title.
public static final String CATEGORY_EMAIL = "Email"; */
Organization("Organization"),
/**
* The standard/well-known category of a <tt>ContactDetail</tt> representing /**
* a contact address for instant messaging. * The standard/well-known category of a <tt>ContactDetail</tt>
*/ * representing an e-mail address.
public static final String CATEGORY_INSTANT_MESSAGING = "Instant Messaging"; */
Email("Email"),
/**
* The standard/well-known category of a <tt>ContactDetail</tt> representing /**
* a phone number. * The standard/well-known category of a <tt>ContactDetail</tt>
*/ * representing a contact address for instant messaging.
public static final String CATEGORY_PHONE = "Phone"; */
InstantMessaging("InstantMessaging"),
/**
* The standard/well-known category of a <tt>ContactDetail</tt> representing /**
* a postal address. * The standard/well-known category of a <tt>ContactDetail</tt>
*/ * representing a phone number.
public static final String CATEGORY_ADDRESS = "Address"; */
Phone("Phone"),
/**
* The standard/well-known label of a <tt>ContactDetail</tt> representing a /**
* name. It could be an organization name or a personal name. * The standard/well-known category of a <tt>ContactDetail</tt>
*/ * representing a postal address.
public static final String LABEL_NAME = "Name"; */
Address("Address");
/**
* The standard/well-known label of a <tt>ContactDetail</tt> representing a /**
* last name. * Current enum value.
*/ */
public static final String LABEL_LAST_NAME = "Last name"; private final String value;
/** /**
* The standard/well-known label of a <tt>ContactDetail</tt> representing a * Creates enum whith the specified value.
* nickname. *
*/ * @param value the value to set.
public static final String LABEL_NICK_NAME = "Nickname"; */
Category(String value)
/** {
* The standard/well-known label of a <tt>ContactDetail</tt> representing an this.value = value;
* address of a contact at their home. }
*/
public static final String LABEL_HOME = "Home";
/**
* The standard/well-known label of a <tt>ContactDetail</tt> representing a
* mobile contact address (e.g. a cell phone number).
*/
public static final String LABEL_MOBILE = "Mobile";
/**
* The standard/well-known label of a <tt>ContactDetail</tt> representing an
* address of a contact at their work.
*/
public static final String LABEL_WORK = "Work";
/**
* The standard/well-known label of a <tt>ContactDetail</tt> representing a
* fax number.
*/
public static final String LABEL_FAX = "Fax";
/**
* The standard/well-known label of a <tt>ContactDetail</tt> representing a
* different number.
*/
public static final String LABEL_OTHER = "Other";
/** /**
* The standard/well-known label of a <tt>ContactDetail</tt> representing a * Gets the value.
* country name. *
*/ * @return the value
public static final String LABEL_COUNTRY = "Country"; */
public String value()
{
return value;
}
/** /**
* The standard/well-known label of a <tt>ContactDetail</tt> representing a * Creates enum from its value.
* city name. *
*/ * @param value the enum's value.
public static final String LABEL_CITY = "City"; * @return created enum.
*/
public static Category fromString(String value)
{
if (value != null)
{
for (Category category : Category.values())
{
if (value.equalsIgnoreCase(category.value()))
{
return category;
}
}
return null;
}
return null;
}
}
/** /**
* The standard/well-known label of a <tt>ContactDetail</tt> representing a * Defines all possible sub-categories for a <tt>ContactDetail</tt>.
* street address.
*/ */
public static final String LABEL_STREET = "Street"; public enum SubCategory
{
/**
* The standard/well-known label of a <tt>ContactDetail</tt>
* representing a name. It could be an organization name or a personal
* name.
*/
Name("Name"),
/**
* The standard/well-known label of a <tt>ContactDetail</tt>
* representing a last name.
*/
LastName("LastName"),
/**
* The standard/well-known label of a <tt>ContactDetail</tt>
* representing a nickname.
*/
Nickname("Nickname"),
/**
* The standard/well-known label of a <tt>ContactDetail</tt>
* representing a postal code.
*/
HomePage("HomePage"),
/**
* The standard/well-known label of a <tt>ContactDetail</tt>
* representing an address of a contact at their home.
*/
Home("Home"),
/**
* The standard/well-known label of a <tt>ContactDetail</tt>
* representing a mobile contact address (e.g. a cell phone number).
*/
Mobile("Mobile"),
/**
* The standard/well-known label of a <tt>ContactDetail</tt>
* representing an address of a contact at their work.
*/
Work("Work"),
/**
* The standard/well-known label of a <tt>ContactDetail</tt>
* representing a fax number.
*/
Fax("Fax"),
/**
* The standard/well-known label of a <tt>ContactDetail</tt>
* representing a different number.
*/
Other("Other"),
/**
* The standard/well-known label of a <tt>ContactDetail</tt>
* representing an IM network (like for example jabber).
*/
AIM("AIM"),
ICQ("ICQ"),
MSN("MSN"),
Jabber("Jabber"),
Skype("Skype"),
Yahoo("Yahoo"),
Facebook("Facebook"),
GoogleTalk("GoogleTalk"),
/**
* The standard/well-known label of a <tt>ContactDetail</tt>
* representing a country name.
*/
Country("Country"),
/**
* The standard/well-known label of a <tt>ContactDetail</tt>
* representing a city name.
*/
City("City"),
/**
* The standard/well-known label of a <tt>ContactDetail</tt>
* representing a street address.
*/
Street("Street"),
/**
* The standard/well-known label of a <tt>ContactDetail</tt>
* representing a postal code.
*/
PostalCode("PostalCode"),
/**
* The standard/well-known label of a <tt>ContactDetail</tt>
* representing a job title.
*/
JobTitle("JobTitle");
/**
* Current enum value.
*/
private final String value;
/**
* Creates enum whith the specified value.
*
* @param value the value to set.
*/
SubCategory(String value)
{
this.value = value;
}
/** /**
* The standard/well-known label of a <tt>ContactDetail</tt> representing a * Gets the value.
* postal code. *
*/ * @return the value
public static final String LABEL_POSTAL_CODE = "Postal code"; */
public String value()
{
return value;
}
/** /**
* The standard/well-known label of a <tt>ContactDetail</tt> representing a * Creates enum from its value.
* job title. *
*/ * @param value the enum's value.
public static final String LABEL_JOB_TITLE = "Job title"; * @return created enum.
*/
public static SubCategory fromString(String value)
{
if (value != null)
{
for (SubCategory subCategory : SubCategory.values())
{
if (value.equalsIgnoreCase(subCategory.value()))
{
return subCategory;
}
}
return null;
}
return null;
}
}
/** /**
* The category of this <tt>ContactQuery</tt>. For example, * The category of this <tt>ContactQuery</tt>. For example,
* {@link #CATEGORY_PHONE} or {@link #CATEGORY_EMAIL}. * {@link #CATEGORY_PHONE} or {@link #CATEGORY_EMAIL}.
*/ */
private final String category; private final Category category;
/** /**
* The address of this contact detail. This should be the address through * The address of this contact detail. This should be the address through
* which the contact could be reached by one of the supported * which the contact could be reached by one of the supported
* <tt>OperationSet</tt>s (e.g. by IM, call). * <tt>OperationSet</tt>s (e.g. by IM, call).
*/ */
private final String contactAddress; protected String contactDetailValue;
/** /**
* The set of labels of this <tt>ContactDetail</tt>. The labels may be * The set of labels of this <tt>ContactDetail</tt>. The labels may be
* arbitrary and may include any of the standard/well-known labels defined * arbitrary and may include any of the standard/well-known labels defined
* by the <tt>LABEL_XXX</tt> constants of the <tt>ContactDetail</tt> class. * by the <tt>LABEL_XXX</tt> constants of the <tt>ContactDetail</tt> class.
*/ */
private final Collection<String> labels = new LinkedList<String>(); private final Collection<SubCategory> subCategories
= new LinkedList<SubCategory>();
/** /**
* A mapping of <tt>OperationSet</tt> classes and preferred protocol * A mapping of <tt>OperationSet</tt> classes and preferred protocol
@ -190,11 +318,12 @@ public class ContactDetail
/** /**
* Creates a <tt>ContactDetail</tt> by specifying the contact address, * Creates a <tt>ContactDetail</tt> by specifying the contact address,
* corresponding to this detail. * corresponding to this detail.
* @param contactAddress the contact address corresponding to this detail * @param contactDetailValue the contact detail value corresponding to this
* detail
*/ */
public ContactDetail(String contactAddress) public ContactDetail(String contactDetailValue)
{ {
this(contactAddress, null); this(contactDetailValue, null, null);
} }
/** /**
@ -202,83 +331,33 @@ public ContactDetail(String contactAddress)
* specific contact address and which is to be optionally labeled with a * specific contact address and which is to be optionally labeled with a
* specific set of labels. * specific set of labels.
* *
* @param contactAddress the contact address to be represented by the new * @param contactDetailValue the contact detail value to be represented by
* <tt>ContactDetail</tt> instance * the new <tt>ContactDetail</tt> instance
* @param labels the set of labels with which the new <tt>ContactDetail</tt> * @param category
* instance is to be labeled. The labels may be arbitrary and may include * @param subCategories the set of sub categories with which the new
* any of the standard/well-known labels defined by the <tt>LABEL_XXX</tt> * <tt>ContactDetail</tt> instance is to be labeled.
* constants of the <tt>ContactDetail</tt> class. For the sake of */
* convenience, <tt>null</tt> and duplicate values in the specified public ContactDetail( String contactDetailValue,
* <tt>String[]</tt> <tt>labels</tt> will be ignored i.e. will not appear in Category category,
* the set of labels reported by the new <tt>ContactDetail</tt> instance SubCategory[] subCategories)
* later on. Additionally, the <tt>category</tt> of the new
* <tt>ContactDetail</tt> instance will be implied from the specified
* <tt>labels</tt> by looking for the standard/well-known categories defined
* by the <tt>CATEGORY_XXX</tt> constants of the <tt>ContactDetail</tt>
* class
*/
public ContactDetail(String contactAddress, String[] labels)
{ {
// contactAddress // the value of the detail
this.contactAddress = contactAddress; this.contactDetailValue = contactDetailValue;
// category & labels // category & labels
String category = null; this.category = category;
if (labels != null) if (subCategories != null)
{ {
for (String label : labels) for (SubCategory subCategory : subCategories)
{ {
if ((label != null) && !this.labels.contains(label)) if ((subCategory != null)
&& !this.subCategories.contains(subCategory))
{ {
if (label.equals(CATEGORY_EMAIL) this.subCategories.add(subCategory);
|| label.equals(CATEGORY_INSTANT_MESSAGING)
|| label.equals(CATEGORY_PHONE))
category = label;
else
this.labels.add(label);
} }
} }
} }
this.category = category;
}
/**
* Initializes a new <tt>ContactDetail</tt> instance which is to represent a
* specific contact address and which is to be optionally labeled with a
* specific category and a specific set of labels.
*
* @param contactAddress the contact address to be represented by the new
* <tt>ContactDetail</tt> instance
* @param category the category (such as one of the <tt>CATEGORY_XXX</tt>
* constants defined by the <tt>ContactDetail</tt> class, for example) to be
* assigned to the new <tt>ContactDetail</tt> instance
* @param labels the set of labels with which the new <tt>ContactDetail</tt>
* instance is to be labeled. The labels may be arbitrary and may include
* any of the standard/well-known labels defined by the <tt>LABEL_XXX</tt>
* constants of the <tt>ContactDetail</tt> class. For the sake of
* convenience, <tt>null</tt> and duplicate values in the specified
* <tt>String[]</tt> <tt>labels</tt> will be ignored i.e. will not appear in
* the set of labels reported by the new <tt>ContactDetail</tt> instance
* later on.
*/
public ContactDetail(
String contactAddress,
String category, String[] labels)
{
// contactAddress
this.contactAddress = contactAddress;
// category
this.category = category;
// labels
if (labels != null)
{
for (String label : labels)
{
if ((label != null) && !this.labels.contains(label))
this.labels.add(label);
}
}
} }
/** /**
@ -336,23 +415,25 @@ public void setSupportedOpSets(
* @return the category of this <tt>ContactQuery</tt> if it has any; * @return the category of this <tt>ContactQuery</tt> if it has any;
* otherwise, <tt>null</tt> * otherwise, <tt>null</tt>
*/ */
public String getCategory() public Category getCategory()
{ {
return category; return category;
} }
/** /**
* Returns the contact address corresponding to this detail. * Returns the contact address corresponding to this detail.
*
* @return the contact address corresponding to this detail * @return the contact address corresponding to this detail
*/ */
public String getContactAddress() public String getDetail()
{ {
return contactAddress; return contactDetailValue;
} }
/** /**
* Returns the preferred <tt>ProtocolProviderService</tt> when using the * Returns the preferred <tt>ProtocolProviderService</tt> when using the
* given <tt>opSetClass</tt>. * given <tt>opSetClass</tt>.
*
* @param opSetClass the <tt>OperationSet</tt> class corresponding to a * @param opSetClass the <tt>OperationSet</tt> class corresponding to a
* certain action (e.g. sending an instant message, making a call, etc.). * certain action (e.g. sending an instant message, making a call, etc.).
* @return the preferred <tt>ProtocolProviderService</tt> corresponding to * @return the preferred <tt>ProtocolProviderService</tt> corresponding to
@ -412,9 +493,9 @@ public List<Class<? extends OperationSet>> getSupportedOperationSets()
* @return <tt>true</tt> if the specified <tt>label</tt> is contained in the * @return <tt>true</tt> if the specified <tt>label</tt> is contained in the
* set of labels of this <tt>ContactDetail</tt> * set of labels of this <tt>ContactDetail</tt>
*/ */
public boolean containsLabel(String label) public boolean containsSubCategory(SubCategory label)
{ {
return labels.contains(label); return subCategories.contains(label);
} }
/** /**
@ -426,8 +507,8 @@ public boolean containsLabel(String label)
* <tt>ContactDetail</tt> has no labels, the returned <tt>Collection</tt> is * <tt>ContactDetail</tt> has no labels, the returned <tt>Collection</tt> is
* empty. * empty.
*/ */
public Collection<String> getLabels() public Collection<SubCategory> getSubCategories()
{ {
return Collections.unmodifiableCollection(labels); return Collections.unmodifiableCollection(subCategories);
} }
} }

@ -0,0 +1,59 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.service.contactsource;
/**
* The <tt>EditableContactDetail</tt> is a <tt>ContactDetail</tt> that allows
* editing.
*
* @see ContactDetail
*
* @author Yana Stamcheva
*/
public class EditableContactDetail
extends ContactDetail
{
/**
* Creates a <tt>ContactDetail</tt> by specifying the contact address,
* corresponding to this detail.
* @param contactDetailValue the contact detail value corresponding to this
* detail
*/
public EditableContactDetail(String contactDetailValue)
{
super(contactDetailValue);
}
/**
* Initializes a new <tt>ContactDetail</tt> instance which is to represent a
* specific contact address and which is to be optionally labeled with a
* specific set of labels.
*
* @param contactDetailValue the contact detail value to be represented by
* the new <tt>ContactDetail</tt> instance
* @param category
* @param subCategories the set of sub categories with which the new
* <tt>ContactDetail</tt> instance is to be labeled.
*/
public EditableContactDetail(
String contactDetailValue,
ContactDetail.Category category,
ContactDetail.SubCategory[] subCategories)
{
super(contactDetailValue, category, subCategories);
}
/**
* Sets the given detail value.
*
* @param value the new value of the detail
*/
public void setDetail(String value)
{
contactDetailValue = value;
}
}

@ -0,0 +1,34 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.service.contactsource;
/**
* The <tt>EditableSourceContact</tt> is an extension to the
* <tt>SourceContact</tt> interface that allows editing.
*
* @see SourceContact
*
* @author Yana Stamcheva
*/
public interface EditableSourceContact
extends SourceContact
{
/**
* Adds a contact detail to the list of contact details.
*
* @param detail the <tt>ContactDetail</tt> to add
*/
public void addContactDetail(ContactDetail detail);
/**
* Removes the given <tt>ContactDetail</tt> from the list of details for
* this <tt>SourceContact</tt>.
*
* @param detail the <tt>ContactDetail</tt> to remove
*/
public void removeContactDetail(ContactDetail detail);
}

@ -115,13 +115,14 @@ public List<ContactDetail> getContactDetails(
* @return a list of all <tt>ContactDetail</tt>s corresponding to the given * @return a list of all <tt>ContactDetail</tt>s corresponding to the given
* category * category
*/ */
public List<ContactDetail> getContactDetails(String category) public List<ContactDetail> getContactDetails(
ContactDetail.Category category)
{ {
List<ContactDetail> contactDetails = new LinkedList<ContactDetail>(); List<ContactDetail> contactDetails = new LinkedList<ContactDetail>();
for (ContactDetail contactDetail : getContactDetails()) for (ContactDetail contactDetail : getContactDetails())
{ {
String detailCategory = contactDetail.getCategory(); ContactDetail.Category detailCategory = contactDetail.getCategory();
if (detailCategory != null && detailCategory.equals(category)) if (detailCategory != null && detailCategory.equals(category))
contactDetails.add(contactDetail); contactDetails.add(contactDetail);
} }

@ -70,7 +70,8 @@ public List<ContactDetail> getContactDetails(
* @throws OperationNotSupportedException if categories aren't supported * @throws OperationNotSupportedException if categories aren't supported
* for call history records * for call history records
*/ */
public List<ContactDetail> getContactDetails(String category) public List<ContactDetail> getContactDetails(
ContactDetail.Category category)
throws OperationNotSupportedException; throws OperationNotSupportedException;
/** /**

Loading…
Cancel
Save