aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/java/sip')
-rw-r--r--src/net/java/sip/communicator/impl/callhistory/CallHistoryContactSource.java22
-rw-r--r--src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsSourceService.java19
-rw-r--r--src/net/java/sip/communicator/impl/gui/GuiActivator.java3
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/MainFrame.java158
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/CallManager.java91
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/ReceivedCallDialog.java1
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/TransferCallDialog.java64
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java257
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatInviteDialog.java53
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/CallHistoryFilter.java19
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListSearchKeyDispatcher.java177
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java188
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/GenericUIContactImpl.java417
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/GroupNode.java14
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/InviteUIContact.java154
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/PresenceFilter.java9
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/SearchField.java70
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFilter.java129
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java218
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactDetailImpl.java35
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactImpl.java9
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/UIFilterQuery.java62
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ExternalContactSource.java8
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactListSource.java1
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIContact.java20
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ProtocolContactSourceServiceImpl.java217
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ShowMoreContact.java19
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/SourceUIContact.java26
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/StringContactSourceServiceImpl.java203
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContact.java16
-rw-r--r--src/net/java/sip/communicator/impl/gui/utils/InviteContactListFilter.java80
-rw-r--r--src/net/java/sip/communicator/impl/gui/utils/InviteContactTransferHandler.java153
-rw-r--r--src/net/java/sip/communicator/impl/gui/utils/InviteDialog.java446
-rw-r--r--src/net/java/sip/communicator/impl/gui/utils/OneChoiceInviteDialog.java154
-rw-r--r--src/net/java/sip/communicator/impl/ldap/LdapContactSourceService.java14
-rw-r--r--src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java41
-rw-r--r--src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactSourceService.java16
-rw-r--r--src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactSourceService.java16
-rw-r--r--src/net/java/sip/communicator/plugin/phonenumbercontactsource/PNContactSourceActivator.java217
-rw-r--r--src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactQuery.java228
-rw-r--r--src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java114
-rw-r--r--src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberSourceContact.java85
-rw-r--r--src/net/java/sip/communicator/plugin/phonenumbercontactsource/phonenumbercontactsource.manifest.mf12
-rw-r--r--src/net/java/sip/communicator/service/contactsource/AsyncContactQuery.java1
-rw-r--r--src/net/java/sip/communicator/service/contactsource/ContactDetail.java1
-rw-r--r--src/net/java/sip/communicator/service/contactsource/ContactSourceService.java32
-rw-r--r--src/net/java/sip/communicator/service/contactsource/GenericSourceContact.java35
-rw-r--r--src/net/java/sip/communicator/service/gui/ContactList.java133
-rw-r--r--src/net/java/sip/communicator/service/gui/ContactListContainer.java39
-rw-r--r--src/net/java/sip/communicator/service/gui/ContactListSearchFilter.java22
-rw-r--r--src/net/java/sip/communicator/service/gui/FilterQuery.java33
-rw-r--r--src/net/java/sip/communicator/service/gui/UIContactDetail.java77
-rw-r--r--src/net/java/sip/communicator/service/gui/event/MetaContactQuery.java (renamed from src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactQuery.java)2
-rw-r--r--src/net/java/sip/communicator/service/gui/event/MetaContactQueryEvent.java (renamed from src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactQueryEvent.java)2
-rw-r--r--src/net/java/sip/communicator/service/gui/event/MetaContactQueryListener.java (renamed from src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactQueryListener.java)2
-rw-r--r--src/net/java/sip/communicator/service/gui/event/MetaContactQueryStatusEvent.java (renamed from src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactQueryStatusEvent.java)2
-rw-r--r--src/net/java/sip/communicator/service/gui/event/MetaGroupQueryEvent.java (renamed from src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaGroupQueryEvent.java)2
-rw-r--r--src/net/java/sip/communicator/service/gui/gui.manifest.mf5
-rw-r--r--src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java42
-rw-r--r--src/net/java/sip/communicator/service/protocol/ProtocolProviderService.java15
60 files changed, 3565 insertions, 1135 deletions
diff --git a/src/net/java/sip/communicator/impl/callhistory/CallHistoryContactSource.java b/src/net/java/sip/communicator/impl/callhistory/CallHistoryContactSource.java
index cc6ede3..db504f9 100644
--- a/src/net/java/sip/communicator/impl/callhistory/CallHistoryContactSource.java
+++ b/src/net/java/sip/communicator/impl/callhistory/CallHistoryContactSource.java
@@ -274,13 +274,23 @@ public class CallHistoryContactSource
}
/**
- * Returns the identifier of this contact source. Some of the common
- * identifiers are defined here (For example the CALL_HISTORY identifier
- * should be returned by all call history implementations of this interface)
- * @return the identifier of this contact source
+ * Returns default type to indicate that this contact source can be queried
+ * by default filters.
+ *
+ * @return the type of this contact source
*/
- public String getIdentifier()
+ public int getType()
{
- return CALL_HISTORY;
+ return HISTORY_TYPE;
+ }
+
+ /**
+ * Returns the index of the contact source in the result list.
+ *
+ * @return the index of the contact source in the result list
+ */
+ public int getIndex()
+ {
+ return 0;
}
}
diff --git a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsSourceService.java b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsSourceService.java
index 7ce8ead..c946514 100644
--- a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsSourceService.java
+++ b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsSourceService.java
@@ -319,14 +319,13 @@ public class GoogleContactsSourceService
}
/**
- * Returns the identifier of this contact source. Some of the common
- * identifiers are defined here (For example the CALL_HISTORY identifier
- * should be returned by all call history implementations of this interface)
+ * Returns SEARCH_TYPE to indicate that this contact source
+ *
* @return the identifier of this contact source
*/
- public String getIdentifier()
+ public int getType()
{
- return "GoogleContacts";
+ return SEARCH_TYPE;
}
/**
@@ -416,4 +415,14 @@ public class GoogleContactsSourceService
{
this.phoneNumberprefix = phoneNumberprefix;
}
+
+ /**
+ * Returns the index of the contact source in the result list.
+ *
+ * @return the index of the contact source in the result list
+ */
+ public int getIndex()
+ {
+ return -1;
+ }
}
diff --git a/src/net/java/sip/communicator/impl/gui/GuiActivator.java b/src/net/java/sip/communicator/impl/gui/GuiActivator.java
index 026dd4a..1ec9479 100644
--- a/src/net/java/sip/communicator/impl/gui/GuiActivator.java
+++ b/src/net/java/sip/communicator/impl/gui/GuiActivator.java
@@ -313,7 +313,8 @@ public class GuiActivator implements BundleActivator
* <tt>protocolName</tt> and supporting the given <tt>operationSetClass</tt>
*/
public static List<ProtocolProviderService> getRegisteredProviders(
- String protocolName, Class<? extends OperationSet> operationSetClass)
+ String protocolName,
+ Class<? extends OperationSet> operationSetClass)
{
List<ProtocolProviderService> opSetProviders
= new LinkedList<ProtocolProviderService>();
diff --git a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
index 58b2e3d..a0f2eb9 100644
--- a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
+++ b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
@@ -56,7 +56,8 @@ import com.explodingpixels.macwidgets.*;
*/
public class MainFrame
extends SIPCommFrame
- implements ExportedWindow,
+ implements ContactListContainer,
+ ExportedWindow,
PluginComponentListener,
Skinnable
{
@@ -96,7 +97,7 @@ public class MainFrame
/**
* The search field shown above the contact list.
*/
- private final SearchField searchField;
+ private SearchField searchField;
/**
* A mapping of <tt>ProtocolProviderService</tt>s and their indexes.
@@ -165,6 +166,11 @@ public class MainFrame
private CallListener uiCallListener;
/**
+ * Contact list search key dispatcher;
+ */
+ private final ContactListSearchKeyDispatcher clKeyDispatcher;
+
+ /**
* Creates an instance of <tt>MainFrame</tt>.
*/
public MainFrame()
@@ -174,12 +180,12 @@ public class MainFrame
this.setUndecorated(true);
}
- this.searchField = new SearchField(this);
-
this.contactListPanel = new ContactListPane(this);
this.accountStatusPanel = new AccountStatusPanel(this);
+ this.searchField = new SearchField(this, TreeContactList.searchFilter);
+
menu = new MainMenu(this);
/*
@@ -233,7 +239,11 @@ public class MainFrame
KeyboardFocusManager keyManager
= KeyboardFocusManager.getCurrentKeyboardFocusManager();
- keyManager.addKeyEventDispatcher(new MainKeyDispatcher(keyManager));
+
+ clKeyDispatcher = new ContactListSearchKeyDispatcher( keyManager,
+ searchField,
+ this);
+ keyManager.addKeyEventDispatcher(clKeyDispatcher);
this.init();
@@ -471,6 +481,9 @@ public class MainFrame
public void setContactList(MetaContactListService contactList)
{
contactListPanel.initList(contactList);
+
+ searchField.setContactList(GuiActivator.getContactList());
+ clKeyDispatcher.setContactList(GuiActivator.getContactList());
}
/**
@@ -1826,144 +1839,11 @@ public class MainFrame
}
/**
- * The <tt>MainKeyDispatcher</tt> is added to pre-listen KeyEvents before
- * they're delivered to the current focus owner in order to introduce a
- * specific behavior for the <tt>SearchField</tt> on top of the contact
- * list.
- */
- private class MainKeyDispatcher implements KeyEventDispatcher
- {
- private KeyboardFocusManager keyManager;
-
- /**
- * Creates an instance of <tt>MainKeyDispatcher</tt>.
- * @param keyManager the parent <tt>KeyboardFocusManager</tt>
- */
- public MainKeyDispatcher(KeyboardFocusManager keyManager)
- {
- this.keyManager = keyManager;
- }
-
- /**
- * Dispatches the given <tt>KeyEvent</tt>.
- * @param e the <tt>KeyEvent</tt> to dispatch
- * @return <tt>true</tt> if the KeyboardFocusManager should take no
- * further action with regard to the KeyEvent; <tt>false</tt>
- * otherwise
- */
- public boolean dispatchKeyEvent(KeyEvent e)
- {
- // If this window is not the focus window or if the event is not
- // of type PRESSED we have nothing more to do here.
- if (!isFocused()
- || (e.getID() != KeyEvent.KEY_PRESSED
- && e.getID() != KeyEvent.KEY_TYPED)
- || (GuiActivator.getUIService()
- .getSingleWindowContainer() != null)
- && GuiActivator.getUIService()
- .getSingleWindowContainer().containsFocus())
- return false;
-
- // Ctrl-Enter || Cmd-Enter typed when this window is the focused
- // window.
- //
- // Tried to make this with key bindings first, but has a problem
- // with enter key binding. When the popup menu containing call
- // contacts was opened the default keyboard manager was prioritizing
- // the window ENTER key, which will open a chat and we wanted that
- // the enter starts a call with the selected contact from the menu.
- // This is why we need to do it here and to check if the
- // permanent focus owner is equal to the focus owner, which is not
- // the case when a popup menu is opened.
- if (e.getKeyCode() == KeyEvent.VK_ENTER
- && (e.isControlDown() || e.isMetaDown()))
- {
- ctrlEnterKeyTyped();
- return false;
- }
- else if (e.getKeyCode() == KeyEvent.VK_ENTER
- && keyManager.getFocusOwner()
- .equals(keyManager.getPermanentFocusOwner()))
- {
- enterKeyTyped();
- return false;
- }
-
- TreeContactList contactList
- = getContactListPanel().getContactList();
-
- // If the search field is the focus owner.
- if (searchField.isFocusOwner()
- && (e.getKeyCode() == KeyEvent.VK_UP
- || e.getKeyCode() == KeyEvent.VK_DOWN
- || e.getKeyCode() == KeyEvent.VK_PAGE_UP
- || e.getKeyCode() == KeyEvent.VK_PAGE_DOWN))
- {
- contactList.selectFirstContact();
- contactList.requestFocus();
- return false;
- }
-
- // If the contact list is the focus owner.
- if (contactList.isFocusOwner()
- && e.getKeyCode() == KeyEvent.VK_ESCAPE)
- {
- // Removes all current selections.
- contactList.removeSelectionRows(contactList.getSelectionRows());
-
- if (searchField.getText() != null)
- {
- searchField.requestFocus();
- }
- return false;
- }
-
- Object selectedObject = contactList.getSelectedValue();
-
- // No matter who is the focus owner.
- if (e.getKeyChar() == KeyEvent.CHAR_UNDEFINED
- || e.getKeyCode() == KeyEvent.VK_ENTER
- || e.getKeyCode() == KeyEvent.VK_DELETE
- || e.getKeyCode() == KeyEvent.VK_BACK_SPACE
- || e.getKeyCode() == KeyEvent.VK_TAB
- || e.getKeyCode() == KeyEvent.VK_SPACE
- || (selectedObject != null
- && selectedObject instanceof GroupNode
- && (e.getKeyChar() == '+'
- || e.getKeyChar() == '-')))
- {
- return false;
- }
-
- boolean singleWindowRule
- = GuiActivator.getUIService().getSingleWindowContainer() == null
- || contactList.isFocusOwner();
-
- if (!searchField.isFocusOwner()
- && keyManager.getFocusOwner() != null
- && singleWindowRule
- && keyManager.getFocusOwner()
- .equals(keyManager.getPermanentFocusOwner()))
- {
- // Request the focus in the search field if a letter is typed.
- searchField.requestFocusInWindow();
-
- // We re-dispatch the event to search field.
- keyManager.redispatchEvent(searchField, e);
-
- // We don't want to dispatch further this event.
- return true;
- }
- return false;
- }
- }
-
- /**
* Called when the ENTER key was typed when this window was the focused
* window. Performs the appropriate actions depending on the current state
* of the contact list.
*/
- private void enterKeyTyped()
+ public void enterKeyTyped()
{
if (unknownContactPanel != null && unknownContactPanel.isVisible())
{
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java b/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java
index dbd7e98..c7d2928 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java
@@ -19,7 +19,9 @@ import net.java.sip.communicator.impl.gui.main.*;
import net.java.sip.communicator.impl.gui.main.contactlist.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.contactlist.*;
+import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.ServerStoredDetails.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.service.protocol.media.*;
import net.java.sip.communicator.util.Logger;
@@ -1333,6 +1335,95 @@ public class CallManager
}
/**
+ * Searches for additional phone numbers found in contact information
+ * @return additional phone numbers found in contact information;
+ */
+ public static List<UIContactDetail> getAdditionalNumbers(
+ MetaContact metaContact)
+ {
+ List<UIContactDetail> telephonyContacts
+ = new ArrayList<UIContactDetail>();
+
+ Iterator<Contact> contacts = metaContact.getContacts();
+
+ while(contacts.hasNext())
+ {
+ Contact contact = contacts.next();
+ OperationSetServerStoredContactInfo infoOpSet =
+ contact.getProtocolProvider().getOperationSet(
+ OperationSetServerStoredContactInfo.class);
+ Iterator<GenericDetail> details;
+ ArrayList<String> phones = new ArrayList<String>();
+
+ if(infoOpSet != null)
+ {
+ details = infoOpSet.getAllDetailsForContact(contact);
+
+ while(details.hasNext())
+ {
+ GenericDetail d = details.next();
+ if(d instanceof PhoneNumberDetail &&
+ !(d instanceof PagerDetail) &&
+ !(d instanceof FaxDetail))
+ {
+ PhoneNumberDetail pnd = (PhoneNumberDetail)d;
+ if(pnd.getNumber() != null &&
+ pnd.getNumber().length() > 0)
+ {
+ String localizedType = null;
+
+ if(d instanceof WorkPhoneDetail)
+ {
+ localizedType =
+ GuiActivator.getResources().
+ getI18NString(
+ "service.gui.WORK_PHONE");
+ }
+ else if(d instanceof MobilePhoneDetail)
+ {
+ localizedType =
+ GuiActivator.getResources().
+ getI18NString(
+ "service.gui.MOBILE_PHONE");
+ }
+ else
+ {
+ localizedType =
+ GuiActivator.getResources().
+ getI18NString(
+ "service.gui.PHONE");
+ }
+
+ phones.add(pnd.getNumber());
+
+ UIContactDetail cd =
+ new UIContactDetailImpl(
+ pnd.getNumber(),
+ pnd.getNumber() +
+ " (" + localizedType + ")",
+ null,
+ new ArrayList<String>(),
+ null,
+ null,
+ null,
+ pnd)
+ {
+ public PresenceStatus getPresenceStatus()
+ {
+ return null;
+ }
+ };
+ telephonyContacts.add(cd);
+ }
+ }
+ }
+ }
+ }
+
+ return telephonyContacts;
+ }
+
+ /**
* Adds a missed call notification.
*
* @param peerName the name of the peer
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/ReceivedCallDialog.java b/src/net/java/sip/communicator/impl/gui/main/call/ReceivedCallDialog.java
index 81807bc..071acd9 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/ReceivedCallDialog.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/ReceivedCallDialog.java
@@ -13,7 +13,6 @@ import java.util.*;
import javax.swing.*;
import net.java.sip.communicator.impl.gui.*;
-import net.java.sip.communicator.impl.gui.main.contactlist.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/TransferCallDialog.java b/src/net/java/sip/communicator/impl/gui/main/call/TransferCallDialog.java
index 2446722..9ead3b8 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/TransferCallDialog.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/TransferCallDialog.java
@@ -8,15 +8,15 @@ package net.java.sip.communicator.impl.gui.main.call;
import java.awt.*;
import java.awt.event.*;
-import java.util.*;
import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
import net.java.sip.communicator.impl.gui.utils.*;
-import net.java.sip.communicator.service.contactlist.*;
+import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.protocol.*;
/**
- * Represents a <code>Dialog</code> which allows specifying the target contact
+ * Represents a <tt>Dialog</tt> which allows specifying the target contact
* address of a transfer-call operation.
*
* @author Yana Stamcheva
@@ -25,6 +25,11 @@ public class TransferCallDialog
extends OneChoiceInviteDialog
{
/**
+ * The peer to transfer.
+ */
+ private final CallPeer transferPeer;
+
+ /**
* Creates a <tt>TransferCallDialog</tt> by specifying the peer to transfer
* @param peer the peer to transfer
*/
@@ -33,6 +38,8 @@ public class TransferCallDialog
super(GuiActivator.getResources()
.getI18NString("service.gui.TRANSFER_CALL_TITLE"));
+ this.transferPeer = peer;
+
this.initContactListData(peer.getProtocolProvider());
this.setInfoText(GuiActivator.getResources()
@@ -52,16 +59,11 @@ public class TransferCallDialog
CallManager.transferCall(peer, transferString);
else
{
- MetaContact metaContact = getSelectedMetaContact();
+ UIContact uiContact = getSelectedContact();
- if (metaContact != null)
+ if (uiContact != null)
{
- Iterator<Contact> contactsIter = metaContact
- .getContactsForProvider(peer.getProtocolProvider());
-
- if (contactsIter.hasNext())
- CallManager.transferCall(peer,
- contactsIter.next().getAddress());
+ transferToContact(uiContact);
}
}
setVisible(false);
@@ -81,32 +83,34 @@ public class TransferCallDialog
/**
* Initializes the left contact list with the contacts that could be added
* to the current chat session.
+ *
* @param protocolProvider the protocol provider from which to initialize
* the contact list data
*/
private void initContactListData(ProtocolProviderService protocolProvider)
{
- MetaContactListService metaContactListService
- = GuiActivator.getContactListService();
-
- Iterator<MetaContact> contactListIter = metaContactListService
- .findAllMetaContactsForProvider(protocolProvider);
+ contactList.addContactSource(
+ new ProtocolContactSourceServiceImpl(
+ protocolProvider, OperationSetBasicTelephony.class));
+ contactList.addContactSource(
+ new StringContactSourceServiceImpl(
+ protocolProvider, OperationSetBasicTelephony.class));
- while (contactListIter.hasNext())
- {
- MetaContact metaContact = contactListIter.next();
-
- this.addMetaContact(metaContact);
- }
+ contactList.applyDefaultFilter();
}
- /*
- * (non-Javadoc)
- *
- * @see
- * net.java.sip.communicator.impl.gui.customcontrols.SIPCommDialog#close
- * (boolean)
+ /**
+ * Transfer the transfer peer to the given <tt>UIContact</tt>.
+ *
+ * @param uiContact the contact to transfer to
*/
- @Override
- protected void close(boolean isEscaped) {}
+ private void transferToContact(UIContact uiContact)
+ {
+ UIContactDetail contactDetail = uiContact
+ .getDefaultContactDetail(
+ OperationSetBasicTelephony.class);
+
+ CallManager.transferCall( transferPeer,
+ contactDetail.getAddress());
+ }
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java
index a4d9a1f..067fa87 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferenceInviteDialog.java
@@ -15,8 +15,10 @@ import javax.swing.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.call.*;
+import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
import net.java.sip.communicator.impl.gui.utils.*;
-import net.java.sip.communicator.service.contactlist.*;
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.swing.*;
// disambiguation
@@ -51,6 +53,16 @@ public class ConferenceInviteDialog
private final Call call;
/**
+ * The current provider contact source.
+ */
+ private ContactSourceService currentProviderContactSource;
+
+ /**
+ * The current string contact source.
+ */
+ private ContactSourceService currentStringContactSource;
+
+ /**
* Creates <tt>ConferenceInviteDialog</tt> by specifying the call, to which
* the contacts are invited.
*
@@ -128,8 +140,6 @@ public class ConferenceInviteDialog
{
lastSelectedAccount = accountSelectorBoxSelectedItem;
- //removeAllSelectedContacts();
-
initContactListData(
(ProtocolProviderService) accountSelectorBox
.getSelectedItem());
@@ -141,14 +151,16 @@ public class ConferenceInviteDialog
{
public void actionPerformed(ActionEvent e)
{
- if (getSelectedMetaContacts() != null
- || getSelectedStrings() != null)
+ Collection<UIContact> selectedContacts
+ = destContactList.getContacts(null);
+
+ if (selectedContacts != null && selectedContacts.size() > 0)
{
ProtocolProviderService selectedProvider
= (ProtocolProviderService) accountSelectorBox
.getSelectedItem();
- inviteContacts();
+ inviteContacts(selectedContacts);
// Store the last used account in order to pre-select it
// next time.
@@ -226,94 +238,73 @@ public class ConferenceInviteDialog
*/
private void initContactListData(ProtocolProviderService protocolProvider)
{
- // re-init list.
- this.removeAllMetaContacts();
+ this.setCurrentProvider(protocolProvider);
- MetaContactListService metaContactListService
- = GuiActivator.getContactListService();
+ srcContactList.removeContactSource(currentProviderContactSource);
+ srcContactList.removeContactSource(currentStringContactSource);
- Iterator<MetaContact> contactListIter = metaContactListService
- .findAllMetaContactsForProvider(protocolProvider);
+ currentProviderContactSource
+ = new ProtocolContactSourceServiceImpl(
+ protocolProvider,
+ OperationSetBasicTelephony.class);
+ currentStringContactSource
+ = new StringContactSourceServiceImpl(
+ protocolProvider,
+ OperationSetBasicTelephony.class);
- while (contactListIter.hasNext())
- {
- MetaContact metaContact = contactListIter.next();
+ srcContactList.addContactSource(currentProviderContactSource);
+ srcContactList.addContactSource(currentStringContactSource);
- if (!containsContact(metaContact))
- {
- if (metaContact.getDefaultContact(
- OperationSetBasicTelephony.class) != null)
- addMetaContact(metaContact);
- }
- }
+ srcContactList.applyDefaultFilter();
}
/**
* Invites the contacts to the chat conference.
+ *
+ * @param contacts the list of contacts to invite
*/
- private void inviteContacts()
+ private void inviteContacts(Collection<UIContact> contacts)
{
ProtocolProviderService selectedProvider = null;
- Map<ProtocolProviderService, List<String>> selectedProviderCallees =
- new HashMap<ProtocolProviderService, List<String>>();
+ Map<ProtocolProviderService, List<String>> selectedProviderCallees
+ = new HashMap<ProtocolProviderService, List<String>>();
List<String> callees = null;
- // Obtain selected contacts.
- Enumeration<MetaContact> selectedContacts = getSelectedMetaContacts();
+ Iterator<UIContact> contactsIter = contacts.iterator();
- if (selectedContacts != null)
+ while (contactsIter.hasNext())
{
- while (selectedContacts.hasMoreElements())
- {
- MetaContact metaContact
- = selectedContacts.nextElement();
+ UIContact uiContact = contactsIter.next();
- Iterator<Contact> contactsIter = metaContact.getContacts();
+ Iterator<UIContactDetail> contactDetailsIter = uiContact
+ .getContactDetailsForOperationSet(
+ OperationSetBasicTelephony.class).iterator();
- // We invite the first protocol contact that corresponds to the
- // invite provider.
- if (contactsIter.hasNext())
- {
- Contact inviteContact = contactsIter.next();
- selectedProvider = inviteContact.getProtocolProvider();
-
- if(selectedProviderCallees.get(selectedProvider) != null)
- {
- callees = selectedProviderCallees.get(selectedProvider);
- }
- else
- {
- callees = new ArrayList<String>();
- }
-
- callees.add(inviteContact.getAddress());
- selectedProviderCallees.put(selectedProvider, callees);
- }
- }
- }
-
- // Obtain selected strings.
- Enumeration<ContactWithProvider> selectedContactWithProvider =
- getSelectedContactsWithProvider();
-
- if (selectedContactWithProvider != null)
- {
- while (selectedContactWithProvider.hasMoreElements())
+ // We invite the first protocol contact that corresponds to the
+ // invite provider.
+ if (contactDetailsIter.hasNext())
{
- ContactWithProvider c =
- selectedContactWithProvider.nextElement();
- selectedProvider = c.getProvider();
+ UIContactDetail inviteDetail = contactDetailsIter.next();
+ selectedProvider = inviteDetail
+ .getPreferredProtocolProvider(
+ OperationSetBasicTelephony.class);
- if(selectedProviderCallees.get(selectedProvider) != null)
+ if (selectedProvider == null)
+ selectedProvider
+ = (ProtocolProviderService) accountSelectorBox
+ .getSelectedItem();
+
+ if(selectedProvider != null
+ && selectedProviderCallees.get(selectedProvider) != null)
{
callees = selectedProviderCallees.get(selectedProvider);
}
else
{
- callees = new ArrayList<String>();
+ callees = new ArrayList<String>();
}
- callees.add(c.getAddress());
+ callees.add(inviteDetail.getAddress());
selectedProviderCallees.put(selectedProvider, callees);
}
}
@@ -321,7 +312,7 @@ public class ConferenceInviteDialog
if(call != null)
{
Map.Entry<ProtocolProviderService, List<String>> entry;
- if(selectedProviderCallees.size() == 1
+ if (selectedProviderCallees.size() == 1
&& (entry = selectedProviderCallees.entrySet().iterator().next())
!= null
&& call.getProtocolProvider().equals(entry.getKey()))
@@ -344,6 +335,7 @@ public class ConferenceInviteDialog
// one provider, normal conf call
Map.Entry<ProtocolProviderService, List<String>> entry =
selectedProviderCallees.entrySet().iterator().next();
+
CallManager.createConferenceCall(
entry.getValue().toArray(
new String[entry.getValue().size()]),
@@ -356,131 +348,4 @@ public class ConferenceInviteDialog
}
}
}
-
- /**
- * Check if the given <tt>metaContact</tt> is already contained in the call.
- *
- * @param metaContact the <tt>Contact</tt> to check for
- * @return <tt>true</tt> if the given <tt>metaContact</tt> is already
- * contained in the call, otherwise - returns <tt>false</tt>
- */
- private boolean containsContact(MetaContact metaContact)
- {
- // If the call is not yet created we just return false.
- if (call == null)
- return false;
-
- Iterator<? extends CallPeer> callPeers = call.getCallPeers();
-
- while(callPeers.hasNext())
- {
- CallPeer callPeer = callPeers.next();
-
- if(metaContact.containsContact(callPeer.getContact()))
- return true;
- }
-
- return false;
- }
-
- /**
- * Moves a string from left to right.
- */
- @Override
- protected void moveStringFromLeftToRight()
- {
- String newContactText = newContactField.getText();
-
- ContactWithProvider c = new ContactWithProvider(
- newContactText, (ProtocolProviderService) accountSelectorBox
- .getSelectedItem());
- if (newContactText != null && newContactText.length() > 0)
- selectedContactListModel.addElement(c);
-
- newContactField.setText("");
- }
-
- /**
- * Returns an enumeration of the list of selected Strings.
- * @return an enumeration of the list of selected Strings
- */
- public Enumeration<ContactWithProvider> getSelectedContactsWithProvider()
- {
- if (selectedContactListModel.getSize() == 0)
- return null;
-
- Vector<ContactWithProvider> selectedStrings =
- new Vector<ContactWithProvider>();
- Enumeration<?> selectedContacts = selectedContactListModel.elements();
- while(selectedContacts.hasMoreElements())
- {
- Object contact = selectedContacts.nextElement();
- if (contact instanceof ContactWithProvider)
- selectedStrings.add((ContactWithProvider)contact);
- }
-
- return selectedStrings.elements();
- }
-
- /**
- * Contact with the provider to call him.
- *
- * @author Sebastien Vincent
- */
- private class ContactWithProvider
- {
- /**
- * The provider.
- */
- private final ProtocolProviderService provider;
-
- /**
- * The contact.
- */
- private final String contact;
-
- /**
- * Constructor.
- *
- * @param contact the contact
- * @param provider the provider
- */
- public ContactWithProvider(String contact,
- ProtocolProviderService provider)
- {
- this.contact = contact;
- this.provider = provider;
- }
-
- /**
- * Returns the contact
- *
- * @return the contact
- */
- public String getAddress()
- {
- return contact;
- }
-
- /**
- * Returns the provider.
- *
- * @return the provider
- */
- public ProtocolProviderService getProvider()
- {
- return provider;
- }
-
- /**
- * Returns <tt>String</tt> representation.
- *
- * @return <tt>String</tt> representation
- */
- @Override
- public String toString()
- {
- return contact;
- }
- }
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatInviteDialog.java b/src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatInviteDialog.java
index c9813b3..ac5996d 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatInviteDialog.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/conference/ChatInviteDialog.java
@@ -11,9 +11,9 @@ import java.util.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.chat.*;
-import net.java.sip.communicator.impl.gui.main.contactlist.*;
+import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
import net.java.sip.communicator.impl.gui.utils.*;
-import net.java.sip.communicator.service.contactlist.*;
+import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.protocol.*;
/**
@@ -70,20 +70,12 @@ public class ChatInviteDialog
{
this.inviteChatTransport = chatPanel.findInviteChatTransport();
- MetaContactListService metaContactListService
- = GuiActivator.getContactListService();
+ srcContactList.addContactSource(
+ new ProtocolContactSourceServiceImpl(
+ inviteChatTransport.getProtocolProvider(),
+ OperationSetMultiUserChat.class));
- Iterator<MetaContact> contactListIter = metaContactListService
- .findAllMetaContactsForProvider(
- inviteChatTransport.getProtocolProvider());
-
- while (contactListIter.hasNext())
- {
- MetaContact metaContact = contactListIter.next();
-
- if(TreeContactList.presenceFilter.isMatching(metaContact))
- this.addMetaContact(metaContact);
- }
+ srcContactList.applyDefaultFilter();
}
/**
@@ -91,44 +83,33 @@ public class ChatInviteDialog
*/
private void inviteContacts()
{
- java.util.List<String> selectedContactAddresses =
- new ArrayList<String>();
+ Collection<String> selectedContactAddresses = new ArrayList<String>();
// Obtain selected contacts.
- Enumeration<MetaContact> selectedContacts = getSelectedMetaContacts();
+ Iterator<UIContact> selectedContacts
+ = destContactList.getContacts(null).iterator();
if (selectedContacts != null)
{
- while (selectedContacts.hasMoreElements())
+ while (selectedContacts.hasNext())
{
- MetaContact metaContact
- = selectedContacts.nextElement();
+ UIContact uiContact = selectedContacts.next();
- Iterator<Contact> contactsIter = metaContact
- .getContactsForProvider(
- inviteChatTransport.getProtocolProvider());
+ Iterator<UIContactDetail> contactsIter
+ = uiContact.getContactDetailsForOperationSet(
+ OperationSetMultiUserChat.class).iterator();
// We invite the first protocol contact that corresponds to the
// invite provider.
if (contactsIter.hasNext())
{
- Contact inviteContact = contactsIter.next();
+ UIContactDetail inviteDetail = contactsIter.next();
- selectedContactAddresses.add(inviteContact.getAddress());
+ selectedContactAddresses.add(inviteDetail.getAddress());
}
}
}
- // Obtain selected strings.
- Enumeration<String> selectedStrings = getSelectedStrings();
- if (selectedStrings != null)
- {
- while (selectedStrings.hasMoreElements())
- {
- selectedContactAddresses.add(selectedStrings.nextElement());
- }
- }
-
// Invite all selected.
if (selectedContactAddresses.size() > 0)
{
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/CallHistoryFilter.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/CallHistoryFilter.java
index b688c21..82d93e4 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/CallHistoryFilter.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/CallHistoryFilter.java
@@ -37,20 +37,17 @@ public class CallHistoryFilter
addMatching(notificationSource);
Collection<UIContactSource> contactSources
- = GuiActivator.getContactList().getContactSources();
+ = GuiActivator.getContactList()
+ .getContactSources(ContactSourceService.HISTORY_TYPE);
// Then add Call history contact source.
for (UIContactSource contactSource : contactSources)
{
- ContactSourceService sourceService
- = contactSource.getContactSourceService();
-
- if (!sourceService.getIdentifier()
- .equals(ContactSourceService.CALL_HISTORY))
- continue;
-
// We're in a case of call history contact source.
- ContactQuery query = sourceService.queryContactSource("", 50);
+ ContactQuery query
+ = contactSource.getContactSourceService()
+ .queryContactSource("", 50);
+
filterQuery.addContactQuery(query);
// Add first available results.
@@ -80,8 +77,8 @@ public class CallHistoryFilter
{
SourceContact sourceContact = (SourceContact) descriptor;
- if (sourceContact.getContactSource().getIdentifier()
- .equals(ContactSourceService.CALL_HISTORY))
+ if (sourceContact.getContactSource().getType()
+ == ContactSourceService.HISTORY_TYPE)
return true;
}
else if (uiContact instanceof NotificationContact)
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListSearchKeyDispatcher.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListSearchKeyDispatcher.java
new file mode 100644
index 0000000..4ec8228
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListSearchKeyDispatcher.java
@@ -0,0 +1,177 @@
+/*
+ * 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.impl.gui.main.contactlist;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.service.gui.*;
+
+/**
+ * The <tt>MainKeyDispatcher</tt> is added to pre-listen KeyEvents before
+ * they're delivered to the current focus owner in order to introduce a
+ * specific behavior for the <tt>SearchField</tt> on top of the contact
+ * list.
+ *
+ * @author Yana Stamcheva
+ */
+public class ContactListSearchKeyDispatcher
+ implements KeyEventDispatcher
+{
+ /**
+ * The keyboard focus manager.
+ */
+ private KeyboardFocusManager keyManager;
+
+ /**
+ * The contact list on which this key dispatcher works.
+ */
+ private ContactList contactList;
+
+ /**
+ * The search field of this key dispatcher.
+ */
+ private final SearchField searchField;
+
+ /**
+ * The container of the contact list.
+ */
+ private final ContactListContainer contactListContainer;
+
+ /**
+ * Creates an instance of <tt>MainKeyDispatcher</tt>.
+ * @param keyManager the parent <tt>KeyboardFocusManager</tt>
+ */
+ public ContactListSearchKeyDispatcher( KeyboardFocusManager keyManager,
+ SearchField searchField,
+ ContactListContainer container)
+ {
+ this.keyManager = keyManager;
+ this.searchField = searchField;
+ this.contactListContainer = container;
+ }
+
+ /**
+ * Sets the contact list.
+ *
+ * @param contactList the contact list to set
+ */
+ public void setContactList(ContactList contactList)
+ {
+ this.contactList = contactList;
+ }
+
+ /**
+ * Dispatches the given <tt>KeyEvent</tt>.
+ * @param e the <tt>KeyEvent</tt> to dispatch
+ * @return <tt>true</tt> if the KeyboardFocusManager should take no
+ * further action with regard to the KeyEvent; <tt>false</tt>
+ * otherwise
+ */
+ public boolean dispatchKeyEvent(KeyEvent e)
+ {
+ // If this window is not the focus window or if the event is not
+ // of type PRESSED we have nothing more to do here.
+ if (!contactListContainer.isFocused()
+ || (e.getID() != KeyEvent.KEY_PRESSED
+ && e.getID() != KeyEvent.KEY_TYPED)
+ || (GuiActivator.getUIService()
+ .getSingleWindowContainer() != null)
+ && GuiActivator.getUIService()
+ .getSingleWindowContainer().containsFocus())
+ return false;
+
+ // Ctrl-Enter || Cmd-Enter typed when this window is the focused
+ // window.
+ //
+ // Tried to make this with key bindings first, but has a problem
+ // with enter key binding. When the popup menu containing call
+ // contacts was opened the default keyboard manager was prioritizing
+ // the window ENTER key, which will open a chat and we wanted that
+ // the enter starts a call with the selected contact from the menu.
+ // This is why we need to do it here and to check if the
+ // permanent focus owner is equal to the focus owner, which is not
+ // the case when a popup menu is opened.
+ if (e.getKeyCode() == KeyEvent.VK_ENTER
+ && (e.isControlDown() || e.isMetaDown()))
+ {
+ contactListContainer.ctrlEnterKeyTyped();
+ return false;
+ }
+ else if (e.getKeyCode() == KeyEvent.VK_ENTER
+ && keyManager.getFocusOwner()
+ .equals(keyManager.getPermanentFocusOwner()))
+ {
+ contactListContainer.enterKeyTyped();
+ return false;
+ }
+
+ // If the search field is the focus owner.
+ if (searchField.isFocusOwner()
+ && (e.getKeyCode() == KeyEvent.VK_UP
+ || e.getKeyCode() == KeyEvent.VK_DOWN
+ || e.getKeyCode() == KeyEvent.VK_PAGE_UP
+ || e.getKeyCode() == KeyEvent.VK_PAGE_DOWN))
+ {
+ contactList.selectFirstContact();
+ contactList.getComponent().requestFocus();
+ return false;
+ }
+
+ // If the contact list is the focus owner.
+ if (contactList.getComponent().isFocusOwner()
+ && e.getKeyCode() == KeyEvent.VK_ESCAPE)
+ {
+ // Removes all current selections.
+ contactList.removeSelection();
+
+ if (searchField.getText() != null)
+ {
+ searchField.requestFocus();
+ }
+ return false;
+ }
+
+ UIGroup selectedGroup = contactList.getSelectedGroup();
+
+ // No matter who is the focus owner.
+ if (e.getKeyChar() == KeyEvent.CHAR_UNDEFINED
+ || e.getKeyCode() == KeyEvent.VK_ENTER
+ || e.getKeyCode() == KeyEvent.VK_DELETE
+ || e.getKeyCode() == KeyEvent.VK_BACK_SPACE
+ || e.getKeyCode() == KeyEvent.VK_TAB
+ || e.getKeyCode() == KeyEvent.VK_SPACE
+ || (selectedGroup != null
+ && (e.getKeyChar() == '+'
+ || e.getKeyChar() == '-')))
+ {
+ return false;
+ }
+
+ boolean singleWindowRule
+ = GuiActivator.getUIService().getSingleWindowContainer() == null
+ || contactList.getComponent().isFocusOwner();
+
+ if (!searchField.isFocusOwner()
+ && keyManager.getFocusOwner() != null
+ && singleWindowRule
+ && keyManager.getFocusOwner()
+ .equals(keyManager.getPermanentFocusOwner()))
+ {
+ // Request the focus in the search field if a letter is typed.
+ searchField.requestFocusInWindow();
+
+ // We re-dispatch the event to search field.
+ keyManager.redispatchEvent(searchField, e);
+
+ // We don't want to dispatch further this event.
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java
index 951cc1c..b6a5f75 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java
@@ -26,10 +26,8 @@ import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.FaxDetail;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.GenericDetail;
-import net.java.sip.communicator.service.protocol.ServerStoredDetails.MobilePhoneDetail;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.PagerDetail;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.PhoneNumberDetail;
-import net.java.sip.communicator.service.protocol.ServerStoredDetails.WorkPhoneDetail;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.skin.*;
import net.java.sip.communicator.util.swing.*;
@@ -203,7 +201,7 @@ public class ContactListTreeCellRenderer
/**
* The parent tree.
*/
- private TreeContactList tree;
+ private TreeContactList treeContactList;
/**
* A list of the custom action buttons.
@@ -342,7 +340,7 @@ public class ContactListTreeCellRenderer
boolean selected, boolean expanded, boolean leaf, int row,
boolean hasFocus)
{
- this.tree = (TreeContactList)tree;
+ this.treeContactList = (TreeContactList) tree;
this.row = row;
this.isSelected = selected;
this.treeNode = (TreeNode) value;
@@ -406,11 +404,12 @@ public class ContactListTreeCellRenderer
// contains a status message.
this.initDisplayDetails(contact.getDisplayDetails());
- this.initButtonsPanel(contact);
+ if (this.treeContactList.isContactButtonsVisible())
+ this.initButtonsPanel(contact);
int avatarWidth, avatarHeight;
- if (isSelected)
+ if (isSelected && treeContactList.isContactButtonsVisible())
{
avatarWidth = EXTENDED_AVATAR_WIDTH;
avatarHeight = EXTENDED_AVATAR_HEIGHT;
@@ -574,7 +573,7 @@ public class ContactListTreeCellRenderer
*/
public int getIconWidth()
{
- return tree.getWidth() + 10;
+ return treeContactList.getWidth() + 10;
}
/**
@@ -597,7 +596,7 @@ public class ContactListTreeCellRenderer
preferredSize.height = preferredHeight;
else if (contact instanceof ShowMoreContact)
preferredSize.height = 18;
- else if (isSelected)
+ else if (isSelected && treeContactList.isContactButtonsVisible())
preferredSize.height = 70;
else
preferredSize.height = 30;
@@ -943,7 +942,7 @@ public class ContactListTreeCellRenderer
addLabels(gridX);
}
- this.setBounds(0, 0, tree.getWidth(), getPreferredSize().height);
+ this.setBounds(0, 0, treeContactList.getWidth(), getPreferredSize().height);
}
/**
@@ -1078,12 +1077,21 @@ public class ContactListTreeCellRenderer
*/
private void call(TreeNode treeNode)
{
+ if (!(treeNode instanceof ContactNode))
+ return;
+
+ UIContactImpl contactDescriptor
+ = ((ContactNode) treeNode).getContactDescriptor();
+
List<UIContactDetail> telephonyContacts
- = ((ContactNode) treeNode).getContactDescriptor()
- .getContactDetailsForOperationSet(
+ = contactDescriptor.getContactDetailsForOperationSet(
OperationSetBasicTelephony.class);
- telephonyContacts.addAll(getAdditionalNumbers());
+ if(contactDescriptor.getDescriptor() instanceof MetaContact)
+ {
+ telephonyContacts.addAll(CallManager.getAdditionalNumbers(
+ (MetaContact) contactDescriptor.getDescriptor()));
+ }
ChooseCallAccountPopupMenu chooseAccountDialog = null;
@@ -1122,13 +1130,13 @@ public class ContactListTreeCellRenderer
}
else if (providersCount > 1)
chooseAccountDialog = new ChooseCallAccountPopupMenu(
- tree, detail.getAddress(), providers);
+ treeContactList, detail.getAddress(), providers);
}
}
else if (telephonyContacts.size() > 1)
{
chooseAccountDialog
- = new ChooseCallAccountPopupMenu(tree, telephonyContacts);
+ = new ChooseCallAccountPopupMenu(treeContactList, telephonyContacts);
}
// If the choose dialog is created we're going to show it.
@@ -1137,10 +1145,10 @@ public class ContactListTreeCellRenderer
Point location = new Point(callButton.getX(),
callButton.getY() + callButton.getHeight());
- SwingUtilities.convertPointToScreen(location, tree);
+ SwingUtilities.convertPointToScreen(location, treeContactList);
location.y = location.y
- + tree.getPathBounds(tree.getSelectionPath()).y;
+ + treeContactList.getPathBounds(treeContactList.getSelectionPath()).y;
chooseAccountDialog.showPopupMenu(location.x + 8, location.y - 8);
}
@@ -1152,13 +1160,19 @@ public class ContactListTreeCellRenderer
*/
private void callVideo(TreeNode treeNode)
{
+ UIContactImpl contactDescriptor
+ = ((ContactNode) treeNode).getContactDescriptor();
+
List<UIContactDetail> videoContacts
- = ((ContactNode) treeNode).getContactDescriptor()
- .getContactDetailsForOperationSet(
+ = contactDescriptor.getContactDetailsForOperationSet(
OperationSetVideoTelephony.class);
- if(ConfigurationManager.isRouteVideoAndDesktopUsingPhoneNumberEnabled())
- videoContacts.addAll(getAdditionalNumbers());
+ if(ConfigurationManager.isRouteVideoAndDesktopUsingPhoneNumberEnabled()
+ && contactDescriptor.getDescriptor() instanceof MetaContact)
+ {
+ videoContacts.addAll(CallManager.getAdditionalNumbers(
+ (MetaContact) contactDescriptor.getDescriptor()));
+ }
ChooseCallAccountPopupMenu chooseAccountDialog = null;
@@ -1228,14 +1242,14 @@ public class ContactListTreeCellRenderer
}
else if (providersCount > 1)
chooseAccountDialog = new ChooseCallAccountPopupMenu(
- tree, detail.getAddress(), providers,
+ treeContactList, detail.getAddress(), providers,
OperationSetVideoTelephony.class);
}
}
else if (videoContacts.size() > 1)
{
chooseAccountDialog
- = new ChooseCallAccountPopupMenu(tree, videoContacts,
+ = new ChooseCallAccountPopupMenu(treeContactList, videoContacts,
OperationSetVideoTelephony.class);
}
@@ -1245,10 +1259,10 @@ public class ContactListTreeCellRenderer
Point location = new Point(callVideoButton.getX(),
callVideoButton.getY() + callVideoButton.getHeight());
- SwingUtilities.convertPointToScreen(location, tree);
+ SwingUtilities.convertPointToScreen(location, treeContactList);
location.y = location.y
- + tree.getPathBounds(tree.getSelectionPath()).y;
+ + treeContactList.getPathBounds(treeContactList.getSelectionPath()).y;
chooseAccountDialog.showPopupMenu(location.x + 8, location.y - 8);
}
@@ -1262,13 +1276,19 @@ public class ContactListTreeCellRenderer
*/
private void shareDesktop(TreeNode treeNode)
{
+ UIContactImpl contactDescriptor
+ = ((ContactNode) treeNode).getContactDescriptor();
+
List<UIContactDetail> desktopContacts
- = ((ContactNode) treeNode).getContactDescriptor()
- .getContactDetailsForOperationSet(
+ = contactDescriptor.getContactDetailsForOperationSet(
OperationSetDesktopSharingServer.class);
- if(ConfigurationManager.isRouteVideoAndDesktopUsingPhoneNumberEnabled())
- desktopContacts.addAll(getAdditionalNumbers());
+ if(ConfigurationManager.isRouteVideoAndDesktopUsingPhoneNumberEnabled()
+ && contactDescriptor.getDescriptor() instanceof MetaContact)
+ {
+ desktopContacts.addAll(CallManager.getAdditionalNumbers(
+ (MetaContact) contactDescriptor.getDescriptor()));
+ }
ChooseCallAccountPopupMenu chooseAccountDialog = null;
@@ -1338,14 +1358,14 @@ public class ContactListTreeCellRenderer
}
else if (providersCount > 1)
chooseAccountDialog = new ChooseCallAccountPopupMenu(
- tree, detail.getAddress(), providers,
+ treeContactList, detail.getAddress(), providers,
OperationSetDesktopSharingServer.class);
}
}
else if (desktopContacts.size() > 1)
{
chooseAccountDialog
- = new ChooseCallAccountPopupMenu(tree, desktopContacts,
+ = new ChooseCallAccountPopupMenu(treeContactList, desktopContacts,
OperationSetDesktopSharingServer.class);
}
@@ -1355,112 +1375,16 @@ public class ContactListTreeCellRenderer
Point location = new Point(desktopSharingButton.getX(),
desktopSharingButton.getY() + desktopSharingButton.getHeight());
- SwingUtilities.convertPointToScreen(location, tree);
+ SwingUtilities.convertPointToScreen(location, treeContactList);
location.y = location.y
- + tree.getPathBounds(tree.getSelectionPath()).y;
+ + treeContactList.getPathBounds(treeContactList.getSelectionPath()).y;
chooseAccountDialog.showPopupMenu(location.x + 8, location.y - 8);
}
}
/**
- * Searches for additional phone numbers found in contact information
- * @return additional phone numbers found in contact information;
- */
- private List<UIContactDetail> getAdditionalNumbers()
- {
- List<UIContactDetail> telephonyContacts
- = new ArrayList<UIContactDetail>();
-
- // Adds additional phone numbers found in contact information
- ContactNode n = (ContactNode)treeNode;
- MetaContact metaContact = null;
-
- if(n.getContactDescriptor().getDescriptor() instanceof MetaContact)
- {
- metaContact = (MetaContact)n.getContactDescriptor().getDescriptor();
- Iterator<Contact> contacts = metaContact.getContacts();
-
- while(contacts.hasNext())
- {
- Contact contact = contacts.next();
- OperationSetServerStoredContactInfo infoOpSet =
- contact.getProtocolProvider().getOperationSet(
- OperationSetServerStoredContactInfo.class);
- Iterator<GenericDetail> details;
- ArrayList<String> phones = new ArrayList<String>();
-
- if(infoOpSet != null)
- {
- details = infoOpSet.getAllDetailsForContact(contact);
-
- while(details.hasNext())
- {
- GenericDetail d = details.next();
- if(d instanceof PhoneNumberDetail &&
- !(d instanceof PagerDetail) &&
- !(d instanceof FaxDetail))
- {
- PhoneNumberDetail pnd = (PhoneNumberDetail)d;
- if(pnd.getNumber() != null &&
- pnd.getNumber().length() > 0)
- {
- String localizedType = null;
-
- if(d instanceof WorkPhoneDetail)
- {
- localizedType =
- GuiActivator.getResources().
- getI18NString(
- "service.gui.WORK_PHONE");
- }
- else if(d instanceof MobilePhoneDetail)
- {
- localizedType =
- GuiActivator.getResources().
- getI18NString(
- "service.gui.MOBILE_PHONE");
- }
- else
- {
- localizedType =
- GuiActivator.getResources().
- getI18NString(
- "service.gui.PHONE");
- }
-
- phones.add(pnd.getNumber());
-
- UIContactDetail cd =
- new UIContactDetailImpl(
- pnd.getNumber(),
- pnd.getNumber() +
- " (" + localizedType + ")",
- null,
- new ArrayList<String>(),
- null,
- null,
- null,
- pnd)
- {
- public PresenceStatus getPresenceStatus()
- {
- return null;
- }
- };
- telephonyContacts.add(cd);
- }
- }
- }
- }
- }
- }
-
- return telephonyContacts;
- }
-
- /**
* Shares the user desktop with the contact contained in the given
* <tt>treeNode</tt>.
*
@@ -1506,15 +1430,15 @@ public class ContactListTreeCellRenderer
popupMenu.insert(new Separator(), 1);
popupMenu.setFocusable(true);
- popupMenu.setInvoker(tree);
+ popupMenu.setInvoker(treeContactList);
Point location = new Point(addContactButton.getX(),
addContactButton.getY() + addContactButton.getHeight());
- SwingUtilities.convertPointToScreen(location, tree);
+ SwingUtilities.convertPointToScreen(location, treeContactList);
location.y = location.y
- + tree.getPathBounds(tree.getSelectionPath()).y;
+ + treeContactList.getPathBounds(treeContactList.getSelectionPath()).y;
popupMenu.setLocation(location.x + 8, location.y - 8);
popupMenu.setVisible(true);
@@ -1694,7 +1618,7 @@ public class ContactListTreeCellRenderer
{
callButton.setEnabled(true);
- tree.refreshContact(uiContact);
+ treeContactList.refreshContact(uiContact);
}
});
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/GenericUIContactImpl.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/GenericUIContactImpl.java
new file mode 100644
index 0000000..74ea61a
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/GenericUIContactImpl.java
@@ -0,0 +1,417 @@
+/*
+ * 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.impl.gui.main.contactlist;
+
+import java.awt.*;
+import java.util.*;
+import java.util.List;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.*;
+
+import net.java.sip.communicator.util.*;
+import net.java.sip.communicator.util.swing.*;
+
+/**
+ * A generic full implementation of the <tt>UIContact</tt> interface.
+ *
+ * @author Yana Stamcheva
+ */
+public class GenericUIContactImpl
+ extends UIContactImpl
+{
+ /**
+ * The descriptor of the contact.
+ */
+ private final Object descriptor;
+
+ /**
+ * The parent group.
+ */
+ private UIGroup parentGroup;
+
+ /**
+ * The display name of this contact.
+ */
+ private final String displayName;
+
+ /**
+ * The display details of this contact.
+ */
+ private String displayDetails;
+
+ /**
+ * The index of the contact in its original source.
+ */
+ private int sourceIndex;
+
+ /**
+ * The list of string that correspond to this contact matches.
+ */
+ private List<String> searchStrings;
+
+ /**
+ * A map of this contact details.
+ */
+ private Map<Class<? extends OperationSet>, List<UIContactDetail>>
+ contactDetails;
+
+ private Collection<SIPCommButton> customActionButtons;
+
+ /**
+ * The corresponding <tt>ContactNode</tt> in the contact list component.
+ */
+ private ContactNode contactNode;
+
+ /**
+ * The status icon of this contact.
+ */
+ private ImageIcon statusIcon;
+
+ /**
+ * The avatar icon of this contact.
+ */
+ private ImageIcon avatarIcon;
+
+ /**
+ * Creates an instance of <tt>GenericUIContactImpl</tt>.
+ *
+ * @param descriptor the descriptor of the contact
+ * @param parentGroup the parent group
+ * @param displayName the display name of the contact
+ */
+ public GenericUIContactImpl(Object descriptor,
+ UIGroup parentGroup,
+ String displayName)
+ {
+ this.descriptor = descriptor;
+ this.parentGroup = parentGroup;
+ this.displayName = displayName;
+ }
+
+ /**
+ * Returns the descriptor of this contact.
+ *
+ * @return the descriptor of this contact
+ */
+ @Override
+ public Object getDescriptor()
+ {
+ return descriptor;
+ }
+
+ /**
+ * Returns the display name of this contact.
+ *
+ * @return the display name of this contact
+ */
+ @Override
+ public String getDisplayName()
+ {
+ return displayName;
+ }
+
+ /**
+ * Returns the display details of this contact. These would be shown
+ * whenever the contact is selected.
+ *
+ * @return the display details of this contact
+ */
+ @Override
+ public String getDisplayDetails()
+ {
+ return displayDetails;
+ }
+
+ /**
+ * Sets the display details of this contact. These would be shown
+ * whenever the contact is selected.
+ *
+ * @param the display details of this contact
+ */
+ public void setDisplayDetails(String displayDetails)
+ {
+ this.displayDetails = displayDetails;
+ }
+
+ /**
+ * Returns the index of this contact in its source.
+ *
+ * @return the source index
+ */
+ @Override
+ public int getSourceIndex()
+ {
+ return sourceIndex;
+ }
+
+ /**
+ * Sets the index of this contact.
+ *
+ * @param the source index
+ */
+ public void setSourceIndex(int index)
+ {
+ this.sourceIndex = index;
+ }
+
+ /**
+ * Creates a tool tip for this contact. If such tooltip is
+ * provided it would be shown on mouse over over this <tt>UIContact</tt>.
+ *
+ * @return the tool tip for this contact descriptor
+ */
+ @Override
+ public ExtendedTooltip getToolTip()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the right button menu component.
+ *
+ * @return the right button menu component
+ */
+ @Override
+ public Component getRightButtonMenu()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the parent group.
+ *
+ * @return the parent group
+ */
+ @Override
+ public UIGroup getParentGroup()
+ {
+ return parentGroup;
+ }
+
+ /**
+ * Sets the parent group.
+ *
+ * @param parentGroup the parent group
+ */
+ @Override
+ public void setParentGroup(UIGroup parentGroup)
+ {
+ this.parentGroup = parentGroup;
+ }
+
+ /**
+ * Returns an <tt>Iterator</tt> over a list of the search strings of this
+ * contact.
+ *
+ * @return an <tt>Iterator</tt> over a list of the search strings of this
+ * contact
+ */
+ @Override
+ public Iterator<String> getSearchStrings()
+ {
+ return searchStrings.iterator();
+ }
+
+ /**
+ * Sets the list of the search strings of this contact.
+ *
+ * @param strings the list of search strings of this contact
+ */
+ public void setSearchStrings(List<String> strings)
+ {
+ this.searchStrings = strings;
+ }
+
+ /**
+ * Returns the default <tt>ContactDetail</tt> to use for any operations
+ * depending to the given <tt>OperationSet</tt> class.
+ *
+ * @param opSetClass the <tt>OperationSet</tt> class we're interested in
+ * @return the default <tt>ContactDetail</tt> to use for any operations
+ * depending to the given <tt>OperationSet</tt> class
+ */
+ @Override
+ public UIContactDetail getDefaultContactDetail(
+ Class<? extends OperationSet> opSetClass)
+ {
+ List<UIContactDetail> opSetDetails = contactDetails.get(opSetClass);
+
+ if (opSetDetails != null && opSetDetails.size() > 0)
+ return opSetDetails.get(0);
+
+ return null;
+ }
+
+ /**
+ * Returns a list of all <tt>UIContactDetail</tt>s corresponding to the
+ * given <tt>OperationSet</tt> class.
+ *
+ * @param opSetClass the <tt>OperationSet</tt> class we're looking for
+ * @return a list of all <tt>UIContactDetail</tt>s corresponding to the
+ * given <tt>OperationSet</tt> class
+ */
+ @Override
+ public List<UIContactDetail> getContactDetailsForOperationSet(
+ Class<? extends OperationSet> opSetClass)
+ {
+ return contactDetails.get(opSetClass);
+ }
+
+ /**
+ * Returns a list of all <tt>UIContactDetail</tt>s within this
+ * <tt>UIContact</tt>.
+ *
+ * @return a list of all <tt>UIContactDetail</tt>s within this
+ * <tt>UIContact</tt>
+ */
+ @Override
+ public List<UIContactDetail> getContactDetails()
+ {
+ List<UIContactDetail> details = new ArrayList<UIContactDetail>();
+
+ Iterator<List<UIContactDetail>> listsIter
+ = contactDetails.values().iterator();
+
+ while (listsIter.hasNext())
+ {
+ details.addAll(listsIter.next());
+ }
+
+ return details;
+ }
+
+ /**
+ * Returns all custom action buttons for this notification contact.
+ *
+ * @return a list of all custom action buttons for this notification contact
+ */
+ @Override
+ public Collection<SIPCommButton> getContactCustomActionButtons()
+ {
+ return customActionButtons;
+ }
+
+ /**
+ * Sets all custom action buttons for this notification contact.
+ *
+ * @param buttonsList a list of all custom action buttons for this
+ * notification contact
+ */
+ public void setContactCustomActionButtons(
+ Collection<SIPCommButton> buttonsList)
+ {
+ this.customActionButtons = buttonsList;
+ }
+
+ /**
+ * Adds the given <tt>detailsList</tt> for the given <tt>opSetClass</tt>.
+ *
+ * @param opSetClass the class of the OperationSet
+ * @param detailsList the list of contact details supported for the given
+ * operation set
+ */
+ public void addContactDetails( Class<? extends OperationSet> opSetClass,
+ List<UIContactDetail> detailsList)
+ {
+ if (contactDetails == null)
+ contactDetails = new HashMap< Class<? extends OperationSet>,
+ List<UIContactDetail>>();
+
+ contactDetails.put(opSetClass, detailsList);
+ }
+
+ /**
+ * Sets the contact details map.
+ *
+ * @param contactDetailsMap the map of contact details and corresponding
+ * supported operation set
+ */
+ public void setContactDetails( Map <Class<? extends OperationSet>,
+ List<UIContactDetail>> contactDetailsMap)
+ {
+ contactDetails = contactDetailsMap;
+ }
+
+ /**
+ * Returns the corresponding <tt>ContactNode</tt> from the contact list
+ * component.
+ * @return the corresponding <tt>ContactNode</tt>
+ */
+ public ContactNode getContactNode()
+ {
+ return contactNode;
+ }
+
+ /**
+ * Sets the corresponding <tt>ContactNode</tt>.
+ * @param contactNode the corresponding <tt>ContactNode</tt>
+ */
+ public void setContactNode(ContactNode contactNode)
+ {
+ this.contactNode = contactNode;
+ }
+
+ /**
+ * Returns the general status icon of the given UIContact.
+ *
+ * @return PresenceStatus the most "available" status from all
+ * sub-contact statuses.
+ */
+ @Override
+ public ImageIcon getStatusIcon()
+ {
+ return statusIcon;
+ }
+
+ /**
+ * Sets the general status icon of this contact.
+ *
+ * @return PresenceStatus The most "available" status from all
+ * sub-contact statuses.
+ */
+ public void setStatusIcon(ImageIcon statusIcon)
+ {
+ this.statusIcon = statusIcon;
+ }
+
+ /**
+ * Gets the avatar of a specific <tt>UIContact</tt> in the form of an
+ * <tt>ImageIcon</tt> value.
+ *
+ * @param isSelected indicates if the contact is selected
+ * @param width the desired icon width
+ * @param height the desired icon height
+ * @return an <tt>ImageIcon</tt> which represents the avatar of the
+ * specified <tt>MetaContact</tt>
+ */
+ @Override
+ public ImageIcon getAvatar(boolean isSelected, int width, int height)
+ {
+ if (avatarIcon != null
+ && (avatarIcon.getIconWidth() > width
+ || avatarIcon.getIconHeight() > height))
+ {
+ avatarIcon = ImageUtils.getScaledRoundedIcon(
+ avatarIcon.getImage(), width, height);
+ }
+ return avatarIcon;
+ }
+
+ /**
+ * Sets the avatar of this <tt>UIContact</tt> in the form of an
+ * <tt>ImageIcon</tt> value.
+ *
+ * @param avatarIcon the avatar icon of this contact
+ */
+ public void setAvatar(ImageIcon avatarIcon)
+ {
+ this.avatarIcon = avatarIcon;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/GroupNode.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/GroupNode.java
index 2d053ae..0f01bcd 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/GroupNode.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/GroupNode.java
@@ -241,6 +241,20 @@ public class GroupNode
}
/**
+ * Returns a collection of all direct children of this <tt>GroupNode</tt>.
+ *
+ * @return a collection of all direct children of this <tt>GroupNode</tt>
+ */
+ @SuppressWarnings("unchecked")
+ public Collection<ContactNode> getContacts()
+ {
+ if (children != null)
+ return Collections.unmodifiableCollection(children);
+
+ return null;
+ }
+
+ /**
* Returns the <tt>UIGroup</tt> corresponding to this <tt>GroupNode</tt>.
* @return the <tt>UIGroup</tt> corresponding to this <tt>GroupNode</tt>
*/
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/InviteUIContact.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/InviteUIContact.java
new file mode 100644
index 0000000..909393c
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/InviteUIContact.java
@@ -0,0 +1,154 @@
+/*
+ * 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.impl.gui.main.contactlist;
+
+import java.util.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The <tt>InviteUIContact</tt> is an <tt>UIContact</tt> used in invite dialogs
+ * to represent the selected contacts the invite operation.
+ *
+ * @author Yana Stamcheva
+ */
+public class InviteUIContact
+ extends GenericUIContactImpl
+{
+ /**
+ * The source <tt>UIContact</tt> from which this contact is created. This
+ * contact can be seen as a copy of the source contact.
+ */
+ private final UIContact sourceUIContact;
+
+ /**
+ * The backup protocol provider to be used for contact operations, if no
+ * other protocol provider has been specified.
+ */
+ private final ProtocolProviderService backupProvider;
+
+ /**
+ * Creates an instance of <tt>InviteUIContact</tt>.
+ *
+ * @param uiContact the source <tt>UIContact</tt>.
+ * @param protocolProvider the backup protocol provider to use if no other
+ * protocol provider has been specified in the source ui contact
+ */
+ public InviteUIContact( UIContact uiContact,
+ ProtocolProviderService protocolProvider)
+ {
+ super(uiContact.getDescriptor(), null, uiContact.getDisplayName());
+
+ setDisplayDetails(uiContact.getDisplayDetails());
+
+ sourceUIContact = uiContact;
+ backupProvider = protocolProvider;
+ }
+
+ /**
+ * Returns a list of <tt>UIContactDetail</tt>s supporting the given
+ * <tt>OperationSet</tt> class.
+ * @param opSetClass the <tt>OperationSet</tt> class we're interested in
+ * @return a list of <tt>UIContactDetail</tt>s supporting the given
+ * <tt>OperationSet</tt> class
+ */
+ public List<UIContactDetail> getContactDetailsForOperationSet(
+ Class<? extends OperationSet> opSetClass)
+ {
+ List<UIContactDetail> contactDetails
+ = sourceUIContact.getContactDetailsForOperationSet(opSetClass);
+
+ if (contactDetails == null)
+ return null;
+
+ if (backupProvider == null)
+ return contactDetails;
+
+ Iterator<UIContactDetail> contactDetailsIter
+ = contactDetails.iterator();
+
+ while (contactDetailsIter.hasNext())
+ {
+ UIContactDetail contactDetail = contactDetailsIter.next();
+
+ if (contactDetail
+ .getPreferredProtocolProvider(opSetClass) == null)
+ {
+ contactDetail.addPreferredProtocolProvider( opSetClass,
+ backupProvider);
+ }
+
+ if (contactDetail
+ .getPreferredProtocol(opSetClass) == null)
+ {
+ contactDetail.addPreferredProtocol(
+ opSetClass,
+ backupProvider.getProtocolName());
+ }
+ }
+
+ return contactDetails;
+ }
+
+ /**
+ * Returns a list of all contained <tt>UIContactDetail</tt>s.
+ *
+ * @return a list of all contained <tt>UIContactDetail</tt>s
+ */
+ public List<UIContactDetail> getContactDetails()
+ {
+ return sourceUIContact.getContactDetails();
+ }
+
+ /**
+ * Returns the default <tt>ContactDetail</tt> to use for any operations
+ * depending to the given <tt>OperationSet</tt> class.
+ *
+ * @param opSetClass the <tt>OperationSet</tt> class we're interested in
+ * @return the default <tt>ContactDetail</tt> to use for any operations
+ * depending to the given <tt>OperationSet</tt> class
+ */
+ public UIContactDetail getDefaultContactDetail(
+ Class<? extends OperationSet> opSetClass)
+ {
+ return sourceUIContact.getDefaultContactDetail(opSetClass);
+ }
+
+ /**
+ * Returns the avatar of this <tt>UIContact</tt>.
+ *
+ * @param isSelected indicates if the avatar is selected
+ * @param width avatar preferred width
+ * @param height avatar preferred height
+ */
+ @Override
+ public ImageIcon getAvatar(boolean isSelected, int width, int height)
+ {
+ if (sourceUIContact instanceof UIContactImpl)
+ return ((UIContactImpl) sourceUIContact)
+ .getAvatar(isSelected, width, height);
+
+ return null;
+ }
+
+ /**
+ * Returns the status icon of this contact.
+ *
+ * @return an <tt>ImageIcon</tt> representing the status of this contact
+ */
+ @Override
+ public ImageIcon getStatusIcon()
+ {
+ if (sourceUIContact instanceof UIContactImpl)
+ return ((UIContactImpl) sourceUIContact).getStatusIcon();
+
+ return null;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/PresenceFilter.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/PresenceFilter.java
index 3bf255e..133f82b 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/PresenceFilter.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/PresenceFilter.java
@@ -13,6 +13,7 @@ import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.contactlist.*;
import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.gui.event.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.*;
@@ -49,6 +50,7 @@ public class PresenceFilter
/**
* Applies this filter. This filter is applied over the
* <tt>MetaContactListService</tt>.
+ *
* @param filterQuery the query which keeps track of the filtering results
*/
public void applyFilter(FilterQuery filterQuery)
@@ -76,6 +78,7 @@ public class PresenceFilter
/**
* Indicates if the given <tt>uiContact</tt> is matching this filter.
+ *
* @param uiContact the <tt>UIContact</tt> to check
* @return <tt>true</tt> if the given <tt>uiContact</tt> is matching
* this filter, otherwise returns <tt>false</tt>
@@ -91,6 +94,7 @@ public class PresenceFilter
/**
* Indicates if the given <tt>uiGroup</tt> is matching this filter.
+ *
* @param uiGroup the <tt>UIGroup</tt> to check
* @return <tt>true</tt> if the given <tt>uiGroup</tt> is matching
* this filter, otherwise returns <tt>false</tt>
@@ -106,6 +110,7 @@ public class PresenceFilter
/**
* Sets the show offline property.
+ *
* @param isShowOffline indicates if offline contacts are shown
*/
public void setShowOffline(boolean isShowOffline)
@@ -118,6 +123,7 @@ public class PresenceFilter
/**
* Returns <tt>true</tt> if offline contacts are shown, otherwise returns
* <tt>false</tt>.
+ *
* @return <tt>true</tt> if offline contacts are shown, otherwise returns
* <tt>false</tt>
*/
@@ -129,6 +135,7 @@ public class PresenceFilter
/**
* Returns <tt>true</tt> if offline contacts are shown or if the given
* <tt>MetaContact</tt> is online, otherwise returns false.
+ *
* @param metaContact the <tt>MetaContact</tt> to check
* @return <tt>true</tt> if the given <tt>MetaContact</tt> is matching this
* filter
@@ -141,6 +148,7 @@ public class PresenceFilter
/**
* Returns <tt>true</tt> if offline contacts are shown or if the given
* <tt>MetaContactGroup</tt> contains online contacts.
+ *
* @param metaGroup the <tt>MetaContactGroup</tt> to check
* @return <tt>true</tt> if the given <tt>MetaContactGroup</tt> is matching
* this filter
@@ -176,6 +184,7 @@ public class PresenceFilter
/**
* Adds all contacts contained in the given <tt>MetaContactGroup</tt>
* matching the current filter and not contained in the contact list.
+ *
* @param metaGroup the <tt>MetaContactGroup</tt>, which matching contacts
* to add
* @param query the <tt>MetaContactQuery</tt> that notifies interested
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchField.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchField.java
index c97ad48..9e08ec7 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchField.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchField.java
@@ -53,15 +53,30 @@ public class SearchField
private final MainFrame mainFrame;
/**
+ * The contact list on which we apply the filter.
+ */
+ private ContactList contactList;
+
+ /**
+ * The filter to apply on search.
+ */
+ private final ContactListSearchFilter searchFilter;
+
+ /**
* Creates the <tt>SearchField</tt>.
+ *
* @param frame the main application window
+ * @param contactList the contact list, which we're searching
+ * @param searchFilter the filter to apply on search
*/
- public SearchField(MainFrame frame)
+ public SearchField( MainFrame frame,
+ ContactListSearchFilter searchFilter)
{
super(GuiActivator.getResources()
.getI18NString("service.gui.ENTER_NAME_OR_NUMBER"));
this.mainFrame = frame;
+ this.searchFilter = searchFilter;
if(getUI() instanceof SearchFieldUI)
((SearchFieldUI)getUI()).setDeleteButtonEnabled(true);
@@ -82,7 +97,8 @@ public class SearchField
{
setText("");
- SearchField.this.mainFrame.requestFocusInCenterPanel();
+ if (SearchField.this.mainFrame != null)
+ SearchField.this.mainFrame.requestFocusInCenterPanel();
}
});
@@ -128,17 +144,15 @@ public class SearchField
boolean isDefaultFilter = false;
+ searchFilter.setFilterString(filterString.trim());
+
if (filterString != null && filterString.length() > 0)
{
- TreeContactList.searchFilter
- .setFilterString(filterString.trim());
-
- filterQuery = GuiActivator.getContactList()
- .applyFilter(TreeContactList.searchFilter);
+ filterQuery = contactList.applyFilter(searchFilter);
}
else
{
- filterQuery = GuiActivator.getContactList().applyDefaultFilter();
+ filterQuery = contactList.applyDefaultFilter();
isDefaultFilter = true;
}
@@ -156,13 +170,16 @@ public class SearchField
filterQuery.setQueryListener(this);
}
else
+ {
// If the query is null or is canceled, we would simply check the
// contact list content.
- enableUnknownContactView(GuiActivator.getContactList().isEmpty());
+ closeFilterQuery(filterQuery, !contactList.isEmpty());
+ }
}
/**
* Sets the unknown contact view to the main contact list window.
+ *
* @param isEnabled indicates if the unknown contact view should be enabled
* or disabled.
*/
@@ -172,14 +189,26 @@ public class SearchField
{
public void run()
{
- mainFrame.enableUnknownContactView(isEnabled);
+ if (mainFrame != null)
+ mainFrame.enableUnknownContactView(isEnabled);
}
});
}
/**
+ * Sets the contact list, in which the search is performed.
+ *
+ * @param contactList the contact list in which the search is performed
+ */
+ public void setContactList(ContactList contactList)
+ {
+ this.contactList = contactList;
+ }
+
+ /**
* Indicates that the given <tt>query</tt> has finished with failure, i.e.
* no results for the filter were found.
+ *
* @param query the <tt>FilterQuery</tt>, where this listener is registered
*/
public void filterQueryFailed(FilterQuery query)
@@ -194,17 +223,12 @@ public class SearchField
/**
* Indicates that the given <tt>query</tt> has finished with success, i.e.
* the filter has returned results.
+ *
* @param query the <tt>FilterQuery</tt>, where this listener is registered
*/
public void filterQuerySucceeded(FilterQuery query)
{
- // If the unknown contact view was previously enabled, but we
- // have found matching contacts we enter the normal view.
- enableUnknownContactView(false);
-
- GuiActivator.getContactList().selectFirstContact();
-
- query.setQueryListener(null);
+ closeFilterQuery(query, !contactList.isEmpty());
}
/**
@@ -227,4 +251,16 @@ public class SearchField
{
return uiClassID;
}
+
+ private void closeFilterQuery(FilterQuery query, boolean hasResults)
+ {
+ // If the unknown contact view was previously enabled, but we
+ // have found matching contacts we enter the normal view.
+ enableUnknownContactView(!hasResults);
+
+ if (hasResults)
+ contactList.selectFirstContact();
+
+ query.setQueryListener(null);
+ }
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFilter.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFilter.java
index 202ae0c..2287618 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFilter.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/SearchFilter.java
@@ -13,6 +13,7 @@ import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
import net.java.sip.communicator.service.contactsource.*;
import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.gui.event.*;
/**
* The <tt>SearchFilter</tt> is a <tt>ContactListFilter</tt> that filters the
@@ -21,27 +22,17 @@ import net.java.sip.communicator.service.gui.*;
* @author Yana Stamcheva
*/
public class SearchFilter
- implements ContactListFilter
+ implements ContactListSearchFilter
{
/**
- * The default contact source search type.
- */
- public static final int DEFAULT_SOURCE = 0;
-
- /**
- * The history contact source search type.
- */
- public static final int HISTORY_SOURCE = 1;
-
- /**
* The string, which we're searching.
*/
- private String filterString;
+ protected String filterString;
/**
* The pattern to filter.
*/
- private Pattern filterPattern;
+ protected Pattern filterPattern;
/**
* The <tt>MetaContactListSource</tt> to search in.
@@ -49,22 +40,25 @@ public class SearchFilter
private final MetaContactListSource mclSource;
/**
- * The list of external contact sources to search in.
+ * The source contact list.
*/
- private Collection<UIContactSource> contactSources;
+ protected ContactList sourceContactList;
/**
- * The type of the search source. One of the above defined DEFAUT_SOURCE or
- * HISTORY_SOURCE.
+ * Creates an instance of <tt>SearchFilter</tt>.
*/
- private int searchSourceType = DEFAULT_SOURCE;
+ public SearchFilter(MetaContactListSource contactListSource)
+ {
+ this.mclSource = contactListSource;
+ }
/**
* Creates an instance of <tt>SearchFilter</tt>.
*/
- public SearchFilter(MetaContactListSource contactListSource)
+ public SearchFilter(ContactList sourceContactList)
{
- this.mclSource = contactListSource;
+ this.mclSource = null;
+ this.sourceContactList = sourceContactList;
}
/**
@@ -73,25 +67,34 @@ public class SearchFilter
*/
public void applyFilter(FilterQuery filterQuery)
{
- // If the filter has a default contact source, we apply it first.
- if (searchSourceType == DEFAULT_SOURCE)
+ if (sourceContactList == null)
+ sourceContactList = GuiActivator.getContactList();
+
+ Iterator<UIContactSource> filterSources
+ = sourceContactList.getContactSources().iterator();
+
+ if (sourceContactList.getDefaultFilter()
+ .equals(TreeContactList.presenceFilter))
{
MetaContactQuery defaultQuery
= mclSource.queryMetaContactSource(filterPattern);
- defaultQuery.addContactQueryListener(GuiActivator.getContactList());
+ defaultQuery.addContactQueryListener(sourceContactList);
// First add the MetaContactListSource
filterQuery.addContactQuery(defaultQuery);
}
+ else if (sourceContactList.getDefaultFilter()
+ .equals(TreeContactList.historyFilter))
+ {
+ filterSources = sourceContactList.getContactSources(
+ ContactSourceService.HISTORY_TYPE).iterator();
+ }
// If we have stopped filtering in the mean time we return here.
if (filterQuery.isCanceled())
return;
- Iterator<UIContactSource> filterSources
- = getContactSources().iterator();
-
// Then we apply the filter on all its contact sources.
while (filterSources.hasNext())
{
@@ -102,12 +105,17 @@ public class SearchFilter
if (filterQuery.isCanceled())
return;
- filterQuery.addContactQuery(
- applyFilter(filterSource));
+ ContactQuery query = applyFilter(filterSource);
+
+ if (query.getStatus() == ContactQuery.QUERY_IN_PROGRESS)
+ filterQuery.addContactQuery(query);
}
// Closes this filter to indicate that we finished adding queries to it.
- filterQuery.close();
+ if (filterQuery.isRunning())
+ filterQuery.close();
+ else if (!sourceContactList.isEmpty())
+ sourceContactList.selectFirstContact();
}
/**
@@ -133,7 +141,7 @@ public class SearchFilter
// Add first available results.
this.addMatching(contactQuery.getQueryResults());
- contactQuery.addContactQueryListener(GuiActivator.getContactList());
+ contactQuery.addContactQueryListener(sourceContactList);
return contactQuery;
}
@@ -215,7 +223,10 @@ public class SearchFilter
*/
private boolean isMatching(String text)
{
- return filterPattern.matcher(text).find();
+ if (filterPattern != null)
+ return filterPattern.matcher(text).find();
+
+ return true;
}
/**
@@ -240,7 +251,7 @@ public class SearchFilter
= sourceContact.getContactSource();
UIContactSource sourceUI
- = GuiActivator.getContactList().getContactSource(contactSource);
+ = sourceContactList.getContactSource(contactSource);
if (sourceUI != null
// ExtendedContactSourceService has already matched the
@@ -248,7 +259,7 @@ public class SearchFilter
&& (contactSource instanceof ExtendedContactSourceService)
|| isMatching(sourceContact))
{
- GuiActivator.getContactList().addContact(
+ sourceContactList.addContact(
sourceUI.createUIContact(sourceContact),
sourceUI.getUIGroup(),
false,
@@ -257,56 +268,4 @@ public class SearchFilter
else
sourceUI.removeUIContact(sourceContact);
}
-
- /**
- * Sets the search source type: DEFAULT_SOURCE or HISTORY_SOURCE.
- * @param searchSourceType the type of the search source to set
- */
- public void setSearchSourceType(int searchSourceType)
- {
- this.searchSourceType = searchSourceType;
-
- switch(searchSourceType)
- {
- case DEFAULT_SOURCE:
- contactSources
- = GuiActivator.getContactList().getContactSources();
- break;
- case HISTORY_SOURCE:
- {
- Collection<UIContactSource> historySources
- = new LinkedList<UIContactSource>();
- UIContactSource historySource
- = GuiActivator.getContactList().getContactSource(
- ContactSourceService.CALL_HISTORY);
-
- historySources.add(historySource);
- contactSources = historySources;
- break;
- }
- }
- }
-
- /**
- * Returns the list of <tt>ExternalContactSource</tt> this filter searches
- * in.
- * @return the list of <tt>ExternalContactSource</tt> this filter searches
- * in
- */
- public Collection<UIContactSource> getContactSources()
- {
- if (contactSources == null)
- contactSources = GuiActivator.getContactList().getContactSources();
- return contactSources;
- }
-
- /**
- * Indicates if this filter contains a default source.
- * @return <tt>true</tt> if this filter contains a default source,
- * <tt>false</tt> otherwise
- */
- public boolean hasDefaultSource()
- {
- return (searchSourceType == DEFAULT_SOURCE);
- }
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java
index 545955c..f703aaa 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java
@@ -124,7 +124,7 @@ public class TreeContactList
*/
private MouseListener[] originalMouseListeners;
- private final Collection<UIContactSource>
+ private final LinkedList<UIContactSource>
contactSources = new LinkedList<UIContactSource>();
private static NotificationContactSource notificationSource;
@@ -139,6 +139,11 @@ public class TreeContactList
private static boolean imageSearchCanceled = false;
/**
+ * Indicates if the contact buttons should be disabled.
+ */
+ private boolean isContactButtonsVisible = true;
+
+ /**
* Creates the <tt>TreeContactList</tt>.
*/
public TreeContactList()
@@ -319,7 +324,7 @@ public class TreeContactList
}
if (uiGroup != null)
- GuiActivator.getContactList().addGroup(uiGroup, true);
+ this.addGroup(uiGroup, true);
}
/**
@@ -737,6 +742,45 @@ public class TreeContactList
}
/**
+ * Returns a collection of all direct child <tt>UIContact</tt>s of the given
+ * <tt>UIGroup</tt>.
+ *
+ * @param group the parent <tt>UIGroup</tt>
+ * @return a collection of all direct child <tt>UIContact</tt>s of the given
+ * <tt>UIGroup</tt>
+ */
+ public Collection<UIContact> getContacts(final UIGroup group)
+ {
+ if (group != null && !(group instanceof UIGroupImpl))
+ return null;
+
+ GroupNode groupNode;
+
+ if (group == null)
+ groupNode = treeModel.getRoot();
+ else
+ groupNode = ((UIGroupImpl) group).getGroupNode();
+
+ if (groupNode == null)
+ return null;
+
+ Collection<ContactNode> contactNodes = groupNode.getContacts();
+
+ if (contactNodes == null)
+ return null;
+
+ Collection<UIContact> childContacts = new ArrayList<UIContact>();
+
+ Iterator<ContactNode> contactNodesIter = contactNodes.iterator();
+ while (contactNodesIter.hasNext())
+ {
+ childContacts.add(contactNodesIter.next().getContactDescriptor());
+ }
+
+ return childContacts;
+ }
+
+ /**
* Adds a listener for <tt>ContactListEvent</tt>s.
*
* @param listener the listener to add
@@ -822,7 +866,7 @@ public class TreeContactList
if (currentFilterQuery != null && !currentFilterQuery.isCanceled())
currentFilterQuery.cancel();
- currentFilterQuery = new UIFilterQuery();
+ currentFilterQuery = new UIFilterQuery(this);
if (filterThread == null)
{
@@ -911,13 +955,16 @@ public class TreeContactList
public void setDefaultFilter(ContactListFilter filter)
{
this.defaultFilter = filter;
+ }
- if (defaultFilter.equals(presenceFilter))
- TreeContactList.searchFilter
- .setSearchSourceType(SearchFilter.DEFAULT_SOURCE);
- else if (defaultFilter.equals(historyFilter))
- TreeContactList.searchFilter
- .setSearchSourceType(SearchFilter.HISTORY_SOURCE);
+ /**
+ * Gets the default filter for this contact list.
+ *
+ * @return the default filter for this contact list
+ */
+ public ContactListFilter getDefaultFilter()
+ {
+ return defaultFilter;
}
/**
@@ -930,6 +977,15 @@ public class TreeContactList
}
/**
+ * Returns the currently applied filter.
+ * @return the currently applied filter
+ */
+ public FilterQuery getCurrentFilterQuery()
+ {
+ return currentFilterQuery;
+ }
+
+ /**
* Indicates if this contact list is empty.
* @return <tt>true</tt> if this contact list contains no children,
* otherwise returns <tt>false</tt>
@@ -1508,7 +1564,14 @@ public class TreeContactList
for (ContactSourceService contactSource
: GuiActivator.getContactSources())
{
- contactSources.add(new ExternalContactSource(contactSource, this));
+ ExternalContactSource extContactSource
+ = new ExternalContactSource(contactSource, this);
+
+ int sourceIndex = contactSource.getIndex();
+ if (sourceIndex >= 0 && contactSources.size() >= sourceIndex)
+ contactSources.add(sourceIndex, extContactSource);
+ else
+ contactSources.add(extContactSource);
}
GuiActivator.bundleContext.addServiceListener(
new ContactSourceServiceListener());
@@ -1524,6 +1587,47 @@ public class TreeContactList
}
/**
+ * Adds the given contact source to the list of available contact sources.
+ *
+ * @param contactSource the <tt>ContactSourceService</tt>
+ */
+ public void addContactSource(ContactSourceService contactSource)
+ {
+ contactSources.add(new ExternalContactSource(contactSource, this));
+ }
+
+ /**
+ * Removes the given contact source from the list of available contact
+ * sources.
+ *
+ * @param contactSource
+ */
+ public void removeContactSource(ContactSourceService contactSource)
+ {
+ Iterator<UIContactSource> extSourcesIter
+ = contactSources.iterator();
+
+ while (extSourcesIter.hasNext())
+ {
+ UIContactSource extSource = extSourcesIter.next();
+
+ if (extSource.getContactSourceService().equals(contactSource))
+ {
+ contactSources.remove(extSource);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Removes all stored contact sources.
+ */
+ public void removeAllContactSources()
+ {
+ contactSources.clear();
+ }
+
+ /**
* Returns the notification contact source.
*
* @return the notification contact source
@@ -1559,12 +1663,15 @@ public class TreeContactList
}
/**
- * Returns the contact source with the given identifier.
- * @param identifier the identifier we're looking for
- * @return the contact source with the given identifier
+ * Returns all <tt>UIContactSource</tt>s of the given type.
+ *
+ * @param type the type of sources we're looking for
+ * @return a list of all <tt>UIContactSource</tt>s of the given type
*/
- public UIContactSource getContactSource(String identifier)
+ public List<UIContactSource> getContactSources(int type)
{
+ List<UIContactSource> sources = new ArrayList<UIContactSource>();
+
Iterator<UIContactSource> extSourcesIter
= contactSources.iterator();
@@ -1572,11 +1679,10 @@ public class TreeContactList
{
UIContactSource extSource = extSourcesIter.next();
- if (extSource.getContactSourceService().getIdentifier()
- .equals(identifier))
- return extSource;
+ if (extSource.getContactSourceService().getType() == type)
+ sources.add(extSource);
}
- return null;
+ return sources;
}
/**
@@ -2038,6 +2144,33 @@ public class TreeContactList
}
/**
+ * Returns the list of selected contacts.
+ *
+ * @return the list of selected contacts
+ */
+ public List<UIContact> getSelectedContacts()
+ {
+ TreePath[] selectionPaths = getSelectionPaths();
+
+ if (selectionPaths == null)
+ return null;
+
+ List<UIContact> selectedContacts = new ArrayList<UIContact>();
+
+ for (TreePath selectionPath : selectionPaths)
+ {
+ if (selectionPath.getLastPathComponent() instanceof ContactNode)
+ {
+ selectedContacts.add(
+ ((ContactNode) selectionPath.getLastPathComponent())
+ .getContactDescriptor());
+ }
+ }
+
+ return selectedContacts;
+ }
+
+ /**
* Returns the currently selected <tt>UIGroup</tt> if there's one.
*
* @return the currently selected <tt>UIGroup</tt> if there's one.
@@ -2057,6 +2190,33 @@ public class TreeContactList
}
/**
+ * Enables/disables multiple selection.
+ *
+ * @param isEnabled <tt>true</tt> to enable multiple selection,
+ * <tt>false</tt> - otherwise
+ */
+ public void setMultipleSelectionEnabled(boolean isEnabled)
+ {
+ if (isEnabled)
+ getSelectionModel().setSelectionMode(
+ TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
+ else
+ getSelectionModel().setSelectionMode(
+ TreeSelectionModel.SINGLE_TREE_SELECTION);
+ }
+
+ /**
+ * Removes the current selection.
+ */
+ public void removeSelection()
+ {
+ TreePath[] selectionPaths = getSelectionPaths();
+
+ if (selectionPaths != null)
+ removeSelectionPaths(selectionPaths);
+ }
+
+ /**
* Indicates that a selection has occurred on the tree.
*
* @param e the <tt>TreeSelectionEvent</tt> that notified us of the change
@@ -2080,4 +2240,26 @@ public class TreeContactList
}
}
}
+
+ /**
+ * Shows/hides buttons shown in contact row.
+ *
+ * @param isVisible <tt>true</tt> to show contact buttons, <tt>false</tt> -
+ * otherwise.
+ */
+ public void setContactButtonsVisible(boolean isVisible)
+ {
+ this.isContactButtonsVisible = isVisible;
+ }
+
+ /**
+ * Shows/hides buttons shown in contact row.
+ *
+ * return <tt>true</tt> to indicate that contact buttons are shown,
+ * <tt>false</tt> - otherwise.
+ */
+ public boolean isContactButtonsVisible()
+ {
+ return isContactButtonsVisible;
+ }
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactDetailImpl.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactDetailImpl.java
index 71b3634..6f07d37 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactDetailImpl.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactDetailImpl.java
@@ -29,6 +29,32 @@ public class UIContactDetailImpl
/**
* Creates a <tt>UIContactDetailImpl</tt> by specifying the contact
* <tt>address</tt>, the <tt>displayName</tt> and <tt>preferredProvider</tt>.
+ *
+ * @param address the contact address
+ * @param displayName the contact display name
+ * @param statusIcon the status icon of this contact detail
+ * @param descriptor the underlying object that this class is wrapping
+ */
+ public UIContactDetailImpl(
+ String address,
+ String displayName,
+ ImageIcon statusIcon,
+ Object descriptor)
+ {
+ super( address,
+ displayName,
+ null,
+ null,
+ null,
+ null,
+ descriptor);
+
+ setStatusIcon(statusIcon);
+ }
+
+ /**
+ * Creates a <tt>UIContactDetailImpl</tt> by specifying the contact
+ * <tt>address</tt>, the <tt>displayName</tt> and <tt>preferredProvider</tt>.
* @param address the contact address
* @param displayName the contact display name
* @param category the category of the underlying contact detail
@@ -45,12 +71,13 @@ public class UIContactDetailImpl
String category,
Collection<String> labels,
ImageIcon statusIcon,
- ProtocolProviderService preferredProvider,
- String preferredProtocol,
+ Map<Class<? extends OperationSet>, ProtocolProviderService>
+ preferredProviders,
+ Map<Class<? extends OperationSet>, String> preferredProtocols,
Object descriptor)
{
- super(address, displayName, category, labels, preferredProvider,
- preferredProtocol, descriptor);
+ super(address, displayName, category, labels, preferredProviders,
+ preferredProtocols, descriptor);
setStatusIcon(statusIcon);
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactImpl.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactImpl.java
index bd15e4b..1e348d4 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactImpl.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactImpl.java
@@ -31,18 +31,15 @@ public abstract class UIContactImpl
public abstract void setContactNode(ContactNode contactNode);
/**
- * Returns the general status icon of the given MetaContact. Detects the
- * status using the priority status table. The priority is defined on
- * the "availability" factor and here the most "available" status is
- * returned.
+ * Returns the general status icon of the given UIContact.
*
- * @return PresenceStatus The most "available" status from all
+ * @return PresenceStatus the most "available" status from all
* sub-contact statuses.
*/
public abstract ImageIcon getStatusIcon();
/**
- * Gets the avatar of a specific <tt>MetaContact</tt> in the form of an
+ * Gets the avatar of a specific <tt>UIContact</tt> in the form of an
* <tt>ImageIcon</tt> value.
*
* @param isSelected indicates if the contact is selected
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/UIFilterQuery.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/UIFilterQuery.java
index 441737d..d4072f4 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/UIFilterQuery.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/UIFilterQuery.java
@@ -8,7 +8,6 @@ package net.java.sip.communicator.impl.gui.main.contactlist;
import java.util.*;
-import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
import net.java.sip.communicator.service.contactsource.*;
import net.java.sip.communicator.service.gui.*;
@@ -25,11 +24,6 @@ public class UIFilterQuery
MetaContactQueryListener
{
/**
- * The maximum result count for each contact source.
- */
- public static final int MAX_EXTERNAL_RESULT_COUNT = 10;
-
- /**
* A listener, which is notified when this query finishes.
*/
private FilterQueryListener filterQueryListener;
@@ -46,6 +40,11 @@ public class UIFilterQuery
private boolean isCanceled = false;
/**
+ * Indicates if this query is currently running.
+ */
+ private boolean isRunning = false;
+
+ /**
* Indicates if this query is closed, means no more queries could be added
* to it. A <tt>FilterQuery</tt>, which is closed knows that it has to wait
* for a final number of queries to finish before notifying interested
@@ -66,6 +65,23 @@ public class UIFilterQuery
private int runningQueries = 0;
/**
+ * The parent contact list of this query.
+ */
+ private final ContactList contactList;
+
+ /**
+ * Creates an instance of <tt>UIFilterQuery</tt> by specifying the parent
+ * <tt>ContactList</tt>.
+ *
+ * @param contactList the <tt>ContactList</tt> on which the query is
+ * performed
+ */
+ public UIFilterQuery(ContactList contactList)
+ {
+ this.contactList = contactList;
+ }
+
+ /**
* Adds the given <tt>contactQuery</tt> to the list of filterQueries.
* @param contactQuery the <tt>ContactQuery</tt> to add
*/
@@ -99,6 +115,7 @@ public class UIFilterQuery
else if (contactQuery instanceof MetaContactQuery)
((MetaContactQuery) contactQuery).addContactQueryListener(this);
+ isRunning = true;
filterQueries.put(contactQuery, queryResults);
runningQueries++;
}
@@ -136,6 +153,19 @@ public class UIFilterQuery
}
/**
+ * Indicates if this query is canceled.
+ *
+ * @return <tt>true</tt> if this query is canceled, <tt>false</tt> otherwise
+ */
+ public boolean isRunning()
+ {
+ synchronized (filterQueries)
+ {
+ return isRunning;
+ }
+ }
+
+ /**
* Cancels this filter query.
*/
public void cancel()
@@ -178,6 +208,8 @@ public class UIFilterQuery
*/
private void fireFilterQueryEvent()
{
+ isRunning = false;
+
if (filterQueryListener == null)
return;
@@ -264,8 +296,7 @@ public class UIFilterQuery
{
ContactQuery contactQuery = (ContactQuery) query;
contactQuery.cancel();
- contactQuery.removeContactQueryListener(
- GuiActivator.getContactList());
+ contactQuery.removeContactQueryListener(contactList);
if (!isSucceeded && contactQuery.getQueryResults().size() > 0)
isSucceeded = true;
}
@@ -273,8 +304,7 @@ public class UIFilterQuery
{
MetaContactQuery metaContactQuery = (MetaContactQuery) query;
metaContactQuery.cancel();
- metaContactQuery.removeContactQueryListener(
- GuiActivator.getContactList());
+ metaContactQuery.removeContactQueryListener(contactList);
if (!isSucceeded && metaContactQuery.getResultCount() > 0)
isSucceeded = true;
}
@@ -306,20 +336,20 @@ public class UIFilterQuery
queryResults.add(contact);
- if (queryResults.size() == MAX_EXTERNAL_RESULT_COUNT)
+ if (getMaxResultShown() > -1
+ && queryResults.size() == getMaxResultShown())
{
- query.removeContactQueryListener(GuiActivator.getContactList());
+ query.removeContactQueryListener(contactList);
ShowMoreContact moreInfoContact
- = new ShowMoreContact(query, queryResults);
+ = new ShowMoreContact(query, queryResults, getMaxResultShown());
ContactSourceService contactSource = query.getContactSource();
- GuiActivator.getContactList().addContact(
+ contactList.addContact(
query,
moreInfoContact,
- GuiActivator.getContactList()
- .getContactSource(contactSource).getUIGroup(),
+ contactList.getContactSource(contactSource).getUIGroup(),
false);
}
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ExternalContactSource.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ExternalContactSource.java
index 619d1b9..48934b8 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ExternalContactSource.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ExternalContactSource.java
@@ -376,8 +376,12 @@ public class ExternalContactSource
*/
public int getSourceIndex()
{
- if (contactSource.getIdentifier()
- .equals(ContactSourceService.CALL_HISTORY))
+ int sourceIndex = contactSource.getIndex();
+
+ if (sourceIndex >= 0)
+ return sourceIndex;
+
+ if (contactSource.getType() == ContactSourceService.HISTORY_TYPE)
return Integer.MAX_VALUE;
return Integer.MAX_VALUE - 1;
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactListSource.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactListSource.java
index 82ea955..6049ddf 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactListSource.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactListSource.java
@@ -22,6 +22,7 @@ import net.java.sip.communicator.service.contactlist.*;
import net.java.sip.communicator.service.contactlist.event.*;
import net.java.sip.communicator.service.customcontactactions.*;
import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.gui.event.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIContact.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIContact.java
index bb4b2f5..085351e 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIContact.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIContact.java
@@ -605,6 +605,7 @@ public class MetaUIContact
/**
* Creates an instance of <tt>MetaContactDetail</tt> by specifying the
* underlying protocol <tt>Contact</tt>.
+ *
* @param contact the protocol contact, on which this implementation
* is based
*/
@@ -612,14 +613,25 @@ public class MetaUIContact
{
super( contact.getAddress(),
contact.getDisplayName(),
- null,
- null,
new ImageIcon(contact.getPresenceStatus().getStatusIcon()),
- contact.getProtocolProvider(),
- contact.getProtocolProvider().getProtocolName(),
contact);
this.contact = contact;
+
+ ProtocolProviderService parentProvider
+ = contact.getProtocolProvider();
+
+ Iterator<Class<? extends OperationSet>> opSetClasses
+ = parentProvider.getSupportedOperationSetClasses().iterator();
+
+ while (opSetClasses.hasNext())
+ {
+ Class<? extends OperationSet> opSetClass = opSetClasses.next();
+
+ addPreferredProtocolProvider(opSetClass, parentProvider);
+ addPreferredProtocol(opSetClass,
+ parentProvider.getProtocolName());
+ }
}
/**
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ProtocolContactSourceServiceImpl.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ProtocolContactSourceServiceImpl.java
new file mode 100644
index 0000000..228d1e5
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ProtocolContactSourceServiceImpl.java
@@ -0,0 +1,217 @@
+/*
+ * 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.impl.gui.main.contactlist.contactsource;
+
+import java.util.*;
+import java.util.regex.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.service.contactlist.*;
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ *
+ * @author Yana Stamcheva
+ */
+public class ProtocolContactSourceServiceImpl
+ implements ContactSourceService
+{
+ private final ProtocolProviderService protocolProvider;
+
+ private final Class<? extends OperationSet> opSetClass;
+
+ MetaContactListService metaContactListService
+ = GuiActivator.getContactListService();
+
+ /**
+ * The <tt>List</tt> of <tt>ProtocolContactQuery</tt> instances
+ * which have been started and haven't stopped yet.
+ */
+ private final List<ProtocolCQuery> queries
+ = new LinkedList<ProtocolCQuery>();
+
+ /**
+ * Creates an instance of <tt>ProtocolContactSourceServiceImpl</tt>.
+ *
+ * @param protocolProvider the protocol provider which is the contact source
+ * @param opSetClass the <tt>OperationSet</tt> class that is supported by
+ * source contacts
+ */
+ public ProtocolContactSourceServiceImpl(
+ ProtocolProviderService protocolProvider,
+ Class<? extends OperationSet> opSetClass)
+ {
+ this.protocolProvider = protocolProvider;
+ this.opSetClass = opSetClass;
+ }
+
+ public int getType()
+ {
+ return DEFAULT_TYPE;
+ }
+
+ public String getDisplayName()
+ {
+ return GuiActivator.getResources().getI18NString("service.gui.CONTACTS")
+ + " " + protocolProvider.getAccountID().getDisplayName();
+ }
+
+ public ContactQuery queryContactSource(String queryString)
+ {
+ return queryContactSource(queryString, -1);
+ }
+
+ public ContactQuery queryContactSource( String queryString,
+ int contactCount)
+ {
+ if (queryString == null)
+ queryString = "";
+
+ ProtocolCQuery contactQuery
+ = new ProtocolCQuery(queryString, contactCount);
+
+ synchronized (queries)
+ {
+ queries.add(contactQuery);
+ }
+
+ boolean queryHasStarted = false;
+
+ try
+ {
+ contactQuery.start();
+ queryHasStarted = true;
+ }
+ finally
+ {
+ if (!queryHasStarted)
+ {
+ synchronized (queries)
+ {
+ if (queries.remove(contactQuery))
+ queries.notify();
+ }
+ }
+ }
+ return contactQuery;
+ }
+
+ private class ProtocolCQuery
+ extends AsyncContactQuery<ProtocolContactSourceServiceImpl>
+ {
+ private int contactCount;
+
+ private String queryString;
+
+ public ProtocolCQuery(String queryString, int contactCount)
+ {
+ super(ProtocolContactSourceServiceImpl.this,
+ Pattern.compile(queryString, Pattern.CASE_INSENSITIVE
+ | Pattern.LITERAL));
+
+ this.queryString = queryString;
+ this.contactCount = contactCount;
+ }
+
+ @Override
+ protected String normalizePhoneNumber(String phoneNumber)
+ {
+ return phoneNumber;
+ }
+
+ @Override
+ protected boolean phoneNumberMatches(String phoneNumber)
+ {
+ return false;
+ }
+
+ public void run()
+ {
+ Iterator<MetaContact> contactListIter = metaContactListService
+ .findAllMetaContactsForProvider(protocolProvider);
+
+ while (contactListIter.hasNext())
+ {
+ MetaContact metaContact = contactListIter.next();
+
+ if (getStatus() == QUERY_CANCELED)
+ return;
+
+ this.addResultContact(metaContact);
+ }
+
+ if (getStatus() != QUERY_CANCELED)
+ setStatus(QUERY_COMPLETED);
+ }
+
+ /**
+ * Adds the result for the given group.
+ *
+ * @param group the group
+ */
+ private void addResultContact(MetaContact metaContact)
+ {
+ Iterator<Contact> contacts
+ = metaContact.getContactsForProvider(protocolProvider);
+
+ while (contacts.hasNext())
+ {
+ if (getStatus() == QUERY_CANCELED)
+ return;
+
+ if(contactCount > 0 && getQueryResultCount() > contactCount)
+ break;
+
+ Contact contact = contacts.next();
+
+ if (queryString == null
+ || queryString.length() <= 0
+ || metaContact.getDisplayName().startsWith(queryString)
+ || contact.getAddress().startsWith(queryString)
+ || contact.getDisplayName().startsWith(queryString))
+ {
+ ArrayList<ContactDetail> contactDetails
+ = new ArrayList<ContactDetail>();
+
+ ContactDetail contactDetail
+ = new ContactDetail(contact.getAddress());
+
+ ArrayList<Class<? extends OperationSet>>
+ supportedOpSets
+ = new ArrayList<Class<? extends OperationSet>>();
+ supportedOpSets.add(opSetClass);
+ contactDetail.setSupportedOpSets(supportedOpSets);
+
+ contactDetails.add(contactDetail);
+
+ GenericSourceContact sourceContact
+ = new GenericSourceContact(
+ ProtocolContactSourceServiceImpl.this,
+ contact.getDisplayName(),
+ contactDetails);
+
+ sourceContact.setImage(metaContact.getAvatar());
+ sourceContact
+ .setPresenceStatus(contact.getPresenceStatus());
+
+ addQueryResult(sourceContact);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the index of the contact source in the result list.
+ *
+ * @return the index of the contact source in the result list
+ */
+ public int getIndex()
+ {
+ return 1;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ShowMoreContact.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ShowMoreContact.java
index d3ed3da..0ce9f0f 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ShowMoreContact.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ShowMoreContact.java
@@ -12,7 +12,6 @@ import javax.swing.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.contactlist.*;
-import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.contactsource.*;
import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.gui.event.*;
@@ -56,19 +55,27 @@ public class ShowMoreContact
/**
* The count of shown contacts corresponding to the underlying query.
*/
- private int shownResultsCount = UIFilterQuery.MAX_EXTERNAL_RESULT_COUNT;
+ private int shownResultsCount;
+
+ /**
+ * The maximum result count by show.
+ */
+ private int maxResultCount;
/**
* Creates an instance of <tt>MoreInfoContact</tt>.
*
- * @param contactQuery
- * @param queryResults
+ * @param contactQuery the contact query
+ * @param queryResults the result list
+ * @param maxResultCount the maximum result count
*/
public ShowMoreContact( ContactQuery contactQuery,
- List<SourceContact> queryResults)
+ List<SourceContact> queryResults,
+ int maxResultCount)
{
this.contactQuery = contactQuery;
this.queryResults = queryResults;
+ this.maxResultCount = maxResultCount;
GuiActivator.getContactList().addContactListListener(this);
}
@@ -264,7 +271,7 @@ public class ShowMoreContact
= new ArrayList<SourceContact>(queryResults);
int newCount
- = shownResultsCount + UIFilterQuery.MAX_EXTERNAL_RESULT_COUNT;
+ = shownResultsCount + maxResultCount;
int resultSize = contacts.size();
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/SourceUIContact.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/SourceUIContact.java
index 2bbd010..4f891d8 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/SourceUIContact.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/SourceUIContact.java
@@ -98,10 +98,10 @@ public class SourceUIContact
/**
* The parent group of source contacts could not be changed.
+ *
* @param parentGroup the parent group to set
*/
- public void setParentGroup(UIGroup parentGroup)
- {}
+ public void setParentGroup(UIGroup parentGroup) {}
/**
* Returns -1 to indicate that the source index of the underlying
@@ -160,6 +160,7 @@ public class SourceUIContact
/**
* Returns the default <tt>ContactDetail</tt> to use for any operations
* depending to the given <tt>OperationSet</tt> class.
+ *
* @param opSetClass the <tt>OperationSet</tt> class we're interested in
* @return the default <tt>ContactDetail</tt> to use for any operations
* depending to the given <tt>OperationSet</tt> class
@@ -200,18 +201,6 @@ public class SourceUIContact
*/
public List<UIContactDetail> getContactDetails()
{
- return getContactDetails(sourceContact);
- }
-
- /**
- * Returns a list of all contained <tt>UIContactDetail</tt>s.
- *
- * @param sourceContact the source contact we get details from.
- * @return a list of all contained <tt>UIContactDetail</tt>s
- */
- public static List<UIContactDetail> getContactDetails(
- SourceContact sourceContact)
- {
List<UIContactDetail> resultList
= new LinkedList<UIContactDetail>();
@@ -315,8 +304,8 @@ public class SourceUIContact
detail.getCategory(),
detail.getLabels(),
null,
- detail.getPreferredProtocolProvider(opSetClass),
- detail.getPreferredProtocol(opSetClass),
+ null,
+ null,
detail);
ContactSourceService contactSource
@@ -330,6 +319,11 @@ public class SourceUIContact
if (prefix != null)
setPrefix(prefix);
}
+
+ addPreferredProtocolProvider(opSetClass,
+ detail.getPreferredProtocolProvider(opSetClass));
+ addPreferredProtocol(opSetClass,
+ detail.getPreferredProtocol(opSetClass));
}
/**
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/StringContactSourceServiceImpl.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/StringContactSourceServiceImpl.java
new file mode 100644
index 0000000..10c5c5d
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/StringContactSourceServiceImpl.java
@@ -0,0 +1,203 @@
+/*
+ * 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.impl.gui.main.contactlist.contactsource;
+
+import java.util.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The <tt>StringContactSourceServiceImpl</tt> is an implementation of the
+ * <tt>ContactSourceService</tt> that returns the searched string as a result
+ * contact.
+ *
+ * @author Yana Stamcheva
+ */
+public class StringContactSourceServiceImpl
+ implements ContactSourceService
+{
+ /**
+ * The protocol provider to be used with this string contact source.
+ */
+ private final ProtocolProviderService protocolProvider;
+
+ /**
+ * The operation set supported by this string contact source.
+ */
+ private final Class<? extends OperationSet> opSetClass;
+
+ /**
+ * Creates an instance of <tt>StringContactSourceServiceImpl</tt>.
+ *
+ * @param protocolProvider the protocol provider to be used with this string
+ * contact source
+ * @param opSet the operation set supported by this string contact source
+ */
+ public StringContactSourceServiceImpl(
+ ProtocolProviderService protocolProvider,
+ Class<? extends OperationSet> opSet)
+ {
+ this.protocolProvider = protocolProvider;
+ this.opSetClass = opSet;
+ }
+
+ /**
+ * Returns the type of this contact source.
+ *
+ * @return the type of this contact source
+ */
+ public int getType()
+ {
+ return SEARCH_TYPE;
+ }
+
+ /**
+ * Returns a user-friendly string that identifies this contact source.
+ *
+ * @return the display name of this contact source
+ */
+ public String getDisplayName()
+ {
+ return GuiActivator.getResources().getI18NString(
+ "service.gui.SEARCH_STRING_CONTACT_SOURCE");
+ }
+
+ /**
+ * Queries this search source for the given <tt>queryString</tt>.
+ *
+ * @param queryString the string to search for
+ * @return the created query
+ */
+ public ContactQuery queryContactSource(String queryString)
+ {
+ return queryContactSource(queryString, -1);
+ }
+
+ /**
+ * Queries this search source for the given <tt>queryString</tt>.
+ *
+ * @param queryString the string to search for
+ * @param contactCount the maximum count of result contacts
+ * @return the created query
+ */
+ public ContactQuery queryContactSource( String queryString,
+ int contactCount)
+ {
+ return new StringQuery(queryString);
+ }
+
+ /**
+ * The query implementation.
+ */
+ private class StringQuery
+ extends AbstractContactQuery<ContactSourceService>
+ {
+ /**
+ * The query string.
+ */
+ private String queryString;
+
+ /**
+ * The query result list.
+ */
+ private final List<SourceContact> results;
+
+ /**
+ * Creates an instance of this query implementation.
+ *
+ * @param queryString the string to query
+ */
+ public StringQuery(String queryString)
+ {
+ super(StringContactSourceServiceImpl.this);
+
+ this.queryString = queryString;
+ this.results = new ArrayList<SourceContact>();
+
+ results.add(getSourceContact());
+
+ if (getStatus() != QUERY_CANCELED)
+ setStatus(QUERY_COMPLETED);
+ }
+
+ /**
+ * Returns the query string.
+ *
+ * @return the query string
+ */
+ public String getQueryString()
+ {
+ return queryString;
+ }
+
+ /**
+ * Returns the list of query results.
+ *
+ * @return the list of query results
+ */
+ public List<SourceContact> getQueryResults()
+ {
+ return results;
+ }
+
+ /**
+ * Returns the source contact corresponding to the query string.
+ *
+ * @return the source contact corresponding to the query string
+ */
+ private SourceContact getSourceContact()
+ {
+ ArrayList<ContactDetail> contactDetails
+ = new ArrayList<ContactDetail>();
+
+ ContactDetail contactDetail = new ContactDetail(queryString);
+
+ // Init supported operation sets.
+ ArrayList<Class<? extends OperationSet>>
+ supportedOpSets
+ = new ArrayList<Class<? extends OperationSet>>();
+ supportedOpSets.add(opSetClass);
+ contactDetail.setSupportedOpSets(supportedOpSets);
+
+ // Init preferred protocol providers.
+ Map<Class<? extends OperationSet>,ProtocolProviderService>
+ providers = new HashMap<Class<? extends OperationSet>,
+ ProtocolProviderService>();
+
+ providers.put(opSetClass, protocolProvider);
+
+ contactDetail.setPreferredProviders(providers);
+
+ contactDetails.add(contactDetail);
+
+ GenericSourceContact sourceContact
+ = new GenericSourceContact( StringContactSourceServiceImpl.this,
+ queryString,
+ contactDetails);
+
+ sourceContact.setDisplayDetails(
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CALL_VIA")
+ + " "
+ + protocolProvider.getAccountID().getDisplayName());
+
+ return sourceContact;
+ }
+ }
+
+ /**
+ * Returns the index of the contact source in the result list.
+ *
+ * @return the index of the contact source in the result list
+ */
+ public int getIndex()
+ {
+ return 0;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContact.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContact.java
index 4d0877b..e65ae28 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContact.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContact.java
@@ -471,12 +471,20 @@ public class NotificationContact
{
super( messageAccount,
messageAccount,
- null,
- null,
ImageLoader.getAccountStatusImage(protocolProvider),
- protocolProvider,
- protocolProvider.getProtocolName(),
notificationMessage);
+
+ Iterator<Class<? extends OperationSet>> opSetClasses
+ = protocolProvider.getSupportedOperationSetClasses().iterator();
+
+ while (opSetClasses.hasNext())
+ {
+ Class<? extends OperationSet> opSetClass = opSetClasses.next();
+
+ addPreferredProtocolProvider(opSetClass, protocolProvider);
+ addPreferredProtocol(opSetClass,
+ protocolProvider.getProtocolName());
+ }
}
/**
diff --git a/src/net/java/sip/communicator/impl/gui/utils/InviteContactListFilter.java b/src/net/java/sip/communicator/impl/gui/utils/InviteContactListFilter.java
new file mode 100644
index 0000000..0c90fd0
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/utils/InviteContactListFilter.java
@@ -0,0 +1,80 @@
+/*
+ * 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.impl.gui.utils;
+
+import java.util.*;
+
+import net.java.sip.communicator.impl.gui.main.contactlist.*;
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.gui.*;
+
+/**
+ * The <tt>InviteContactListFilter</tt> is a <tt>SearchFilter</tt> that filters
+ * the contact list to fit invite operations.
+ *
+ * @author Yana Stamcheva
+ */
+public class InviteContactListFilter
+ extends SearchFilter
+{
+ /**
+ * Creates an instance of <tt>InviteContactListFilter</tt>.
+ *
+ * @param sourceContactList the contact list to filter
+ */
+ public InviteContactListFilter(ContactList sourceContactList)
+ {
+ super(sourceContactList);
+ }
+
+ /**
+ * Applies this filter to the default contact source.
+ * @param filterQuery the query that tracks this filter.
+ */
+ public void applyFilter(FilterQuery filterQuery)
+ {
+ filterQuery.setMaxResultShown(-1);
+
+ List<UIContactSource> filterSources
+ = sourceContactList.getContactSources(
+ ContactSourceService.DEFAULT_TYPE);
+
+ if (filterString != null && filterString.length() > 0)
+ {
+ filterSources.addAll(sourceContactList
+ .getContactSources(ContactSourceService.SEARCH_TYPE));
+ }
+
+ Iterator<UIContactSource> filterSourceIter = filterSources.iterator();
+
+ // If we have stopped filtering in the mean time we return here.
+ if (filterQuery.isCanceled())
+ return;
+
+ // Then we apply the filter on all its contact sources.
+ while (filterSourceIter.hasNext())
+ {
+ final UIContactSource filterSource
+ = filterSourceIter.next();
+
+ // If we have stopped filtering in the mean time we return here.
+ if (filterQuery.isCanceled())
+ return;
+
+ ContactQuery query = applyFilter(filterSource);
+
+ if (query.getStatus() == ContactQuery.QUERY_IN_PROGRESS)
+ filterQuery.addContactQuery(query);
+ }
+
+ // Closes this filter to indicate that we finished adding queries to it.
+ if (filterQuery.isRunning())
+ filterQuery.close();
+ else if (!sourceContactList.isEmpty())
+ sourceContactList.selectFirstContact();
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/gui/utils/InviteContactTransferHandler.java b/src/net/java/sip/communicator/impl/gui/utils/InviteContactTransferHandler.java
index e4be964..7d291c5 100644
--- a/src/net/java/sip/communicator/impl/gui/utils/InviteContactTransferHandler.java
+++ b/src/net/java/sip/communicator/impl/gui/utils/InviteContactTransferHandler.java
@@ -13,7 +13,6 @@ import java.util.*;
import javax.swing.*;
import net.java.sip.communicator.impl.gui.main.contactlist.*;
-import net.java.sip.communicator.service.contactlist.*;
import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.*;
@@ -24,6 +23,7 @@ import net.java.sip.communicator.util.swing.*;
* simple string addresses to the conference invite dialog.
*
* @author Sebastien Vincent
+ * @author Yana Stamcheva
*/
public class InviteContactTransferHandler
extends ExtendedTransferHandler
@@ -46,15 +46,19 @@ public class InviteContactTransferHandler
= new DataFlavor(UIContact.class, "UIContact");
/**
- * The data flavor used when transferring <tt>UIContact</tt>s.
+ * The source contact list.
*/
- protected static final DataFlavor metaContactDataFlavor
- = new DataFlavor(MetaContact.class, "MetaContact");
+ private final ContactList srcContactList;
/**
- * The invite dialog.
+ * The destination contact list.
*/
- private final InviteDialog dialog;
+ private final ContactList destContactList;
+
+ /**
+ * The backup provider to use if no provider is specified.
+ */
+ private ProtocolProviderService backupProvider;
/**
* If the component is the selected contact list or not
@@ -67,15 +71,19 @@ public class InviteContactTransferHandler
* @param dialog the invite dialog
* @param selected if the column is the selected ones
*/
- public InviteContactTransferHandler(InviteDialog dialog, boolean selected)
+ public InviteContactTransferHandler(ContactList srcContactList,
+ ContactList destContactList,
+ boolean selected)
{
- this.dialog = dialog;
+ this.srcContactList = srcContactList;
+ this.destContactList = destContactList;
this.selected = selected;
}
/**
* Creates a transferable for text pane components in order to enable drag
* and drop of text.
+ *
* @param component the component for which to create a
* <tt>Transferable</tt>
* @return the created <tt>Transferable</tt>
@@ -83,11 +91,12 @@ public class InviteContactTransferHandler
@Override
protected Transferable createTransferable(JComponent component)
{
- if (component instanceof DefaultContactList)
+ if (component instanceof ContactList)
{
- MetaContact c =
- (MetaContact)((DefaultContactList)component).getSelectedValue();
- return new MetaContactTransferable(c);
+ List<UIContact> c = ((ContactList) component).getSelectedContacts();
+
+ if (c != null)
+ return new UIContactTransferable(c);
}
return super.createTransferable(component);
@@ -109,10 +118,9 @@ public class InviteContactTransferHandler
{
for (int i = 0, n = flavor.length; i < n; i++)
{
- if (flavor[i].equals(uiContactDataFlavor) ||
- flavor[i].equals(metaContactDataFlavor))
+ if (flavor[i].equals(uiContactDataFlavor))
{
- if (comp instanceof DefaultContactList)
+ if (comp instanceof ContactList)
{
return true;
}
@@ -156,102 +164,111 @@ public class InviteContactTransferHandler
logger.debug("Failed to drop meta contact.", e);
}
- if (o instanceof ContactNode)
+ if (o instanceof Collection)
{
- UIContact uiContact
- = ((ContactNode) o).getContactDescriptor();
-
- Object obj = uiContact.getDescriptor();
-
- if(!(obj instanceof MetaContact))
- return false;
-
- Iterator<UIContactDetail> contactDetails
- = uiContact.getContactDetailsForOperationSet(
- OperationSetBasicTelephony.class).iterator();
- if(!contactDetails.hasNext())
- return false;
+ Iterator<?> c = ((Collection<?>) o).iterator();
- MetaContact metaContact =
- (MetaContact)uiContact.getDescriptor();
+ while (c.hasNext())
+ {
+ Object nextO = c.next();
+
+ if (nextO instanceof UIContact)
+ {
+ destContactList.addContact(
+ new InviteUIContact((UIContact) nextO,
+ backupProvider),
+ null, false, false);
+ }
+ }
- dialog.addSelectedMetaContact(metaContact);
return true;
}
- }
- else if(t.isDataFlavorSupported(metaContactDataFlavor))
- {
- MetaContact c = null;
-
- try
- {
- c = (MetaContact)t.getTransferData(metaContactDataFlavor);
- }
- catch(Exception e)
+ else if (o instanceof UIContact)
{
- e.printStackTrace();
- }
+ destContactList.addContact(
+ new InviteUIContact((UIContact) o,
+ backupProvider),
+ null, false, false);
- if(selected)
- {
- dialog.removeMetaContact(c);
- dialog.addSelectedMetaContact(c);
return true;
}
- else
+ else if (o instanceof ContactNode)
{
- dialog.removeSelectedMetaContact(c);
- dialog.addMetaContact(c);
+ UIContact uiContact = ((ContactNode) o).getContactDescriptor();
+
+ if (uiContact != null)
+ {
+ destContactList.addContact(
+ new InviteUIContact(uiContact,
+ backupProvider),
+ null, false, false);
+
+ return true;
+ }
}
- return true;
}
return false;
}
/**
- * Transferable for DefaultContactList that enables drag and drop of
- * meta contacts.
+ * The backup provider to use if no provider has been specified.
+ *
+ * @param backupProvider the backup provider to use if no provider has been
+ * specified
*/
- public class MetaContactTransferable
+ public void setBackupProvider(ProtocolProviderService backupProvider)
+ {
+ this.backupProvider = backupProvider;
+ }
+
+ /**
+ * Transferable for TreeContactList that enables drag and drop of
+ * ui contacts.
+ */
+ public class UIContactTransferable
implements Transferable
{
/**
- * The meta contact.
+ * The ui contact.
*/
- private final MetaContact metaContact;
+ private final List<UIContact> uiContacts;
/**
- * Creates an instance of <tt>MetaContactTransferable</tt>.
- * @param metaContact the meta contact to transfer
+ * Creates an instance of <tt>UIContactTransferable</tt>.
+ *
+ * @param uiContacts the ui contacts to transfer
*/
- public MetaContactTransferable(MetaContact metaContact)
+ public UIContactTransferable(List<UIContact> uiContacts)
{
- this.metaContact = metaContact;
+ this.uiContacts = uiContacts;
}
/**
* Returns supported flavors.
+ *
* @return an array of supported flavors
*/
public DataFlavor[] getTransferDataFlavors()
{
- return new DataFlavor[] { metaContactDataFlavor};
+ return new DataFlavor[] {uiContactDataFlavor};
}
/**
* Returns <tt>true</tt> if the given <tt>flavor</tt> is supported,
* otherwise returns <tt>false</tt>.
+ *
* @param flavor the data flavor to verify
* @return <tt>true</tt> if the given <tt>flavor</tt> is supported,
* otherwise returns <tt>false</tt>
*/
public boolean isDataFlavorSupported(DataFlavor flavor)
{
- return metaContactDataFlavor.equals(flavor);
+ return uiContactDataFlavor.equals(flavor);
}
/**
* Returns the selected text.
+ *
* @param flavor the flavor
* @return the selected text
* @exception UnsupportedFlavorException if the requested data flavor
@@ -263,17 +280,17 @@ public class InviteContactTransferHandler
throws UnsupportedFlavorException,
IOException
{
- return metaContact;
+ return uiContacts;
}
/**
- * Returns meta contact.
+ * Returns the ui contacts.
*
- * @return meta contact
+ * @return the ui contacts
*/
- public MetaContact getMetaContact()
+ public List<UIContact> getUIContacts()
{
- return metaContact;
+ return uiContacts;
}
}
}
diff --git a/src/net/java/sip/communicator/impl/gui/utils/InviteDialog.java b/src/net/java/sip/communicator/impl/gui/utils/InviteDialog.java
index 8dcf07f..47a7cd7 100644
--- a/src/net/java/sip/communicator/impl/gui/utils/InviteDialog.java
+++ b/src/net/java/sip/communicator/impl/gui/utils/InviteDialog.java
@@ -8,17 +8,19 @@ package net.java.sip.communicator.impl.gui.utils;
import java.awt.*;
import java.awt.event.*;
-import java.util.*;
import javax.swing.*;
import net.java.sip.communicator.impl.gui.*;
-import net.java.sip.communicator.impl.gui.lookandfeel.*;
import net.java.sip.communicator.impl.gui.main.contactlist.*;
-import net.java.sip.communicator.service.contactlist.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.gui.event.*;
+import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.skin.*;
import net.java.sip.communicator.util.swing.*;
+import java.util.*;
+import java.util.List;
/**
* The invite dialog is a widget that shows a list of contacts, from which the
* user could pick in order to create a conference chat or call.
@@ -28,52 +30,61 @@ import net.java.sip.communicator.util.swing.*;
*/
public class InviteDialog
extends SIPCommDialog
- implements Skinnable
+ implements Skinnable,
+ ContactListContainer
{
private static final long serialVersionUID = 0L;
+ /**
+ * Text area where user can specify a reason for the invitation.
+ */
private final JTextArea reasonArea = new JTextArea();
+ /**
+ * The button, which performs the invite.
+ */
private final JButton inviteButton = new JButton(
GuiActivator.getResources().getI18NString("service.gui.INVITE"));
+ /**
+ * The button, which cancels the operation.
+ */
private final JButton cancelButton = new JButton(
GuiActivator.getResources().getI18NString("service.gui.CANCEL"));
- private final DefaultListModel contactListModel = new DefaultListModel();
+ /**
+ * The search field.
+ */
+ private final SearchField searchField;
- protected final DefaultListModel selectedContactListModel
- = new DefaultListModel();
+ /**
+ * The source contact list.
+ */
+ protected ContactList srcContactList;
- protected final SIPCommTextField newContactField
- = new SIPCommTextField(GuiActivator.getResources()
- .getI18NString("service.gui.OR_ENTER_PHONE_NUMBER"));
+ /**
+ * The destination contact list.
+ */
+ protected ContactList destContactList;
/**
- * Icon label.
+ * The invite contact transfer handler.
*/
- private final JLabel iconLabel;
+ private InviteContactTransferHandler inviteContactTransferHandler;
/**
- * Constructs an <tt>InviteDialog</tt>, by specifying the initial list of
- * contacts available for invite.
- *
- * @param title the title to show on the top of this dialog
- * @param metaContacts the list of contacts available for invite
+ * Currently selected protocol provider.
*/
- public InviteDialog(String title, java.util.List<MetaContact> metaContacts)
- {
- this(title);
+ private ProtocolProviderService currentProvider;
- // Initialize contacts list.
- for(MetaContact metaContact : metaContacts)
- {
- this.addMetaContact(metaContact);
- }
- }
+ /**
+ * Icon label.
+ */
+ private final JLabel iconLabel;
/**
* Constructs an <tt>InviteDialog</tt>.
+ *
* @param title the title to show on the top of this dialog
*/
public InviteDialog (String title)
@@ -120,78 +131,22 @@ public class InviteDialog
buttonsPanel.add(inviteButton);
buttonsPanel.add(cancelButton);
- this.getRootPane().setDefaultButton(inviteButton);
inviteButton.setMnemonic(
GuiActivator.getResources().getI18nMnemonic("service.gui.INVITE"));
cancelButton.setMnemonic(
GuiActivator.getResources().getI18nMnemonic("service.gui.CANCEL"));
- final DefaultContactList contactList = new DefaultContactList();
- final DefaultContactList selectedContactList = new DefaultContactList();
+ Component contactListComponent = createSrcContactListComponent();
- contactList.setModel(contactListModel);
- contactList.setDragEnabled(true);
- contactList.setTransferHandler(new InviteContactTransferHandler(this,
- false));
- selectedContactList.setModel(selectedContactListModel);
- selectedContactList.setTransferHandler(
- new InviteContactTransferHandler(this, true));
- selectedContactList.setDragEnabled(true);
+ ContactListSearchFilter inviteFilter
+ = new InviteContactListFilter(srcContactList);
- contactList.addMouseListener(new MouseAdapter()
- {
- public void mouseClicked(MouseEvent e)
- {
- if (e.getClickCount() > 1)
- {
- Object[] metaContacts = contactList.getSelectedValues();
-
- moveContactsFromLeftToRight(metaContacts);
- }
- }
- });
+ srcContactList.setDefaultFilter(inviteFilter);
- selectedContactList.addMouseListener(new MouseAdapter()
- {
- public void mouseClicked(MouseEvent e)
- {
- if (e.getClickCount() > 1)
- {
- Object[] metaContacts
- = selectedContactList.getSelectedValues();
-
- moveContactsFromRightToLeft(metaContacts);
- }
- }
- });
-
- JScrollPane contactListScrollPane = new JScrollPane();
-
- contactListScrollPane.setOpaque(false);
- contactListScrollPane.getViewport().setOpaque(false);
- contactListScrollPane.getViewport().add(contactList);
- contactListScrollPane.getViewport().setBorder(null);
- contactListScrollPane.setViewportBorder(null);
- contactListScrollPane.setBorder(null);
-
- JScrollPane selectedListScrollPane = new JScrollPane();
-
- selectedListScrollPane.setOpaque(false);
- selectedListScrollPane.getViewport().setOpaque(false);
- selectedListScrollPane.getViewport().add(selectedContactList);
- selectedListScrollPane.getViewport().setBorder(null);
- selectedListScrollPane.setViewportBorder(null);
- selectedListScrollPane.setBorder(
- SIPCommBorders.getRoundBorder());
-
- // New contact text field panel.
- newContactField.getInputMap().put(
- KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
- "moveStringFromLeftToRight");
- newContactField.getActionMap().put("moveStringFromLeftToRight",
- new MoveStringToRight());
-
- newContactField.addFocusListener(new FocusAdapter()
+ searchField = new SearchField(null, inviteFilter);
+ searchField.setPreferredSize(new Dimension(200, 25));
+ searchField.setContactList(srcContactList);
+ searchField.addFocusListener(new FocusAdapter()
{
/**
* Removes all other selections.
@@ -199,21 +154,20 @@ public class InviteDialog
*/
public void focusGained(FocusEvent e)
{
- contactList.removeSelectionInterval(
- 0, contactList.getMaxSelectionIndex());
+ srcContactList.removeSelection();
}
});
- TransparentPanel leftPanel = new TransparentPanel(new BorderLayout());
- leftPanel.setBorder(SIPCommBorders.getRoundBorder());
- leftPanel.add(contactListScrollPane);
- leftPanel.add(newContactField, BorderLayout.SOUTH);
+ TransparentPanel leftPanel
+ = new TransparentPanel(new BorderLayout(5, 5));
+ leftPanel.add(searchField, BorderLayout.NORTH);
+ leftPanel.add(contactListComponent);
JPanel listPanel = new JPanel(new GridLayout(0, 2, 5, 5));
listPanel.setPreferredSize(new Dimension(400, 200));
listPanel.add(leftPanel);
- listPanel.add(selectedListScrollPane);
+ listPanel.add(createDestContactListComponent());
listPanel.setOpaque(false);
// Add remove buttons panel.
@@ -233,12 +187,11 @@ public class InviteDialog
{
public void actionPerformed(ActionEvent e)
{
- Object[] metaContacts = contactList.getSelectedValues();
-
- if (metaContacts != null && metaContacts.length > 0)
- moveContactsFromLeftToRight(metaContacts);
+ List<UIContact> selectedContacts
+ = srcContactList.getSelectedContacts();
- moveStringFromLeftToRight();
+ if (selectedContacts != null && selectedContacts.size() > 0)
+ moveContactsFromLeftToRight(selectedContacts.iterator());
}
});
@@ -246,10 +199,11 @@ public class InviteDialog
{
public void actionPerformed(ActionEvent e)
{
- Object[] metaContacts = selectedContactList.getSelectedValues();
+ List<UIContact> selectedContacts
+ = destContactList.getSelectedContacts();
- if (metaContacts != null && metaContacts.length > 0)
- moveContactsFromRightToLeft(metaContacts);
+ if (selectedContacts != null && selectedContacts.size() > 0)
+ moveContactsFromRightToLeft(selectedContacts.iterator());
}
});
@@ -267,211 +221,251 @@ public class InviteDialog
mainPanel.add(southPanel, BorderLayout.SOUTH);
this.getContentPane().add(mainPanel);
- }
- /**
- * Adds the given <tt>metaContact</tt> to the right list (selected) of
- * contacts for invite.
- * @param metaContact the <tt>MetaContact</tt> to add
- */
- public void addSelectedMetaContact(MetaContact metaContact)
- {
- selectedContactListModel.addElement(metaContact);
- }
+ initTransferHandler();
- /**
- * Removes the given <tt>metaContact</tt> from the right list (selected) of
- * contacts available for invite.
- * @param metaContact the <tt>MetaContact</tt> to remove
- */
- public void removeSelectedMetaContact(MetaContact metaContact)
- {
- selectedContactListModel.removeElement(metaContact);
+ KeyboardFocusManager keyManager
+ = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+
+ ContactListSearchKeyDispatcher clKeyDispatcher
+ = new ContactListSearchKeyDispatcher( keyManager,
+ searchField,
+ this);
+
+ clKeyDispatcher.setContactList(srcContactList);
+
+ keyManager.addKeyEventDispatcher(clKeyDispatcher);
}
/**
- * Adds the given <tt>metaContact</tt> to the left list of contacts
- * available for invite.
- * @param metaContact the <tt>MetaContact</tt> to add
+ * Returns the reason of this invite, if the user has specified one.
+ *
+ * @return the reason of this invite
*/
- public void addMetaContact(MetaContact metaContact)
+ public String getReason()
{
- contactListModel.addElement(metaContact);
+ return reasonArea.getText();
}
/**
- * Removes the given <tt>metaContact</tt> from the left list of contacts
- * available for invite.
- * @param metaContact the <tt>MetaContact</tt> to remove
+ * Adds an <tt>ActionListener</tt> to the contained "Invite" button.
+ *
+ * @param l the <tt>ActionListener</tt> to add
*/
- public void removeMetaContact(MetaContact metaContact)
+ public void addInviteButtonListener(ActionListener l)
{
- contactListModel.removeElement(metaContact);
+ this.inviteButton.addActionListener(l);
}
/**
- * Removes all <tt>MetaContact</tt>-s from the left list of contacts
- * available for invite.
+ * Adds an <tt>ActionListener</tt> to the contained "Cancel" button.
+ *
+ * @param l the <tt>ActionListener</tt> to add
*/
- public void removeAllMetaContacts()
+ public void addCancelButtonListener(ActionListener l)
{
- contactListModel.removeAllElements();
+ this.cancelButton.addActionListener(l);
}
/**
- * Removes all <tt>MetaContact</tt>-s from the right list of selected
- * contacts for invite.
+ * Closes this dialog by clicking on the "Cancel" button.
+ *
+ * @param isEscaped indicates if this <tt>close</tt> is provoked by an
+ * escape
*/
- public void removeAllSelectedContacts()
+ protected void close(boolean isEscaped)
{
- selectedContactListModel.removeAllElements();
+ this.cancelButton.doClick();
}
/**
- * Returns an enumeration of the list of selected <tt>MetaContact</tt>s.
- * @return an enumeration of the list of selected <tt>MetaContact</tt>s
+ * Sets the current provider selected for this invite dialog.
+ *
+ * @param protocolProvider the protocol provider selected for this invite
+ * dialog
*/
- public Enumeration<MetaContact> getSelectedMetaContacts()
+ protected void setCurrentProvider(ProtocolProviderService protocolProvider)
{
- if (selectedContactListModel.getSize() == 0)
- return null;
-
- Vector<MetaContact> selectedMetaContacts = new Vector<MetaContact>();
- Enumeration<?> selectedContacts = selectedContactListModel.elements();
- while(selectedContacts.hasMoreElements())
- {
- Object contact = selectedContacts.nextElement();
- if (contact instanceof MetaContact)
- selectedMetaContacts.add((MetaContact)contact);
- }
+ this.currentProvider = protocolProvider;
- return selectedMetaContacts.elements();
+ inviteContactTransferHandler.setBackupProvider(currentProvider);
}
/**
- * Returns an enumeration of the list of selected Strings.
- * @return an enumeration of the list of selected Strings
+ * Moves contacts from the left list to the right.
+ *
+ * @param contacts an Iterator over a list of <tt>UIContact</tt>s
*/
- public Enumeration<String> getSelectedStrings()
+ private void moveContactsFromLeftToRight(Iterator<UIContact> contacts)
{
- if (selectedContactListModel.getSize() == 0)
- return null;
-
- Vector<String> selectedStrings = new Vector<String>();
- Enumeration<?> selectedContacts = selectedContactListModel.elements();
- while(selectedContacts.hasMoreElements())
+ while (contacts.hasNext())
{
- Object contact = selectedContacts.nextElement();
- if (contact instanceof String)
- selectedStrings.add((String)contact);
+ moveContactFromLeftToRight(contacts.next());
}
-
- return selectedStrings.elements();
}
/**
- * Returns the reason of this invite, if the user has specified one.
- * @return the reason of this invite
+ * Moves the given <tt>UIContact</tt> from left list to the right.
+ *
+ * @param uiContact the contact to move
*/
- public String getReason()
+ private void moveContactFromLeftToRight(UIContact uiContact)
{
- return reasonArea.getText();
+ destContactList.addContact(
+ new InviteUIContact(uiContact, currentProvider), null, false, false);
}
/**
- * Adds an <tt>ActionListener</tt> to the contained "Invite" button.
- * @param l the <tt>ActionListener</tt> to add
+ * Moves contacts from the right list to the left.
+ *
+ * @param contacts an Iterator over a list of <tt>UIContact</tt>s
*/
- public void addInviteButtonListener(ActionListener l)
+ protected void moveContactsFromRightToLeft(Iterator<UIContact> contacts)
{
- this.inviteButton.addActionListener(l);
+ while (contacts.hasNext())
+ {
+ moveContactFromRightToLeft(contacts.next());
+ }
}
/**
- * Adds an <tt>ActionListener</tt> to the contained "Cancel" button.
- * @param l the <tt>ActionListener</tt> to add
+ * Moves the given <tt>UIContact</tt> from left list to the right.
+ *
+ * @param uiContact the contact to move
*/
- public void addCancelButtonListener(ActionListener l)
+ private void moveContactFromRightToLeft(UIContact uiContact)
{
- this.cancelButton.addActionListener(l);
+ destContactList.removeContact(uiContact);
}
/**
- * Closes this dialog by clicking on the "Cancel" button.
- * @param isEscaped indicates if this <tt>close</tt> is provoked by an
- * escape
+ * Reloads icon for icon label.
*/
- protected void close(boolean isEscaped)
+ public void loadSkin()
{
- this.cancelButton.doClick();
+ iconLabel.setIcon(new ImageIcon(
+ ImageLoader.getImage(ImageLoader.INVITE_DIALOG_ICON)));
}
/**
- * Moves contacts from the left list to the right.
+ * Creates the source contact list component.
*
- * @param metaContacts the contacts to move.
+ * @return the created contact list component
*/
- private void moveContactsFromLeftToRight(Object[] metaContacts)
+ private Component createSrcContactListComponent()
{
- for (Object metaContact : metaContacts)
+ srcContactList
+ = GuiActivator.getUIService().createContactListComponent();
+
+ srcContactList.setDragEnabled(true);
+ srcContactList.setContactButtonsVisible(false);
+ srcContactList.setMultipleSelectionEnabled(true);
+ srcContactList.addContactListListener(new ContactListListener()
{
- contactListModel.removeElement(metaContact);
+ public void groupSelected(ContactListEvent evt) {}
- selectedContactListModel.addElement(metaContact);
- }
- }
+ public void groupClicked(ContactListEvent evt) {}
- /**
- * Moves a string from left to right.
- */
- protected void moveStringFromLeftToRight()
- {
- String newContactText = newContactField.getText();
+ public void contactSelected(ContactListEvent evt) {}
+
+ public void contactClicked(ContactListEvent evt)
+ {
+ if (evt.getClickCount() > 1)
+ moveContactFromLeftToRight(evt.getSourceContact());
+ }
+ });
- if (newContactText != null && newContactText.length() > 0)
- selectedContactListModel.addElement(newContactField.getText());
+ // By default we set the current filter to be the presence filter.
+ JScrollPane contactListScrollPane = new JScrollPane();
+
+ contactListScrollPane.setOpaque(false);
+ contactListScrollPane.getViewport().setOpaque(false);
+ contactListScrollPane.getViewport().add(srcContactList.getComponent());
+ contactListScrollPane.getViewport().setBorder(null);
+ contactListScrollPane.setViewportBorder(null);
+ contactListScrollPane.setBorder(null);
- newContactField.setText("");
+ return contactListScrollPane;
}
/**
- * Moves a contact from the right list to the left.
+ * Creates the destination contact list component.
*
- * @param contacts the contact to move.
+ * @return the created contact list component
*/
- protected void moveContactsFromRightToLeft(Object[] contacts)
+ private Component createDestContactListComponent()
{
- for (Object contact : contacts)
+ destContactList
+ = GuiActivator.getUIService().createContactListComponent();
+
+ destContactList.setContactButtonsVisible(false);
+ destContactList.setMultipleSelectionEnabled(true);
+ destContactList.addContactListListener(new ContactListListener()
{
- selectedContactListModel.removeElement(contact);
+ public void groupSelected(ContactListEvent evt) {}
- // If this is a MetaContact re-add it in the left list.
- if (contact instanceof MetaContact)
- contactListModel.addElement(contact);
- }
+ public void groupClicked(ContactListEvent evt) {}
+
+ public void contactSelected(ContactListEvent evt) {}
+
+ public void contactClicked(ContactListEvent evt)
+ {
+ if (evt.getClickCount() > 1)
+ moveContactFromRightToLeft(evt.getSourceContact());
+ }
+ });
+
+ // By default we set the current filter to be the presence filter.
+ JScrollPane contactListScrollPane = new JScrollPane();
+
+ contactListScrollPane.setOpaque(false);
+ contactListScrollPane.getViewport().setOpaque(false);
+ contactListScrollPane.getViewport().add(destContactList.getComponent());
+ contactListScrollPane.getViewport().setBorder(null);
+ contactListScrollPane.setViewportBorder(null);
+ contactListScrollPane.setBorder(null);
+
+ return contactListScrollPane;
}
/**
- * The <tt>MoveStringToRight</tt> is an <tt>AbstractAction</tt> that moves
- * the text to right panel containing selected contacts.
+ * Called when the ENTER key was typed when this container was the focused
+ * container. Performs the appropriate actions depending on the current
+ * state of the contained contact list.
*/
- private class MoveStringToRight
- extends UIAction
+ public void enterKeyTyped()
{
- private static final long serialVersionUID = 0L;
+ List<UIContact> selectedContacts = srcContactList.getSelectedContacts();
- public void actionPerformed(ActionEvent e)
- {
- moveStringFromLeftToRight();
- }
+ if (selectedContacts == null)
+ return;
+
+ moveContactsFromLeftToRight(selectedContacts.iterator());
}
/**
- * Reloads icon for icon label.
+ * Called when the CTRL-ENTER or CMD-ENTER keys were typed when this
+ * container was the focused container. Performs the appropriate actions
+ * depending on the current state of the contained contact list.
*/
- public void loadSkin()
+ public void ctrlEnterKeyTyped() {}
+
+ /**
+ * Initializes the transfer handler.
+ */
+ private void initTransferHandler()
{
- iconLabel.setIcon(new ImageIcon(
- ImageLoader.getImage(ImageLoader.INVITE_DIALOG_ICON)));
+ inviteContactTransferHandler
+ = new InviteContactTransferHandler( srcContactList,
+ destContactList,
+ true);
+
+ if (srcContactList.getComponent() instanceof JComponent)
+ ((JComponent) srcContactList).setTransferHandler(
+ inviteContactTransferHandler);
+
+ if (destContactList.getComponent() instanceof JComponent)
+ ((JComponent) destContactList).setTransferHandler(
+ inviteContactTransferHandler);
}
}
diff --git a/src/net/java/sip/communicator/impl/gui/utils/OneChoiceInviteDialog.java b/src/net/java/sip/communicator/impl/gui/utils/OneChoiceInviteDialog.java
index 3c98513..b2da16c 100644
--- a/src/net/java/sip/communicator/impl/gui/utils/OneChoiceInviteDialog.java
+++ b/src/net/java/sip/communicator/impl/gui/utils/OneChoiceInviteDialog.java
@@ -10,12 +10,12 @@ import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
-import javax.swing.event.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.lookandfeel.*;
import net.java.sip.communicator.impl.gui.main.contactlist.*;
-import net.java.sip.communicator.service.contactlist.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.gui.event.*;
import net.java.sip.communicator.util.swing.*;
/**
@@ -26,6 +26,7 @@ import net.java.sip.communicator.util.swing.*;
*/
public class OneChoiceInviteDialog
extends SIPCommDialog
+ implements ContactListContainer
{
/**
* The information text area.
@@ -52,38 +53,12 @@ public class OneChoiceInviteDialog
/**
* The contact list.
*/
- private DefaultContactList contactList;
+ protected ContactList contactList;
/**
- * The contact list model.
+ * The search field.
*/
- private final DefaultListModel contactListModel = new DefaultListModel();
-
- /**
- * The new contact field.
- */
- private final SIPCommTextField newContactField
- = new SIPCommTextField(GuiActivator.getResources()
- .getI18NString("service.gui.OR_ENTER_PHONE_NUMBER"));
-
- /**
- * Constructs an <tt>OneChoiceInviteDialog</tt>, by specifying the initial
- * list of contacts available.
- *
- * @param title the title to show on the top of this dialog
- * @param metaContacts the list of contacts available for invite
- */
- public OneChoiceInviteDialog(String title,
- java.util.List<MetaContact> metaContacts)
- {
- this(title);
-
- // Initialize contacts list.
- for(MetaContact metaContact : metaContacts)
- {
- this.addMetaContact(metaContact);
- }
- }
+ private final SearchField searchField;
/**
* Constructs an <tt>OneChoiceInviteDialog</tt>.
@@ -125,7 +100,15 @@ public class OneChoiceInviteDialog
Component contactListComponent = createContactListComponent();
- newContactField.addFocusListener(new FocusAdapter()
+ ContactListSearchFilter inviteFilter
+ = new InviteContactListFilter(contactList);
+
+ contactList.setDefaultFilter(inviteFilter);
+
+ searchField = new SearchField(null, inviteFilter);
+ searchField.setPreferredSize(new Dimension(200, 25));
+ searchField.setContactList(contactList);
+ searchField.addFocusListener(new FocusAdapter()
{
/**
* Removes all other selections.
@@ -133,60 +116,42 @@ public class OneChoiceInviteDialog
*/
public void focusGained(FocusEvent e)
{
- contactList.removeSelectionInterval(
- contactList.getMinSelectionIndex(),
- contactList.getMaxSelectionIndex());
+ contactList.removeSelection();
}
});
TransparentPanel listPanel = new TransparentPanel(new BorderLayout());
listPanel.setBorder(SIPCommBorders.getRoundBorder());
listPanel.add(contactListComponent);
- listPanel.add(newContactField, BorderLayout.SOUTH);
+
+ northPanel.add(searchField, BorderLayout.SOUTH);
mainPanel.add(northPanel, BorderLayout.NORTH);
mainPanel.add(listPanel, BorderLayout.CENTER);
mainPanel.add(buttonsPanel, BorderLayout.SOUTH);
this.getContentPane().add(mainPanel);
- }
- /**
- * Adds the given <tt>metaContact</tt> to the left list of contacts
- * available for invite.
- * @param metaContact the <tt>MetaContact</tt> to add
- */
- public void addMetaContact(MetaContact metaContact)
- {
- contactListModel.addElement(metaContact);
- }
+ KeyboardFocusManager keyManager
+ = KeyboardFocusManager.getCurrentKeyboardFocusManager();
- /**
- * Removes the given <tt>metaContact</tt> from the left list of contacts
- * available for invite.
- * @param metaContact the <tt>MetaContact</tt> to add
- */
- public void removeMetaContact(MetaContact metaContact)
- {
- contactListModel.removeElement(metaContact);
- }
+ ContactListSearchKeyDispatcher clKeyDispatcher
+ = new ContactListSearchKeyDispatcher( keyManager,
+ searchField,
+ this);
- /**
- * Removes all <tt>MetaContact</tt>-s from the left list of contacts
- * available for invite.
- */
- public void removeAllMetaContacts()
- {
- contactListModel.removeAllElements();
+ clKeyDispatcher.setContactList(contactList);
+
+ keyManager.addKeyEventDispatcher(clKeyDispatcher);
}
/**
* Returns an enumeration of the list of selected <tt>MetaContact</tt>s.
* @return an enumeration of the list of selected <tt>MetaContact</tt>s
*/
- public MetaContact getSelectedMetaContact()
+ public UIContact getSelectedContact()
{
- return (MetaContact) contactList.getSelectedValue();
+ return contactList.getSelectedContact();
}
/**
@@ -195,7 +160,7 @@ public class OneChoiceInviteDialog
*/
public String getSelectedString()
{
- return newContactField.getText();
+ return searchField.getText();
}
/**
@@ -276,28 +241,71 @@ public class OneChoiceInviteDialog
*/
private Component createContactListComponent()
{
- contactList = new DefaultContactList();
-
- contactList.setModel(contactListModel);
+ contactList
+ = GuiActivator.getUIService().createContactListComponent();
- contactList.addListSelectionListener(new ListSelectionListener()
+ contactList.setContactButtonsVisible(false);
+ contactList.addContactListListener(new ContactListListener()
{
- public void valueChanged(ListSelectionEvent e)
+ public void groupSelected(ContactListEvent evt) {}
+
+ public void groupClicked(ContactListEvent evt) {}
+
+ public void contactSelected(ContactListEvent evt) {}
+
+ public void contactClicked(ContactListEvent evt)
{
- if (contactList.getSelectedIndex() >= 0)
- newContactField.setText("");
+ int clickCount = evt.getClickCount();
+
+ if (clickCount > 1)
+ {
+ okButton.doClick();
+ }
}
});
+ // By default we set the current filter to be the presence filter.
JScrollPane contactListScrollPane = new JScrollPane();
contactListScrollPane.setOpaque(false);
contactListScrollPane.getViewport().setOpaque(false);
- contactListScrollPane.getViewport().add(contactList);
+ contactListScrollPane.getViewport().add(contactList.getComponent());
contactListScrollPane.getViewport().setBorder(null);
contactListScrollPane.setViewportBorder(null);
contactListScrollPane.setBorder(null);
return contactListScrollPane;
}
+
+ /**
+ * Adds the given contact to this contact list.
+ *
+ * @param contact
+ */
+ protected void addContact(UIContact contact)
+ {
+ contactList.addContact(contact, null, true, false);
+ }
+
+ /**
+ * Called when the ENTER key was typed when this container was the focused
+ * container. Performs the appropriate actions depending on the current
+ * state of the contained contact list.
+ */
+ public void enterKeyTyped()
+ {
+ UIContact selectedContact = contactList.getSelectedContact();
+
+ if (selectedContact != null)
+ {
+ okButton.doClick();
+ }
+ }
+
+ /**
+ * Called when the CTRL-ENTER or CMD-ENTER keys were typed when this
+ * container was the focused container. Performs the appropriate actions
+ * depending on the current state of the contained contact list.
+ */
+ public void ctrlEnterKeyTyped() {}
}
diff --git a/src/net/java/sip/communicator/impl/ldap/LdapContactSourceService.java b/src/net/java/sip/communicator/impl/ldap/LdapContactSourceService.java
index 1ca8bca..dd90821 100644
--- a/src/net/java/sip/communicator/impl/ldap/LdapContactSourceService.java
+++ b/src/net/java/sip/communicator/impl/ldap/LdapContactSourceService.java
@@ -114,9 +114,9 @@ public class LdapContactSourceService
* should be returned by all call history implementations of this interface)
* @return the identifier of this contact source
*/
- public String getIdentifier()
+ public int getType()
{
- return "LDAP";
+ return SEARCH_TYPE;
}
/**
@@ -205,4 +205,14 @@ public class LdapContactSourceService
queries.notify();
}
}
+
+ /**
+ * Returns the index of the contact source in the result list.
+ *
+ * @return the index of the contact source in the result list
+ */
+ public int getIndex()
+ {
+ return -1;
+ }
}
diff --git a/src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java b/src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java
index a07678e..8aaad0f 100644
--- a/src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java
+++ b/src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java
@@ -141,6 +141,47 @@ public class MockProvider
}
/**
+ * Returns a collection containing all operation sets classes supported by
+ * the current implementation. When querying this method users must be
+ * prepared to receive any subset of the OperationSet-s defined by this
+ * service. They MUST ignore any OperationSet-s that they are not aware of
+ * and that may be defined by future versions of this service. Such
+ * "unknown" OperationSet-s though not encouraged, may also be defined by
+ * service implementors.
+ *
+ * @return a {@link Collection} containing instances of all supported
+ * operation set classes (e.g. <tt>OperationSetPresence.class</tt>.
+ */
+ @SuppressWarnings("unchecked")
+ public Collection<Class<? extends OperationSet>>
+ getSupportedOperationSetClasses()
+ {
+ Collection<Class<? extends OperationSet>> opSetClasses
+ = new ArrayList<Class<? extends OperationSet>>();
+
+ Iterator<String> opSets
+ = getSupportedOperationSets().keySet().iterator();
+
+ while (opSets.hasNext())
+ {
+ String opSetClassName = opSets.next();
+ try
+ {
+ opSetClasses.add(
+ (Class<? extends OperationSet>) getSupportedOperationSets()
+ .get(opSetClassName).getClass().getClassLoader()
+ .loadClass(opSetClassName));
+ }
+ catch (ClassNotFoundException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ return opSetClasses;
+ }
+
+ /**
* Returns the operation set corresponding to the specified class or null
* if this operation set is not supported by the provider implementation.
*
diff --git a/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactSourceService.java b/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactSourceService.java
index 26c3857..1e75e7e 100644
--- a/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactSourceService.java
+++ b/src/net/java/sip/communicator/plugin/addrbook/macosx/MacOSXAddrBookContactSourceService.java
@@ -65,11 +65,11 @@ public class MacOSXAddrBookContactSourceService
*
* @return a <tt>String</tt> which uniquely identifies the instances of the
* <tt>MacOSXAddrBookContactSourceService</tt> implementation
- * @see ContactSourceService#getIdentifier()
+ * @see ContactSourceService#getType()
*/
- public String getIdentifier()
+ public int getType()
{
- return "MacOSXAddressBook";
+ return SEARCH_TYPE;
}
/**
@@ -129,6 +129,16 @@ public class MacOSXAddrBookContactSourceService
}
/**
+ * Returns the index of the contact source in the result list.
+ *
+ * @return the index of the contact source in the result list
+ */
+ public int getIndex()
+ {
+ return -1;
+ }
+
+ /**
* Stops a native <tt>MacOSXAddrBookContactSourceService</tt>.
*
* @param ptr the pointer to the native
diff --git a/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactSourceService.java b/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactSourceService.java
index f94dac5..1f270ac 100644
--- a/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactSourceService.java
+++ b/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactSourceService.java
@@ -93,11 +93,11 @@ public class MsOutlookAddrBookContactSourceService
*
* @return a <tt>String</tt> which uniquely identifies the instances of the
* <tt>MsOutlookAddrBookContactSourceService</tt> implementation
- * @see ContactSourceService#getIdentifier()
+ * @see ContactSourceService#getType()
*/
- public String getIdentifier()
+ public int getType()
{
- return "MsOutlookAddressBook";
+ return SEARCH_TYPE;
}
private static native void MAPIInitialize(long version, long flags)
@@ -206,4 +206,14 @@ public class MsOutlookAddrBookContactSourceService
queries.notify();
}
}
+
+ /**
+ * Returns the index of the contact source in the result list.
+ *
+ * @return the index of the contact source in the result list
+ */
+ public int getIndex()
+ {
+ return -1;
+ }
}
diff --git a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PNContactSourceActivator.java b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PNContactSourceActivator.java
new file mode 100644
index 0000000..90657e5
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PNContactSourceActivator.java
@@ -0,0 +1,217 @@
+/*
+ * 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.plugin.phonenumbercontactsource;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.resources.*;
+import org.osgi.framework.*;
+
+/**
+ * The activator for the phone number contact source bundle.
+ *
+ * @author Yana Stamcheva
+ */
+public class PNContactSourceActivator
+ implements BundleActivator
+{
+ /**
+ * The <tt>Logger</tt> used by the
+ * <tt>PNContactSourceActivator</tt> class for logging output.
+ */
+ private static final Logger logger
+ = Logger.getLogger(PNContactSourceActivator.class);
+
+ /**
+ * The bundle context.
+ */
+ static BundleContext bundleContext = null;
+
+ /**
+ * Providers of contact info.
+ */
+ private static List<ProtocolProviderService> phoneProviders;
+
+ /**
+ * The contact source.
+ */
+ private static final PhoneNumberContactSource phoneNumberContactSource
+ = new PhoneNumberContactSource();
+
+ /**
+ * The resource service.
+ */
+ private static ResourceManagementService resources = null;
+
+ /**
+ * Starts this bundle.
+ *
+ * @param context the bundle context where we register and obtain services.
+ */
+ public void start(BundleContext context) throws Exception
+ {
+ bundleContext = context;
+
+ bundleContext.registerService(
+ ContactSourceService.class.getName(),
+ phoneNumberContactSource,
+ null);
+ }
+
+ public void stop(BundleContext context) throws Exception
+ {
+ }
+
+ /**
+ * Returns a reference to the ResourceManagementService implementation
+ * currently registered in the bundle context or null if no such
+ * implementation was found.
+ *
+ * @return a reference to a ResourceManagementService implementation
+ * currently registered in the bundle context or null if no such
+ * implementation was found.
+ */
+ public static ResourceManagementService getResources()
+ {
+ if (resources == null)
+ {
+ resources
+ = ServiceUtils.getService(
+ bundleContext, ResourceManagementService.class);
+ }
+ return resources;
+ }
+
+ /**
+ * Returns a list of all currently registered server stored contact info
+ * providers.
+ *
+ * @return a list of all currently registered server stored contact info
+ * providers
+ */
+ public static List<ProtocolProviderService> getPhoneNumberProviders()
+ {
+ if (phoneProviders != null)
+ return phoneProviders;
+
+ phoneProviders = new LinkedList<ProtocolProviderService>();
+
+ bundleContext.addServiceListener(new ProtocolProviderRegListener());
+
+ ServiceReference[] serRefs = null;
+ try
+ {
+ // get all registered provider factories
+ serRefs
+ = bundleContext.getServiceReferences(
+ ProtocolProviderFactory.class.getName(),
+ null);
+ }
+ catch (InvalidSyntaxException e)
+ {
+ logger.error("LoginManager : " + e);
+ }
+
+ if (serRefs != null)
+ {
+ for (ServiceReference serRef : serRefs)
+ {
+ ProtocolProviderFactory providerFactory
+ = (ProtocolProviderFactory)
+ bundleContext.getService(serRef);
+
+ ProtocolProviderService protocolProvider;
+
+ for (AccountID accountID
+ : providerFactory.getRegisteredAccounts())
+ {
+ serRef = providerFactory.getProviderForAccount(accountID);
+
+ protocolProvider
+ = (ProtocolProviderService) bundleContext
+ .getService(serRef);
+
+ handleProviderAdded(protocolProvider);
+ }
+ }
+ }
+ return phoneProviders;
+ }
+
+ /**
+ * Listens for <tt>ProtocolProviderService</tt> registrations.
+ */
+ private static class ProtocolProviderRegListener
+ implements ServiceListener
+ {
+ public void serviceChanged(ServiceEvent event)
+ {
+ ServiceReference serviceRef = event.getServiceReference();
+
+ // if the event is caused by a bundle being stopped, we don't want to
+ // know
+ if (serviceRef.getBundle().getState() == Bundle.STOPPING)
+ {
+ return;
+ }
+
+ Object service = bundleContext.getService(serviceRef);
+
+ // we don't care if the source service is not a protocol provider
+ if (!(service instanceof ProtocolProviderService))
+ {
+ return;
+ }
+
+ switch (event.getType())
+ {
+ case ServiceEvent.REGISTERED:
+ handleProviderAdded((ProtocolProviderService) service);
+ break;
+ case ServiceEvent.UNREGISTERING:
+ handleProviderRemoved((ProtocolProviderService) service);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Handles the registration of a new <tt>ProtocolProviderService</tt>. Adds
+ * the given <tt>protocolProvider</tt> to the list of queried providers.
+ *
+ * @param protocolProvider the <tt>ProtocolProviderService</tt> to add
+ */
+ private static void handleProviderAdded(
+ ProtocolProviderService protocolProvider)
+ {
+ if (protocolProvider.getOperationSet(
+ OperationSetServerStoredContactInfo.class) != null
+ && protocolProvider.isRegistered()
+ && !phoneProviders.contains(protocolProvider))
+ {
+ phoneProviders.add(protocolProvider);
+ }
+ }
+
+ /**
+ * Handles the un-registration of a <tt>ProtocolProviderService</tt>.
+ * Removes the given <tt>protocolProvider</tt> from the list of queried
+ * providers.
+ *
+ * @param protocolProvider the <tt>ProtocolProviderService</tt> to remove
+ */
+ private static void handleProviderRemoved(
+ ProtocolProviderService protocolProvider)
+ {
+ if (phoneProviders.contains(protocolProvider))
+ phoneProviders.remove(protocolProvider);
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactQuery.java b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactQuery.java
new file mode 100644
index 0000000..e65ba51
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactQuery.java
@@ -0,0 +1,228 @@
+/*
+ * 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.plugin.phonenumbercontactsource;
+
+import java.util.*;
+import java.util.regex.*;
+
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.ServerStoredDetails.*;
+
+/**
+ * The <tt>PhoneNumberContactQuery</tt> is a query over the
+ * <tt>PhoneNumberContactSource</tt>.
+ *
+ * @author Yana Stamcheva
+ */
+public class PhoneNumberContactQuery
+ extends AsyncContactQuery<PhoneNumberContactSource>
+{
+ /**
+ * The query string.
+ */
+ private String queryString;
+
+ /**
+ * The contact count.
+ */
+ private int contactCount;
+
+ /**
+ * Creates an instance of <tt>PhoneNumberContactQuery</tt> by specifying
+ * the parent contact source, the query string to match and the maximum
+ * result contacts to return.
+ *
+ * @param contactSource the parent contact source
+ * @param queryString the query string to match
+ * @param contactCount the maximum result contact count
+ */
+ public PhoneNumberContactQuery( PhoneNumberContactSource contactSource,
+ String queryString,
+ int contactCount)
+ {
+ super(contactSource,
+ Pattern.compile(queryString, Pattern.CASE_INSENSITIVE
+ | Pattern.LITERAL));
+
+ this.queryString = queryString;
+ this.contactCount = contactCount;
+ }
+
+ /**
+ * Do all the work in different thread.
+ */
+ public void run()
+ {
+ Iterator<ProtocolProviderService> providers
+ = PNContactSourceActivator
+ .getPhoneNumberProviders().iterator();
+
+ while (providers.hasNext())
+ {
+ if(contactCount > 0 && getQueryResultCount() > contactCount)
+ break;
+
+ ProtocolProviderService provider = providers.next();
+
+ OperationSetPersistentPresence persPresOpSet
+ = provider.getOperationSet(
+ OperationSetPersistentPresence.class);
+
+ // If there's no presence operation set continue to the
+ // next protocol provider.
+ if (persPresOpSet == null)
+ continue;
+
+ ContactGroup rootGroup
+ = persPresOpSet.getServerStoredContactListRoot();
+
+ addResultContactsForGroup(rootGroup);
+
+ Iterator<ContactGroup> subgroups = rootGroup.subgroups();
+
+ while (subgroups.hasNext())
+ {
+ ContactGroup group = subgroups.next();
+
+ addResultContactsForGroup(group);
+ }
+ }
+
+ if (getStatus() != QUERY_CANCELED)
+ setStatus(QUERY_COMPLETED);
+ }
+
+ /**
+ * Adss the result contacts for the given group.
+ *
+ * @param group the <tt>ContactGroup</tt> to check for matching contacts
+ */
+ private void addResultContactsForGroup(ContactGroup group)
+ {
+ Iterator<Contact> contacts = group.contacts();
+ while (contacts.hasNext())
+ {
+ if(contactCount > 0 && getQueryResultCount() > contactCount)
+ break;
+
+ Contact contact = contacts.next();
+
+ addAdditionalNumbers(contact);
+ }
+ }
+
+ /**
+ * Returns all additional phone numbers corresponding to the given
+ * contact.
+ *
+ * @param contact the <tt>contact</tt>, which phone details we're
+ * looking for
+ * @return a list of all additional phone numbers corresponding to the
+ * given contact
+ */
+ private void addAdditionalNumbers(Contact contact)
+ {
+ OperationSetServerStoredContactInfo infoOpSet
+ = contact.getProtocolProvider().getOperationSet(
+ OperationSetServerStoredContactInfo.class);
+
+ Iterator<GenericDetail> details;
+
+ if(infoOpSet != null)
+ {
+ details = infoOpSet.getAllDetailsForContact(contact);
+
+ while(details.hasNext())
+ {
+ if(contactCount > 0 && getQueryResultCount() > contactCount)
+ break;
+
+ GenericDetail d = details.next();
+ if(d instanceof PhoneNumberDetail &&
+ !(d instanceof PagerDetail) &&
+ !(d instanceof FaxDetail))
+ {
+ PhoneNumberDetail pnd = (PhoneNumberDetail)d;
+ if(pnd.getNumber() != null &&
+ pnd.getNumber().length() > 0)
+ {
+ String localizedType = null;
+
+ if(d instanceof WorkPhoneDetail)
+ {
+ localizedType =
+ PNContactSourceActivator.getResources()
+ .getI18NString("service.gui.WORK_PHONE");
+ }
+ else if(d instanceof MobilePhoneDetail)
+ {
+ localizedType =
+ PNContactSourceActivator.getResources()
+ .getI18NString("service.gui.MOBILE_PHONE");
+ }
+ else
+ {
+ localizedType =
+ PNContactSourceActivator.getResources()
+ .getI18NString("service.gui.PHONE");
+ }
+
+ String contactName = contact.getDisplayName();
+ String contactAddress = contact.getAddress();
+ String numberString = pnd.getNumber();
+
+ if(queryString == null
+ || (queryString != null
+ && (numberString.startsWith(
+ queryString)
+ || contactName.startsWith(queryString)
+ || contactAddress.startsWith(queryString)
+ )))
+ {
+ ArrayList<ContactDetail> contactDetails
+ = new ArrayList<ContactDetail>();
+
+ ContactDetail detail
+ = new ContactDetail(pnd.getNumber());
+ ArrayList<Class<? extends OperationSet>>
+ supportedOpSets
+ = new ArrayList<Class<? extends OperationSet>>();
+ supportedOpSets
+ .add(OperationSetBasicTelephony.class);
+ detail.setSupportedOpSets(supportedOpSets);
+
+ contactDetails.add(detail);
+
+ PhoneNumberSourceContact numberSourceContact
+ = new PhoneNumberSourceContact(
+ getContactSource(),
+ contact,
+ contactDetails,
+ pnd.getNumber()
+ + "(" + localizedType + ")");
+
+ addQueryResult(numberSourceContact);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ protected String normalizePhoneNumber(String phoneNumber)
+ {
+ return null;
+ }
+
+ @Override
+ protected boolean phoneNumberMatches(String phoneNumber)
+ {
+ return false;
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java
new file mode 100644
index 0000000..a5c662e
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java
@@ -0,0 +1,114 @@
+/*
+ * 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.plugin.phonenumbercontactsource;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.contactsource.*;
+
+/**
+ * The <tt>PhoneNumberContactSource</tt> is a source of phone numbers coming
+ * from the server stored contact info of all contacts for all protocol
+ * providers.
+ *
+ * @author Yana Stamcheva
+ */
+public class PhoneNumberContactSource
+ implements ContactSourceService
+{
+ /**
+ * The <tt>List</tt> of <tt>PhoneNumberContactQuery</tt> instances
+ * which have been started and haven't stopped yet.
+ */
+ private final List<PhoneNumberContactQuery> queries
+ = new LinkedList<PhoneNumberContactQuery>();
+
+ /**
+ * Returns DEFAULT_TYPE to indicate that this contact source is a default
+ * source.
+ *
+ * @return the type of this contact source
+ */
+ public int getType()
+ {
+ return DEFAULT_TYPE;
+ }
+
+ /**
+ * Returns a user-friendly string that identifies this contact source.
+ *
+ * @return the display name of this contact source
+ */
+ public String getDisplayName()
+ {
+ return PNContactSourceActivator.getResources().getI18NString(
+ "plugin.phonenumbercontactsource.DISPLAY_NAME");
+ }
+
+ /**
+ * Queries this contact source for the given <tt>queryString</tt>.
+ *
+ * @param queryString the string to search for
+ * @return the created query
+ */
+ public ContactQuery queryContactSource(String queryString)
+ {
+ return queryContactSource(queryString, -1);
+ }
+
+ /**
+ * Queries this contact source for the given <tt>queryString</tt>.
+ *
+ * @param queryString the string to search for
+ * @param contactCount the maximum count of result contacts
+ * @return the created query
+ */
+ public ContactQuery queryContactSource( String queryString,
+ int contactCount)
+ {
+ if (queryString == null)
+ queryString = "";
+
+ PhoneNumberContactQuery contactQuery
+ = new PhoneNumberContactQuery(this, queryString, contactCount);
+
+ synchronized (queries)
+ {
+ queries.add(contactQuery);
+ }
+
+ boolean queryHasStarted = false;
+
+ try
+ {
+ contactQuery.start();
+ queryHasStarted = true;
+ }
+ finally
+ {
+ if (!queryHasStarted)
+ {
+ synchronized (queries)
+ {
+ if (queries.remove(contactQuery))
+ queries.notify();
+ }
+ }
+ }
+ return contactQuery;
+ }
+
+ /**
+ * Returns the index of the contact source in the result list.
+ *
+ * @return the index of the contact source in the result list
+ */
+ public int getIndex()
+ {
+ return -1;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberSourceContact.java b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberSourceContact.java
new file mode 100644
index 0000000..00943f3
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberSourceContact.java
@@ -0,0 +1,85 @@
+/*
+ * 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.plugin.phonenumbercontactsource;
+
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.protocol.*;
+
+import java.util.*;
+
+/**
+ * The <tt>PhoneNumberSourceContact</tt> extends the
+ * <tt>GenericSourceContact</tt> and represents a contact in the
+ * <tt>PhoneNumberContactSource</tt>.
+ *
+ * @author Yana Stamcheva
+ */
+public class PhoneNumberSourceContact
+ extends GenericSourceContact
+{
+ /**
+ * The display details of this contact.
+ */
+ private String displayDetails;
+
+ /**
+ * Creates an instance of <tt>PhoneNumberSourceContact</tt>.
+ *
+ * @param contactSource the parent contact source
+ * @param contact the protocol contact corresponding to this source contact
+ * information about the phone number corresponding to this source contact
+ * @param detailDisplayName the display name of the phone number detail
+ */
+ public PhoneNumberSourceContact(PhoneNumberContactSource contactSource,
+ Contact contact,
+ List<ContactDetail> contactDetails,
+ String detailDisplayName)
+ {
+ super( contactSource,
+ contact.getDisplayName(),
+ contactDetails);
+
+ displayDetails = detailDisplayName;
+ }
+
+ /**
+ * Returns the display details of this search contact. This could be any
+ * important information that should be shown to the user.
+ *
+ * @return the display details of the search contact
+ */
+ public String getDisplayDetails()
+ {
+ return displayDetails;
+ }
+
+ /**
+ * Compares object display names.
+ */
+ @Override
+ public boolean equals(Object o)
+ {
+ if(this == o)
+ return true;
+
+ if(o == null)
+ return false;
+
+ if(o == null || getClass() != o.getClass())
+ return false;
+
+ PhoneNumberSourceContact that = (PhoneNumberSourceContact) o;
+
+ String displayName = getDisplayName();
+ if(displayName != null ?
+ !displayName.equals(that.getDisplayName())
+ : that.getDisplayName() != null)
+ return false;
+
+ return true;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/phonenumbercontactsource.manifest.mf b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/phonenumbercontactsource.manifest.mf
new file mode 100644
index 0000000..ba3c1ff
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/phonenumbercontactsource.manifest.mf
@@ -0,0 +1,12 @@
+Bundle-Activator: net.java.sip.communicator.plugin.phonenumbercontactsource.PNContactSourceActivator
+Bundle-Name: Phone number contact source
+Bundle-Description: Phone number contact source
+Bundle-Vendor: jitsi.org
+Bundle-Version: 0.0.1
+System-Bundle: yes
+Import-Package: org.osgi.framework,
+ net.java.sip.communicator.service.contactsource,
+ net.java.sip.communicator.service.protocol,
+ net.java.sip.communicator.service.protocol.event,
+ net.java.sip.communicator.util,
+ org.jitsi.service.resources \ No newline at end of file
diff --git a/src/net/java/sip/communicator/service/contactsource/AsyncContactQuery.java b/src/net/java/sip/communicator/service/contactsource/AsyncContactQuery.java
index 20b06bb..aed89b3 100644
--- a/src/net/java/sip/communicator/service/contactsource/AsyncContactQuery.java
+++ b/src/net/java/sip/communicator/service/contactsource/AsyncContactQuery.java
@@ -88,6 +88,7 @@ public abstract class AsyncContactQuery<T extends ContactSourceService>
}
if (changed)
fireContactReceived(sourceContact);
+
return changed;
}
diff --git a/src/net/java/sip/communicator/service/contactsource/ContactDetail.java b/src/net/java/sip/communicator/service/contactsource/ContactDetail.java
index 0de7e69..23e7092 100644
--- a/src/net/java/sip/communicator/service/contactsource/ContactDetail.java
+++ b/src/net/java/sip/communicator/service/contactsource/ContactDetail.java
@@ -315,6 +315,7 @@ public class ContactDetail
* Returns a list of all supported <tt>OperationSet</tt> classes, which
* would indicate what are the supported actions by this contact
* (e.g. write a message, make a call, etc.)
+ *
* @return a list of all supported <tt>OperationSet</tt> classes
*/
public List<Class<? extends OperationSet>> getSupportedOperationSets()
diff --git a/src/net/java/sip/communicator/service/contactsource/ContactSourceService.java b/src/net/java/sip/communicator/service/contactsource/ContactSourceService.java
index 35001c8..0077c47 100644
--- a/src/net/java/sip/communicator/service/contactsource/ContactSourceService.java
+++ b/src/net/java/sip/communicator/service/contactsource/ContactSourceService.java
@@ -16,26 +16,37 @@ package net.java.sip.communicator.service.contactsource;
public interface ContactSourceService
{
/**
- * Constants to identify <tt>ContactSource</tt> in call history.
+ * Type of a default source.
*/
- public static final String CALL_HISTORY = "CallHistory";
+ public static final int DEFAULT_TYPE = 0;
/**
- * Returns the identifier of this contact source. Some of the common
- * identifiers are defined here (For example the CALL_HISTORY identifier
- * should be returned by all call history implementations of this interface)
- * @return the identifier of this contact source
+ * Type of a search source. Queried only when searches are performed.
*/
- public String getIdentifier();
+ public static final int SEARCH_TYPE = 1;
+
+ /**
+ * Type of a history source. Queries only when history should be shown.
+ */
+ public static final int HISTORY_TYPE = 2;
+
+ /**
+ * Returns the type of this contact source.
+ *
+ * @return the type of this contact source
+ */
+ public int getType();
/**
* Returns a user-friendly string that identifies this contact source.
+ *
* @return the display name of this contact source
*/
public String getDisplayName();
/**
* Queries this search source for the given <tt>queryString</tt>.
+ *
* @param queryString the string to search for
* @return the created query
*/
@@ -50,4 +61,11 @@ public interface ContactSourceService
*/
public ContactQuery queryContactSource(String queryString,
int contactCount);
+
+ /**
+ * Returns the index of the contact source in the result list.
+ *
+ * @return the index of the contact source in the result list
+ */
+ public int getIndex();
}
diff --git a/src/net/java/sip/communicator/service/contactsource/GenericSourceContact.java b/src/net/java/sip/communicator/service/contactsource/GenericSourceContact.java
index 4214c16..f2897ab 100644
--- a/src/net/java/sip/communicator/service/contactsource/GenericSourceContact.java
+++ b/src/net/java/sip/communicator/service/contactsource/GenericSourceContact.java
@@ -38,6 +38,16 @@ public class GenericSourceContact
private final String displayName;
/**
+ * The display details of this contact.
+ */
+ private String displayDetails;
+
+ /**
+ * The presence status of this contact.
+ */
+ private PresenceStatus presenceStatus;
+
+ /**
* The image/avatar of this <tt>SourceContact</tt>
*/
private byte[] image;
@@ -139,8 +149,17 @@ public class GenericSourceContact
*/
public String getDisplayDetails()
{
- // TODO Auto-generated method stub
- return null;
+ return displayDetails;
+ }
+
+ /**
+ * Sets the display details of this <tt>SourceContact</tt>.
+ *
+ * @param displayDetails the display details of this <tt>SourceContact</tt>
+ */
+ public String setDisplayDetails(String displayDetails)
+ {
+ return this.displayDetails = displayDetails;
}
/**
@@ -200,6 +219,16 @@ public class GenericSourceContact
*/
public PresenceStatus getPresenceStatus()
{
- return null;
+ return presenceStatus;
+ }
+
+ /**
+ * Sets the status of the source contact.
+ *
+ * @param presenceStatus the status of this contact
+ */
+ public void setPresenceStatus(PresenceStatus presenceStatus)
+ {
+ this.presenceStatus = presenceStatus;
}
}
diff --git a/src/net/java/sip/communicator/service/gui/ContactList.java b/src/net/java/sip/communicator/service/gui/ContactList.java
index 1a448ba..ca57886 100644
--- a/src/net/java/sip/communicator/service/gui/ContactList.java
+++ b/src/net/java/sip/communicator/service/gui/ContactList.java
@@ -8,6 +8,7 @@ package net.java.sip.communicator.service.gui;
import java.awt.*;
import java.util.*;
+import java.util.List;
import net.java.sip.communicator.service.contactsource.*;
import net.java.sip.communicator.service.gui.event.*;
@@ -20,6 +21,8 @@ import net.java.sip.communicator.service.gui.event.*;
* @author Yana Stamcheva
*/
public interface ContactList
+ extends ContactQueryListener,
+ MetaContactQueryListener
{
/**
* Returns the actual component corresponding to the contact list.
@@ -30,6 +33,7 @@ public interface ContactList
/**
* Returns the list of registered contact sources to search in.
+ *
* @return the list of registered contact sources to search in
*/
public Collection<UIContactSource> getContactSources();
@@ -37,6 +41,7 @@ public interface ContactList
/**
* Returns the <tt>ExternalContactSource</tt> corresponding to the given
* <tt>ContactSourceService</tt>.
+ *
* @param contactSource the <tt>ContactSourceService</tt>, which
* corresponding external source implementation we're looking for
* @return the <tt>ExternalContactSource</tt> corresponding to the given
@@ -45,7 +50,49 @@ public interface ContactList
public UIContactSource getContactSource(ContactSourceService contactSource);
/**
+ * Adds the given contact source to the list of available contact sources.
+ *
+ * @param contactSource the <tt>ContactSourceService</tt>
+ */
+ public void addContactSource(ContactSourceService contactSource);
+
+ /**
+ * Removes the given contact source from the list of available contact
+ * sources.
+ *
+ * @param contactSource
+ */
+ public void removeContactSource(ContactSourceService contactSource);
+
+ /**
+ * Removes all stored contact sources.
+ */
+ public void removeAllContactSources();
+
+ /**
+ * Sets the default filter to the given <tt>filter</tt>.
+ * @param filter the <tt>ContactListFilter</tt> to set as default
+ */
+ public void setDefaultFilter(ContactListFilter filter);
+
+ /**
+ * Gets the default filter for this contact list.
+ *
+ * @return the default filter for this contact list
+ */
+ public ContactListFilter getDefaultFilter();
+
+ /**
+ * Returns all <tt>UIContactSource</tt>s of the given type.
+ *
+ * @param type the type of sources we're looking for
+ * @return a list of all <tt>UIContactSource</tt>s of the given type
+ */
+ public List<UIContactSource> getContactSources(int type);
+
+ /**
* Adds the given group to this list.
+ *
* @param group the <tt>UIGroup</tt> to add
* @param isSorted indicates if the contact should be sorted regarding to
* the <tt>GroupNode</tt> policy
@@ -54,12 +101,14 @@ public interface ContactList
/**
* Removes the given group and its children from the list.
+ *
* @param group the <tt>UIGroup</tt> to remove
*/
public void removeGroup(final UIGroup group);
/**
* Adds the given <tt>contact</tt> to this list.
+ *
* @param contact the <tt>UIContact</tt> to add
* @param group the <tt>UIGroup</tt> to add to
* @param isContactSorted indicates if the contact should be sorted
@@ -75,6 +124,7 @@ public interface ContactList
/**
* Adds the given <tt>contact</tt> to this list.
+ *
* @param query the <tt>ContactQuery</tt> that adds the given contact
* @param contact the <tt>UIContact</tt> to add
* @param group the <tt>UIGroup</tt> to add to
@@ -89,6 +139,7 @@ public interface ContactList
/**
* Removes the node corresponding to the given <tt>MetaContact</tt> from
* this list.
+ *
* @param contact the <tt>UIContact</tt> to remove
* @param removeEmptyGroup whether we should delete the group if is empty
*/
@@ -98,18 +149,38 @@ public interface ContactList
/**
* Removes the node corresponding to the given <tt>MetaContact</tt> from
* this list.
+ *
* @param contact the <tt>UIContact</tt> to remove
*/
public void removeContact(UIContact contact);
/**
+ * Returns a collection of all direct child <tt>UIContact</tt>s of the given
+ * <tt>UIGroup</tt>.
+ *
+ * @param group the parent <tt>UIGroup</tt>
+ * @return a collection of all direct child <tt>UIContact</tt>s of the given
+ * <tt>UIGroup</tt>
+ */
+ public Collection<UIContact> getContacts(final UIGroup group);
+
+ /**
* Returns the currently applied filter.
+ *
* @return the currently applied filter
*/
public ContactListFilter getCurrentFilter();
/**
+ * Returns the currently applied filter.
+ *
+ * @return the currently applied filter
+ */
+ public FilterQuery getCurrentFilterQuery();
+
+ /**
* Applies the given <tt>filter</tt>.
+ *
* @param filter the <tt>ContactListFilter</tt> to apply.
* @return the filter query
*/
@@ -117,18 +188,27 @@ public interface ContactList
/**
* Applies the default filter.
+ *
* @return the filter query that keeps track of the filtering results
*/
public FilterQuery applyDefaultFilter();
/**
- * Returns the currently selected <tt>UIContact</tt> if there's one.
+ * Returns the currently selected <tt>UIContact</tt>. In case of a multiple
+ * selection returns the first contact in the selection.
*
* @return the currently selected <tt>UIContact</tt> if there's one.
*/
public UIContact getSelectedContact();
/**
+ * Returns the list of selected contacts.
+ *
+ * @return the list of selected contacts
+ */
+ public List<UIContact> getSelectedContacts();
+
+ /**
* Returns the currently selected <tt>UIGroup</tt> if there's one.
*
* @return the currently selected <tt>UIGroup</tt> if there's one.
@@ -150,6 +230,17 @@ public interface ContactList
public void setSelectedGroup(UIGroup uiGroup);
/**
+ * Selects the first found contact node from the beginning of the contact
+ * list.
+ */
+ public void selectFirstContact();
+
+ /**
+ * Removes the current selection.
+ */
+ public void removeSelection();
+
+ /**
* Adds a listener for <tt>ContactListEvent</tt>s.
*
* @param listener the listener to add
@@ -169,4 +260,44 @@ public interface ContactList
* @param uiContact the contact to refresh
*/
public void refreshContact(UIContact uiContact);
+
+ /**
+ * Indicates if this contact list is empty.
+ *
+ * @return <tt>true</tt> if this contact list contains no children,
+ * otherwise returns <tt>false</tt>
+ */
+ public boolean isEmpty();
+
+ /**
+ * Shows/hides buttons shown in contact row.
+ *
+ * @param isVisible <tt>true</tt> to show contact buttons, <tt>false</tt> -
+ * otherwise.
+ */
+ public void setContactButtonsVisible(boolean isVisible);
+
+ /**
+ * Shows/hides buttons shown in contact row.
+ *
+ * return <tt>true</tt> to indicate that contact buttons are shown,
+ * <tt>false</tt> - otherwise.
+ */
+ public boolean isContactButtonsVisible();
+
+ /**
+ * Enables/disables multiple selection.
+ *
+ * @param isEnabled <tt>true</tt> to enable multiple selection,
+ * <tt>false</tt> - otherwise
+ */
+ public void setMultipleSelectionEnabled(boolean isEnabled);
+
+ /**
+ * Enables/disables drag operations on this contact list.
+ *
+ * @param isEnabled <tt>true</tt> to enable drag operations, <tt>false</tt>
+ * otherwise
+ */
+ public void setDragEnabled(boolean isEnabled);
}
diff --git a/src/net/java/sip/communicator/service/gui/ContactListContainer.java b/src/net/java/sip/communicator/service/gui/ContactListContainer.java
new file mode 100644
index 0000000..41746da
--- /dev/null
+++ b/src/net/java/sip/communicator/service/gui/ContactListContainer.java
@@ -0,0 +1,39 @@
+/*
+ * 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.gui;
+
+/**
+ * The <tt>ContactListContainer</tt> is a container of a <tt>ContactList</tt>
+ * component.
+ *
+ * @author Yana Stamcheva
+ */
+public interface ContactListContainer
+{
+ /**
+ * Called when the ENTER key was typed when this container was the focused
+ * container. Performs the appropriate actions depending on the current
+ * state of the contained contact list.
+ */
+ public void enterKeyTyped();
+
+ /**
+ * Called when the CTRL-ENTER or CMD-ENTER keys were typed when this
+ * container was the focused container. Performs the appropriate actions
+ * depending on the current state of the contained contact list.
+ */
+ public void ctrlEnterKeyTyped();
+
+ /**
+ * Returns <tt>true</tt> if this contact list container has the focus,
+ * otherwise returns <tt>false</tt>.
+ *
+ * @return <tt>true</tt> if this contact list container has the focus,
+ * otherwise returns <tt>false</tt>
+ */
+ public boolean isFocused();
+}
diff --git a/src/net/java/sip/communicator/service/gui/ContactListSearchFilter.java b/src/net/java/sip/communicator/service/gui/ContactListSearchFilter.java
new file mode 100644
index 0000000..7f2db25
--- /dev/null
+++ b/src/net/java/sip/communicator/service/gui/ContactListSearchFilter.java
@@ -0,0 +1,22 @@
+/*
+ * 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.gui;
+
+/**
+ * The <tt>ContactListSearchFilter</tt> is a <tt>ContactListFilter</tt> specific
+ * for string search.
+ */
+public interface ContactListSearchFilter
+ extends ContactListFilter
+{
+ /**
+ * Creates the <tt>SearchFilter</tt> by specifying the string used for
+ * filtering.
+ * @param filter the String used for filtering
+ */
+ public void setFilterString(String filter);
+}
diff --git a/src/net/java/sip/communicator/service/gui/FilterQuery.java b/src/net/java/sip/communicator/service/gui/FilterQuery.java
index 7b2cda9..ad5fd0a 100644
--- a/src/net/java/sip/communicator/service/gui/FilterQuery.java
+++ b/src/net/java/sip/communicator/service/gui/FilterQuery.java
@@ -17,6 +17,11 @@ import net.java.sip.communicator.service.gui.event.*;
public abstract class FilterQuery
{
/**
+ * The maximum result count for each contact source.
+ */
+ private int maxResultCount = 10;
+
+ /**
* A listener, which is notified when this query finishes.
*/
private FilterQueryListener filterQueryListener;
@@ -47,6 +52,13 @@ public abstract class FilterQuery
public abstract boolean isCanceled();
/**
+ * Indicates if this query is canceled.
+ *
+ * @return <tt>true</tt> if this query is canceled, <tt>false</tt> otherwise
+ */
+ public abstract boolean isRunning();
+
+ /**
* Cancels this filter query.
*/
public abstract void cancel();
@@ -81,4 +93,25 @@ public abstract class FilterQuery
* filter query, <tt>false</tt> - otherwise
*/
public abstract boolean containsQuery(Object query);
+
+
+ /**
+ * Sets the maximum result count shown.
+ *
+ * @param resultCount the maximum result count shown
+ */
+ public void setMaxResultShown(int resultCount)
+ {
+ this.maxResultCount = resultCount;
+ }
+
+ /**
+ * Gets the maximum result count shown.
+ *
+ * @return the maximum result count shown
+ */
+ public int getMaxResultShown()
+ {
+ return maxResultCount;
+ }
}
diff --git a/src/net/java/sip/communicator/service/gui/UIContactDetail.java b/src/net/java/sip/communicator/service/gui/UIContactDetail.java
index 88f8a8e..6ae1182 100644
--- a/src/net/java/sip/communicator/service/gui/UIContactDetail.java
+++ b/src/net/java/sip/communicator/service/gui/UIContactDetail.java
@@ -37,13 +37,14 @@ public abstract class UIContactDetail
/**
* The <tt>ProtocolProviderService</tt> corresponding to this detail.
*/
- private final ProtocolProviderService protocolProvider;
+ private Map<Class<? extends OperationSet>, ProtocolProviderService>
+ preferredProviders;
/**
* The protocol to be used for this contact detail if no protocol provider
* is set.
*/
- private final String preferredProtocol;
+ private Map<Class<? extends OperationSet>, String> preferredProtocols;
/**
* The collection of labels associated with this detail.
@@ -63,6 +64,29 @@ public abstract class UIContactDetail
/**
* Creates a <tt>UIContactDetail</tt> by specifying the contact
* <tt>address</tt>, the <tt>displayName</tt> and <tt>preferredProvider</tt>.
+ *
+ * @param address the contact address
+ * @param displayName the contact display name
+ * @param descriptor the underlying object that this class is wrapping
+ */
+ public UIContactDetail(
+ String address,
+ String displayName,
+ Object descriptor)
+ {
+ this( address,
+ displayName,
+ null,
+ null,
+ null,
+ null,
+ descriptor);
+ }
+
+ /**
+ * Creates a <tt>UIContactDetail</tt> by specifying the contact
+ * <tt>address</tt>, the <tt>displayName</tt> and <tt>preferredProvider</tt>.
+ *
* @param address the contact address
* @param displayName the contact display name
* @param category the category of the underlying contact detail
@@ -78,16 +102,17 @@ public abstract class UIContactDetail
String displayName,
String category,
Collection<String> labels,
- ProtocolProviderService preferredProvider,
- String preferredProtocol,
+ Map<Class<? extends OperationSet>, ProtocolProviderService>
+ preferredProviders,
+ Map<Class<? extends OperationSet>, String> preferredProtocols,
Object descriptor)
{
this.address = address;
this.displayName = displayName;
this.category = category;
this.labels = labels;
- this.protocolProvider = preferredProvider;
- this.preferredProtocol = preferredProtocol;
+ this.preferredProviders = preferredProviders;
+ this.preferredProtocols = preferredProtocols;
this.descriptor = descriptor;
}
@@ -147,7 +172,25 @@ public abstract class UIContactDetail
public ProtocolProviderService getPreferredProtocolProvider(
Class<? extends OperationSet> opSetClass)
{
- return protocolProvider;
+ return preferredProviders.get(opSetClass);
+ }
+
+ /**
+ * Adds a preferred protocol provider for a given OperationSet class.
+ *
+ * @param opSetClass the <tt>OperationSet</tt> class for which we're looking
+ * for protocol
+ * @param protocol the preferred protocol provider to add
+ */
+ public void addPreferredProtocolProvider(
+ Class<? extends OperationSet> opSetClass,
+ ProtocolProviderService protocolProvider)
+ {
+ if (preferredProviders == null)
+ preferredProviders = new HashMap< Class<? extends OperationSet>,
+ ProtocolProviderService>();
+
+ preferredProviders.put(opSetClass, protocolProvider);
}
/**
@@ -160,7 +203,25 @@ public abstract class UIContactDetail
*/
public String getPreferredProtocol(Class<? extends OperationSet> opSetClass)
{
- return preferredProtocol;
+ return preferredProtocols.get(opSetClass);
+ }
+
+ /**
+ * Adds a preferred protocol for a given OperationSet class.
+ *
+ * @param opSetClass the <tt>OperationSet</tt> class for which we're looking
+ * for protocol
+ * @param protocol the preferred protocol to add
+ */
+ public void addPreferredProtocol(
+ Class<? extends OperationSet> opSetClass,
+ String protocol)
+ {
+ if (preferredProtocols == null)
+ preferredProtocols = new HashMap< Class<? extends OperationSet>,
+ String>();
+
+ preferredProtocols.put(opSetClass, protocol);
}
/**
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactQuery.java b/src/net/java/sip/communicator/service/gui/event/MetaContactQuery.java
index caeae4b..9af6ff1 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactQuery.java
+++ b/src/net/java/sip/communicator/service/gui/event/MetaContactQuery.java
@@ -4,7 +4,7 @@
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
-package net.java.sip.communicator.impl.gui.main.contactlist.contactsource;
+package net.java.sip.communicator.service.gui.event;
import java.util.*;
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactQueryEvent.java b/src/net/java/sip/communicator/service/gui/event/MetaContactQueryEvent.java
index 44c143c..2e8bf2e 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactQueryEvent.java
+++ b/src/net/java/sip/communicator/service/gui/event/MetaContactQueryEvent.java
@@ -4,7 +4,7 @@
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
-package net.java.sip.communicator.impl.gui.main.contactlist.contactsource;
+package net.java.sip.communicator.service.gui.event;
import java.util.*;
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactQueryListener.java b/src/net/java/sip/communicator/service/gui/event/MetaContactQueryListener.java
index 7994810..a8f5ee4 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactQueryListener.java
+++ b/src/net/java/sip/communicator/service/gui/event/MetaContactQueryListener.java
@@ -4,7 +4,7 @@
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
-package net.java.sip.communicator.impl.gui.main.contactlist.contactsource;
+package net.java.sip.communicator.service.gui.event;
/**
* The <tt>MetaContactQueryListener</tt> listens for events coming from a
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactQueryStatusEvent.java b/src/net/java/sip/communicator/service/gui/event/MetaContactQueryStatusEvent.java
index d0c8854..9d06713 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaContactQueryStatusEvent.java
+++ b/src/net/java/sip/communicator/service/gui/event/MetaContactQueryStatusEvent.java
@@ -4,7 +4,7 @@
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
-package net.java.sip.communicator.impl.gui.main.contactlist.contactsource;
+package net.java.sip.communicator.service.gui.event;
import java.util.*;
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaGroupQueryEvent.java b/src/net/java/sip/communicator/service/gui/event/MetaGroupQueryEvent.java
index 500eebf..546c8f9 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaGroupQueryEvent.java
+++ b/src/net/java/sip/communicator/service/gui/event/MetaGroupQueryEvent.java
@@ -4,7 +4,7 @@
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
-package net.java.sip.communicator.impl.gui.main.contactlist.contactsource;
+package net.java.sip.communicator.service.gui.event;
import java.util.*;
diff --git a/src/net/java/sip/communicator/service/gui/gui.manifest.mf b/src/net/java/sip/communicator/service/gui/gui.manifest.mf
index 0708371..1797cf6 100644
--- a/src/net/java/sip/communicator/service/gui/gui.manifest.mf
+++ b/src/net/java/sip/communicator/service/gui/gui.manifest.mf
@@ -7,7 +7,10 @@ System-Bundle: yes
Import-Package: org.osgi.framework,
org.jitsi.service.resources,
net.java.sip.communicator.service.resources,
- net.java.sip.communicator.util
+ net.java.sip.communicator.util,
+ net.java.sip.communicator.service.contactsource,
+ net.java.sip.communicator.service.contactlist,
+ net.java.sip.communicator.service.protocol
Export-Package: net.java.sip.communicator.service.gui,
net.java.sip.communicator.service.gui.event,
net.java.sip.communicator.service.shutdown
diff --git a/src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java b/src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java
index a4423f5..a78ea45 100644
--- a/src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java
+++ b/src/net/java/sip/communicator/service/protocol/AbstractProtocolProviderService.java
@@ -211,6 +211,48 @@ public abstract class AbstractProtocolProviderService
return new Hashtable<String, OperationSet>(supportedOperationSets);
}
+
+ /**
+ * Returns a collection containing all operation sets classes supported by
+ * the current implementation. When querying this method users must be
+ * prepared to receive any subset of the OperationSet-s defined by this
+ * service. They MUST ignore any OperationSet-s that they are not aware of
+ * and that may be defined by future versions of this service. Such
+ * "unknown" OperationSet-s though not encouraged, may also be defined by
+ * service implementors.
+ *
+ * @return a {@link Collection} containing instances of all supported
+ * operation set classes (e.g. <tt>OperationSetPresence.class</tt>.
+ */
+ @SuppressWarnings("unchecked")
+ public Collection<Class<? extends OperationSet>>
+ getSupportedOperationSetClasses()
+ {
+ Collection<Class<? extends OperationSet>> opSetClasses
+ = new ArrayList<Class<? extends OperationSet>>();
+
+ Iterator<String> opSets
+ = getSupportedOperationSets().keySet().iterator();
+
+ while (opSets.hasNext())
+ {
+ String opSetClassName = opSets.next();
+ try
+ {
+ opSetClasses.add(
+ (Class<? extends OperationSet>) getSupportedOperationSets()
+ .get(opSetClassName).getClass().getClassLoader()
+ .loadClass(opSetClassName));
+ }
+ catch (ClassNotFoundException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ return opSetClasses;
+ }
+
/**
* Indicates whether or not this provider is registered
*
diff --git a/src/net/java/sip/communicator/service/protocol/ProtocolProviderService.java b/src/net/java/sip/communicator/service/protocol/ProtocolProviderService.java
index caf053d..d3d4b53 100644
--- a/src/net/java/sip/communicator/service/protocol/ProtocolProviderService.java
+++ b/src/net/java/sip/communicator/service/protocol/ProtocolProviderService.java
@@ -146,6 +146,21 @@ public interface ProtocolProviderService
public Map<String, OperationSet> getSupportedOperationSets();
/**
+ * Returns a collection containing all operation sets classes supported by
+ * the current implementation. When querying this method users must be
+ * prepared to receive any subset of the OperationSet-s defined by this
+ * service. They MUST ignore any OperationSet-s that they are not aware of
+ * and that may be defined by future versions of this service. Such
+ * "unknown" OperationSet-s though not encouraged, may also be defined by
+ * service implementors.
+ *
+ * @return a {@link Collection} containing instances of all supported
+ * operation set classes (e.g. <tt>OperationSetPresence.class</tt>.
+ */
+ public Collection<Class<? extends OperationSet>>
+ getSupportedOperationSetClasses();
+
+ /**
* Returns the operation set corresponding to the specified class or
* <tt>null</tt> if this operation set is not supported by the provider
* implementation.