Results from a MetaContactList filtering are now returned as events.

cusax-fix
Yana Stamcheva 16 years ago
parent 8bd683d875
commit e59acc9770

@ -44,7 +44,7 @@ public ContactQuery queryContactSource(String queryString)
if (queryString != null && queryString.length() > 0)
return new CallHistoryContactQuery(
CallHistoryActivator.getCallHistoryService()
.findByPeer(queryString, 100));
.findByPeer(queryString, 50));
else
return new CallHistoryContactQuery(
CallHistoryActivator.getCallHistoryService()

@ -19,20 +19,13 @@
* @author Yana Stamcheva
*/
public class CallHistoryFilter
implements ContactListFilter,
ContactQueryListener
implements ContactListFilter
{
/**
* This class logger.
*/
private final Logger logger = Logger.getLogger(CallHistoryFilter.class);
/**
* The <tt>ContactListTreeModel</tt>, where the results of this filter are
* stored
*/
private ContactListTreeModel resultTreeModel;
/**
* The current <tt>ContactQuery</tt>.
*/
@ -40,16 +33,11 @@ public class CallHistoryFilter
/**
* Applies this filter and stores the result in the given <tt>treeModel</tt>.
*
* @param treeModel the <tt>ContactListTreeModel</tt>, where the results
* of this filter are stored
*/
public void applyFilter(ContactListTreeModel treeModel)
public void applyFilter()
{
logger.debug("Call history filter applied.");
this.resultTreeModel = treeModel;
Collection<ExternalContactSource> contactSources
= TreeContactList.getContactSources();
@ -69,15 +57,36 @@ public void applyFilter(ContactListTreeModel treeModel)
this.addMatching( currentQuery.getQueryResults(),
contactSource);
currentQuery.addContactQueryListener(this);
currentQuery.addContactQueryListener(GuiActivator.getContactList());
}
}
/**
* Indicates if the given <tt>uiContact</tt> is matching this filter.
* @param uiContact the <tt>UIContact</tt> to check for match
* @return <tt>true</tt> if the given <tt>uiContact</tt> is matching this
* filter, <tt>false</tt> otherwise
*/
public boolean isMatching(UIContact uiContact)
{
Object descriptor = uiContact.getDescriptor();
if (descriptor instanceof SourceContact)
{
SourceContact sourceContact = (SourceContact) descriptor;
if ((sourceContact.getContactSource().getIdentifier()
.equals(ContactSourceService.CALL_HISTORY)))
return true;
}
return false;
}
/**
* No group could match this filter.
* @param uiGroup the <tt>UIGroup</tt> to check for match
* @return <tt>false</tt> to indicate that no group could match this filter
*/
public boolean isMatching(UIGroup uiGroup)
{
return false;
@ -96,62 +105,13 @@ private void addMatching( List<SourceContact> sourceContacts,
while (contactsIter.hasNext())
{
addHistoryContact(contactsIter.next(), uiSource);
GuiActivator.getContactList()
.addContact(uiSource.createUIContact(contactsIter.next()),
uiSource.getUIGroup(),
false);
}
}
/**
* Indicates that a contact has been received for a query.
* @param event the <tt>ContactReceivedEvent</tt> that notified us
*/
public void contactReceived(ContactReceivedEvent event)
{
synchronized (resultTreeModel)
{
ExternalContactSource sourceUI
= TreeContactList.getContactSource(
event.getQuerySource().getContactSource());
addHistoryContact(event.getContact(), sourceUI);
}
}
/**
* Indicates that the query status has changed.
* @param event the <tt>ContactQueryStatusEvent</tt> that notified us
*/
public void queryStatusChanged(ContactQueryStatusEvent event)
{
int eventType = event.getEventType();
// Remove the current query when it's stopped for some reason.
// QUERY_COMPLETED, QUERY_COMPLETED, QUERY_ERROR
currentQuery = null;
if (eventType == ContactQueryStatusEvent.QUERY_ERROR)
{
//TODO: Show the error to the user??
}
event.getQuerySource().removeContactQueryListener(this);
}
/**
* Adds the given <tt>sourceContact</tt> to the contact list.
* @param sourceContact the <tt>SourceContact</tt> to add
* @param uiSource the UI adapter for the original contact source
*/
private void addHistoryContact( SourceContact sourceContact,
ExternalContactSource uiSource)
{
GuiActivator.getContactList()
.addContact(resultTreeModel,
uiSource.createUIContact(sourceContact),
uiSource.getUIGroup(),
false,
false);
}
/**
* Stops this filter current queries.
*/

@ -33,11 +33,9 @@ public interface ContactListFilter
public boolean isMatching(UIGroup uiGroup);
/**
* Applies this filter to any interested sources and stores the result in
* the given <tt>treeModel</tt>.
* @param treeModel the <tt>ContactListTreeModel</tt> to store the result in
* Applies this filter to any interested sources
*/
public void applyFilter(ContactListTreeModel treeModel);
public void applyFilter();
/**
* Stops this filter current queries.

@ -20,16 +20,13 @@
public interface ContactListSourceFilter extends ContactListFilter
{
/**
* Applies this filter to the given <tt>contactSource</tt> and stores the
* result in the given <tt>treeModel</tt>.
* Applies this filter to the given <tt>contactSource</tt>.
*
* @param contactSource the <tt>ExternalContactSource</tt> to apply the
* filter to
* @param treeModel the <tt>ContactListTreeModel</tt> storing the results
* @return the <tt>ContactQuery</tt> that tracks this filter
*/
public ContactQuery applyFilter(ExternalContactSource contactSource,
ContactListTreeModel treeModel);
public ContactQuery applyFilter(ExternalContactSource contactSource);
/**
* Returns the list of current <tt>ExternalContactSource</tt>s this filter

@ -56,39 +56,42 @@ public ContactNode findFirstContactNode()
}
/**
* Clears all dependencies in the abstraction path (i.e. GroupNode - UIGroup
* - MetaContactGroup or ContactNode - UIContact - SourceContact).
* Removes all nodes except the root node and clears all dependencies.
*/
public void clearDependencies()
public void clear()
{
clearDependencies(rootGroupNode);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
int childCount = rootGroupNode.getChildCount();
int[] removedIndexs = new int[childCount];
Object[] removedNodes = new Object[childCount];
for (int i = 0; i < childCount; i ++)
{
removedIndexs[i] = i;
removedNodes[i] = rootGroupNode.getChildAt(i);
}
rootGroupNode.clear();
nodesWereRemoved(rootGroupNode, removedIndexs, removedNodes);
}
});
}
/**
* Clears all dependencies for all children in the given <tt>groupNode</tt>
* (i.e. GroupNode - UIGroup - MetaContactGroup or ContactNode - UIContact
* - SourceContact).
* @param groupNode the <tt>TreeNode</tt> in which we clear dependencies
* Invoke this method after you've changed how node is to be
* represented in the tree.
* @param node the node that has changed
*/
private void clearDependencies(TreeNode groupNode)
public void nodeChanged(final TreeNode node)
{
for (int i = 0; i < groupNode.getChildCount(); i ++)
SwingUtilities.invokeLater(new Runnable()
{
TreeNode treeNode = groupNode.getChildAt(i);
if (treeNode instanceof ContactNode)
public void run()
{
((ContactNode) treeNode).getContactDescriptor()
.setContactNode(null);
ContactListTreeModel.super.nodeChanged(node);
}
else if (treeNode instanceof GroupNode)
{
((GroupNode) treeNode).getGroupDescriptor()
.setGroupNode(null);
clearDependencies(treeNode);
}
}
});
}
/**

@ -16,7 +16,7 @@
* @author Yana Stamcheva
*/
public class FilterQuery
implements ContactQueryListener
implements ContactQueryListener
{
/**
* A listener, which is notified when this query finishes.
@ -138,6 +138,5 @@ public void queryStatusChanged(ContactQueryStatusEvent event)
fireFilterQueryEvent();
}
public void contactReceived(ContactReceivedEvent event)
{}
public void contactReceived(ContactReceivedEvent event) {}
}

@ -8,6 +8,7 @@
import java.util.*;
import javax.swing.*;
import javax.swing.tree.*;
/**
@ -69,7 +70,10 @@ public ContactNode addContact(UIContact uiContact)
ContactNode contactNode = new ContactNode(uiContact);
uiContact.setContactNode(contactNode);
this.add(contactNode);
add(contactNode);
fireNodeInserted(getIndex(contactNode));
return contactNode;
}
@ -77,23 +81,20 @@ public ContactNode addContact(UIContact uiContact)
* Creates a <tt>ContactNode</tt> for the given <tt>uiContact</tt>,
* adds it to this group and performs a sort at the end.
* @param uiContact the <tt>UIContact</tt> to add
* @param isRefreshView indicates if the view should be refreshed
* @return the created <tt>ContactNode</tt>
*/
@SuppressWarnings("unchecked")
public ContactNode sortedAddContact(UIContact uiContact,
boolean isRefreshView)
public ContactNode sortedAddContact(UIContact uiContact)
{
ContactNode contactNode = new ContactNode(uiContact);
uiContact.setContactNode(contactNode);
this.add(contactNode);
add(contactNode);
// TODO: Optimize!
Collections.sort(children, nodeComparator);
if (isRefreshView)
this.fireNodeInserted(getIndex(contactNode));
fireNodeInserted(getIndex(contactNode));
return contactNode;
}
@ -105,14 +106,15 @@ public ContactNode sortedAddContact(UIContact uiContact,
*/
public void removeContact(UIContact uiContact)
{
ContactNode contactNode = findContactNode(uiContact);
final ContactNode contactNode = uiContact.getContactNode();
if (contactNode != null)
{
int index = getIndex(contactNode);
// We remove the node directly from the list, thus skipping all the
// checks verifying if the node belongs to this parent.
// We remove the node directly from the list, thus skipping all
// the checks verifying if the node belongs to this parent.
children.removeElementAt(index);
contactNode.setParent(null);
uiContact.setContactNode(null);
uiContact = null;
@ -132,7 +134,10 @@ public GroupNode addContactGroup(UIGroup uiGroup)
GroupNode groupNode = new GroupNode(treeModel, uiGroup);
uiGroup.setGroupNode(groupNode);
this.add(groupNode);
add(groupNode);
fireNodeInserted(getIndex(groupNode));
return groupNode;
}
@ -151,6 +156,7 @@ public void removeContactGroup(UIGroup uiGroup)
// We remove the node directly from the list, thus skipping all the
// checks verifying if the node belongs to this parent.
children.removeElementAt(index);
groupNode.setParent(null);
uiGroup.setGroupNode(null);
@ -158,49 +164,25 @@ public void removeContactGroup(UIGroup uiGroup)
}
}
/**
* Removes all of this node's children, setting their parents to null.
* If this node has no children, this method does nothing.
*/
public void removeAllChildren()
{
for (int i = getChildCount()-1; i >= 0; i--)
{
TreeNode treeNode = getChildAt(i);
if (treeNode instanceof ContactNode)
((ContactNode) treeNode).getContactDescriptor()
.setContactNode(null);
else if (treeNode instanceof GroupNode)
((GroupNode) treeNode).getGroupDescriptor()
.setGroupNode(null);
children.removeElementAt(i);
((DefaultMutableTreeNode) treeNode).setParent(null);
}
}
/**
* Creates a <tt>GroupNode</tt> for the given <tt>uiGroup</tt>,
* adds it to this group node and performs a sort at the end.
* @param uiGroup the <tt>UIGroup</tt> to add
* @param isRefreshView indicates if the view should be refreshed
* @return the created <tt>GroupNode</tt>
*/
@SuppressWarnings("unchecked")
public GroupNode sortedAddContactGroup( UIGroup uiGroup,
boolean isRefreshView)
public GroupNode sortedAddContactGroup(UIGroup uiGroup)
{
GroupNode groupNode = new GroupNode(treeModel, uiGroup);
uiGroup.setGroupNode(groupNode);
this.add(groupNode);
add(groupNode);
// TODO: Optimize!
Collections.sort(children, nodeComparator);
if (isRefreshView)
this.fireNodeInserted(getIndex(groupNode));
fireNodeInserted(getIndex(groupNode));
return groupNode;
}
@ -214,30 +196,6 @@ public UIGroup getGroupDescriptor()
return (UIGroup) getUserObject();
}
/**
* Finds the <tt>ContactNode</tt> corresponding to the given
* <tt>uiContact</tt> in the children of this node.
* @param uiContact the <tt>UIContact</tt>, which node we're looking for
* @return the corresponding <tt>ContactNode</tt> or null if no contact
* node was found
*/
@SuppressWarnings("unchecked")
public ContactNode findContactNode(UIContact uiContact)
{
Enumeration<TreeNode> children = children();
while(children.hasMoreElements())
{
TreeNode treeNode = children.nextElement();
if (treeNode instanceof ContactNode
&& ((ContactNode) treeNode).getContactDescriptor()
.equals(uiContact))
{
return (ContactNode) treeNode;
}
}
return null;
}
/**
* Returns the index of this node in its parent group.
* @return the index of this node in its parent group
@ -257,9 +215,15 @@ public void sort(ContactListTreeModel treeModel)
{
if (children != null)
{
Collections.sort(children, nodeComparator);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Collections.sort(children, nodeComparator);
fireNodesChanged();
fireNodesChanged();
}
});
}
}
@ -274,6 +238,34 @@ public boolean isCollapsed()
return isCollapsed;
}
/**
* Clears all dependencies for all children in the given <tt>groupNode</tt>
* (i.e. GroupNode - UIGroup - MetaContactGroup or ContactNode - UIContact
* - SourceContact).
*/
public void clear()
{
for (int i = 0; i < getChildCount(); i ++)
{
TreeNode treeNode = getChildAt(i);
if (treeNode instanceof ContactNode)
{
((ContactNode) treeNode).getContactDescriptor()
.setContactNode(null);
}
else if (treeNode instanceof GroupNode)
{
((GroupNode) treeNode).getGroupDescriptor()
.setGroupNode(null);
((GroupNode) treeNode).clear();
}
}
if (children != null)
children.removeAllElements();
}
/**
* Notifies all interested listeners that a node has been inserted at the
* given <tt>index</tt>.

@ -0,0 +1,32 @@
/*
* SIP Communicator, 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 net.java.sip.communicator.service.contactlist.*;
/**
* The <tt>MetaContactQueryListener</tt> listens for events coming from a
* <tt>MetaContactListService</tt> filtering.
*
* @author Yana Stamcheva
*/
public interface MetaContactQueryListener
{
/**
* Indicates that a <tt>MetaContact</tt> has been received for a search in
* the <tt>MetaContactListService</tt>.
* @param metaContact the received <tt>MetaContact</tt>
*/
public void metaContactReceived(MetaContact metaContact);
/**
* Indicates that a <tt>MetaGroup</tt> has been received from a search in
* the <tt>MetaContactListService</tt>.
* @param metaGroup the <tt>MetaGroup</tt> that has been received
*/
public void metaGroupReceived(MetaContactGroup metaGroup);
}

@ -50,16 +50,14 @@ public PresenceFilter()
/**
* Applies this filter. This filter is applied over the
* <tt>MetaContactListService</tt>.
* @param treeModel the model to which we should add the results from the
* filtering operation
*/
public void applyFilter(ContactListTreeModel treeModel)
public void applyFilter()
{
logger.debug("Presence filter applied.");
isFiltering = true;
addMatching(GuiActivator.getContactListService().getRoot(), treeModel);
addMatching(GuiActivator.getContactListService().getRoot());
isFiltering = false;
}
@ -165,11 +163,8 @@ private boolean isContactOnline(MetaContact contact)
* matching the current filter and not contained in the contact list.
* @param metaGroup the <tt>MetaContactGroup</tt>, which matching contacts
* to add
* @param resultTreeModel the <tt>ContactListTreeModel</tt>, where results
* should be added
*/
private void addMatching( MetaContactGroup metaGroup,
ContactListTreeModel resultTreeModel)
private void addMatching(MetaContactGroup metaGroup)
{
Iterator<MetaContact> childContacts = metaGroup.getChildContacts();
@ -179,26 +174,7 @@ private void addMatching( MetaContactGroup metaGroup,
if(isMatching(metaContact))
{
MetaContactGroup parentGroup
= metaContact.getParentMetaContactGroup();
UIGroup uiGroup = null;
if (!MetaContactListSource.isRootGroup(parentGroup))
{
uiGroup = MetaContactListSource
.getUIGroup(parentGroup);
if (uiGroup == null)
uiGroup = MetaContactListSource
.createUIGroup(parentGroup);
}
GuiActivator.getContactList().addContact(
resultTreeModel,
MetaContactListSource.createUIContact(metaContact),
uiGroup,
true,
false);
MetaContactListSource.fireQueryEvent(metaContact);
}
}
@ -210,12 +186,9 @@ private void addMatching( MetaContactGroup metaGroup,
if (subgroup.countChildContacts() == 0
&& subgroup.countSubgroups() == 0
&& isMatching(subgroup))
GuiActivator.getContactList().addGroup(
resultTreeModel,
MetaContactListSource.createUIGroup(subgroup),
false);
MetaContactListSource.fireQueryEvent(subgroup);
else
addMatching(subgroup, resultTreeModel);
addMatching(subgroup);
}
}

@ -79,30 +79,26 @@ public SearchFilter()
}
/**
* Applies this filter and stores the result in the given <tt>treeModel</tt>.
* @param treeModel the <tt>ContactListTreeModel</tt>, in which we store
* results
* Applies this filter to the default contact source.
*/
public void applyFilter(ContactListTreeModel treeModel)
public void applyFilter()
{
logger.debug("Search filter applied on default source");
if (searchSourceType == DEFAULT_SOURCE)
{
// First add the MetaContactListSource
mclSource.filter(filterPattern, treeModel);
mclSource.filter(filterPattern);
}
}
/**
* Applies this filter to the given <tt>contactSource</tt> and stores the
* result in the given <tt>treeModel</tt>.
* Applies this filter to the given <tt>contactSource</tt>.
*
* @param contactSource the <tt>ExternalContactSource</tt> to apply the
* filter to
* @param treeModel the <tt>ContactListTreeModel</tt> in which the results
* are stored
* @return the <tt>ContactQuery</tt> that tracks this filter
*/
public ContactQuery applyFilter(ExternalContactSource contactSource,
ContactListTreeModel treeModel)
public ContactQuery applyFilter(ExternalContactSource contactSource)
{
logger.debug("Search filter applied on source: "
+ contactSource.getContactSourceService());
@ -119,7 +115,7 @@ public ContactQuery applyFilter(ExternalContactSource contactSource,
contactQuery = sourceService.queryContactSource(filterString);
// Add first available results.
this.addMatching(contactQuery.getQueryResults(), treeModel);
this.addMatching(contactQuery.getQueryResults());
currentQueries.add(contactQuery);
contactQuery.addContactQueryListener(GuiActivator.getContactList());
@ -228,28 +224,23 @@ private boolean isMatching(String text)
}
/**
* Adds the list of <tt>sourceContacts</tt> in the given <tt>treeModel</tt>.
* Adds the list of <tt>sourceContacts</tt> to the contact list.
* @param sourceContacts the list of <tt>SourceContact</tt>s to add
* @param treeModel the <tt>ContactListTreeModel</tt>, where the contacts
* are added
*/
private void addMatching( List<SourceContact> sourceContacts,
ContactListTreeModel treeModel)
private void addMatching( List<SourceContact> sourceContacts)
{
Iterator<SourceContact> contactsIter = sourceContacts.iterator();
while (contactsIter.hasNext())
{
addSourceContact(contactsIter.next(), treeModel);
addSourceContact(contactsIter.next());
}
}
/**
* Adds the given <tt>sourceContact</tt> to the result tree model.
* Adds the given <tt>sourceContact</tt> to the contact list.
* @param sourceContact the <tt>SourceContact</tt> to add
* @param treeModel the <tt>ContactListTreeModel</tt> storing the result
*/
private void addSourceContact( SourceContact sourceContact,
ContactListTreeModel treeModel)
private void addSourceContact( SourceContact sourceContact)
{
ContactSourceService contactSource
= sourceContact.getContactSource();
@ -264,10 +255,8 @@ private void addSourceContact( SourceContact sourceContact,
|| isMatching(sourceContact))
{
GuiActivator.getContactList().addContact(
treeModel,
sourceUI.createUIContact(sourceContact),
sourceUI.getUIGroup(),
false,
false);
}
}

@ -44,6 +44,12 @@ public class MetaContactListSource
*/
private boolean isFiltering = false;
/**
* The <tt>MetaContactQueryListener</tt> listens for <tt>MetaContact</tt>s
* and <tt>MetaGroup</tt>s received as a result of a filtering.
*/
private static MetaContactQueryListener queryListener;
/**
* Returns the <tt>UIContact</tt> corresponding to the given
* <tt>MetaContact</tt>.
@ -144,15 +150,12 @@ public void stopFiltering()
* <tt>filterPattern</tt> and stores the result in the given
* <tt>treeModel</tt>.
* @param filterPattern the pattern to filter through
* @param treeModel the <tt>ContactListTreeModel</tt>, in which we store
* the results
*/
public void filter(Pattern filterPattern, ContactListTreeModel treeModel)
public void filter(Pattern filterPattern)
{
isFiltering = true;
filter(filterPattern, treeModel,
GuiActivator.getContactListService().getRoot());
filter(filterPattern, GuiActivator.getContactListService().getRoot());
isFiltering = false;
}
@ -162,12 +165,9 @@ public void filter(Pattern filterPattern, ContactListTreeModel treeModel)
* given <tt>filterPattern</tt> and stores the result in the given
* <tt>treeModel</tt>.
* @param filterPattern the pattern to filter through
* @param treeModel the <tt>ContactListTreeModel</tt>, in which we store
* the results
* @param parentGroup the <tt>MetaContactGroup</tt> to filter
*/
private void filter(Pattern filterPattern,
ContactListTreeModel treeModel,
MetaContactGroup parentGroup)
{
Iterator<MetaContact> childContacts = parentGroup.getChildContacts();
@ -178,23 +178,7 @@ private void filter(Pattern filterPattern,
if (isMatching(filterPattern, metaContact))
{
UIGroup uiGroup = null;
if (!MetaContactListSource.isRootGroup(parentGroup))
{
uiGroup = MetaContactListSource
.getUIGroup(parentGroup);
if (uiGroup == null)
uiGroup = MetaContactListSource
.createUIGroup(parentGroup);
}
GuiActivator.getContactList().addContact(
treeModel,
MetaContactListSource.createUIContact(metaContact),
uiGroup,
true,
false);
fireQueryEvent(metaContact);
}
}
@ -203,7 +187,7 @@ private void filter(Pattern filterPattern,
{
MetaContactGroup subgroup = subgroups.next();
filter(filterPattern, treeModel, subgroup);
filter(filterPattern, subgroup);
}
}
@ -267,4 +251,45 @@ public boolean isMatching(Pattern filterPattern, MetaContactGroup metaGroup)
}
return false;
}
/**
* Sets the given <tt>MetaContactQueryListener</tt> to listen for query
* events coming from <tt>MetaContactListService</tt> filtering.
* @param l the <tt>MetaContactQueryListener</tt> to set
*/
public static void setMetaContactQueryListener(MetaContactQueryListener l)
{
queryListener = l;
}
/**
* Returns the currently registered <tt>MetaContactQueryListener</tt>.
* @return the currently registered <tt>MetaContactQueryListener</tt>
*/
public static MetaContactQueryListener getMetaContactQueryListener()
{
return queryListener;
}
/**
* Notifies the <tt>MetaContactQueryListener</tt> that a new
* <tt>MetaContact</tt> has been received as a result of a search.
* @param metaContact the received <tt>MetaContact</tt>
*/
public static void fireQueryEvent(MetaContact metaContact)
{
if (queryListener != null)
queryListener.metaContactReceived(metaContact);
}
/**
* Notifies the <tt>MetaContactQueryListener</tt> that a new
* <tt>MetaGroup</tt> has been received as a result of a search.
* @param metaGroup the received <tt>MetaGroup</tt>
*/
public static void fireQueryEvent(MetaContactGroup metaGroup)
{
if (queryListener != null)
queryListener.metaGroupReceived(metaGroup);
}
}

Loading…
Cancel
Save