diff options
author | Yana Stamcheva <yana@jitsi.org> | 2010-05-05 12:03:42 +0000 |
---|---|---|
committer | Yana Stamcheva <yana@jitsi.org> | 2010-05-05 12:03:42 +0000 |
commit | 32656edcfc7b5cdacc642a3f333741eb135e2419 (patch) | |
tree | 0c44166bced2c0d876ec360e70dd1895cf4c0da8 /src | |
parent | 6007623e549ae18830a221178eedac125e867f41 (diff) | |
download | jitsi-32656edcfc7b5cdacc642a3f333741eb135e2419.zip jitsi-32656edcfc7b5cdacc642a3f333741eb135e2419.tar.gz jitsi-32656edcfc7b5cdacc642a3f333741eb135e2419.tar.bz2 |
Search Filter: After filtering each source update the user interface (i.e. we don't wait until all the sources are filter before updating the ui)
Diffstat (limited to 'src')
7 files changed, 447 insertions, 120 deletions
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListSourceFilter.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListSourceFilter.java new file mode 100644 index 0000000..4b9bde9 --- /dev/null +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListSourceFilter.java @@ -0,0 +1,46 @@ +/* + * 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 java.util.*; + +import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*; + +/** + * The <tt>ContactListSourceFilter</tt> is a <tt>ContactListFilter</tt> that + * allows to apply the filter to only one of its contact sources at a time. + * + * @author Yana Stamcheva + */ +public interface ContactListSourceFilter extends ContactListFilter +{ + /** + * Applies this filter to the given <tt>contactSource</tt> and stores the + * result in the given <tt>treeModel</tt>. + * + * @param contactSource the <tt>ExternalContactSource</tt> to apply the + * filter to + * @param treeModel the <tt>ContactListTreeModel</tt> storing the results + */ + public void applyFilter(ExternalContactSource contactSource, + ContactListTreeModel treeModel); + + /** + * Returns the list of current <tt>ExternalContactSource</tt>s this filter + * works with. + * @return the list of current <tt>ExternalContactSource</tt>s this filter + * works with + */ + public Collection<ExternalContactSource> getContactSources(); + + /** + * 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(); +} diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/FilterQuery.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/FilterQuery.java new file mode 100644 index 0000000..0dedbc2 --- /dev/null +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/FilterQuery.java @@ -0,0 +1,110 @@ +/* + * 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; + +/** + * The <tt>FilterQuery</tt> gives information about a current filtering. + * + * @author Yana Stamcheva + */ +public class FilterQuery +{ + /** + * A listener, which is notified when this query finishes. + */ + private FilterQueryListener filterQueryListener; + + /** + * Indicates if the query succeeded, i.e. if the filter has returned any + * results. + */ + private boolean isSucceeded = false; + + /** + * Indicates if this query has been canceled. + */ + private boolean isCanceled = false; + + /** + * The number of results we're waiting for, before notifying interested + * <tt>filterQueryListener</tt> that the query has finished. + */ + private int waitResults = 0; + + /** + * Adds a wait result. + */ + public void addWaitResult() + { + waitResults ++; + } + + /** + * Removes a wait result. If no more results are waited then we notify + * interested listener that this query has finished. + */ + public void removeWaitResult() + { + waitResults --; + + if (waitResults == 0) + fireFilterQueryEvent(); + } + + /** + * Sets the <tt>isSucceeded</tt> property. + * @param isSucceeded indicates if this query has succeeded + */ + public void setSucceeded(boolean isSucceeded) + { + this.isSucceeded = isSucceeded; + } + + /** + * Indicates if this query has succeeded. + * @return <tt>true</tt> if this query has succeeded, <tt>false</tt> - + * otherwise + */ + public boolean isSucceeded() + { + return isSucceeded; + } + + public boolean isCanceled() + { + return isCanceled; + } + + public void cancel() + { + isCanceled = true; + } + + /** + * Sets the given <tt>FilterQueryListener</tt>. + * @param l the <tt>FilterQueryListener</tt> to set + */ + public void setQueryListener(FilterQueryListener l) + { + filterQueryListener = l; + } + + /** + * Notifies the <tt>FilterQueryListener</tt> of the result status of + * this query. + */ + private void fireFilterQueryEvent() + { + if (filterQueryListener == null) + return; + + if (isSucceeded) + filterQueryListener.filterQuerySucceeded(this); + else + filterQueryListener.filterQueryFailed(this); + } +} diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/FilterQueryListener.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/FilterQueryListener.java new file mode 100644 index 0000000..98c1d66 --- /dev/null +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/FilterQueryListener.java @@ -0,0 +1,29 @@ +/* + * 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; + +/** + * The <tt>FilterQueryListener</tt> is notified when a filter query finishes. + * + * @author Yana Stamcheva + */ +public interface FilterQueryListener +{ + /** + * 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); + + /** + * 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); +} 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 3b8bc1f..25fafd6 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 @@ -51,8 +51,7 @@ public class PresenceFilter { isFiltering = true; - addMatching(GuiActivator.getContactListService().getRoot(), - treeModel); + addMatching(GuiActivator.getContactListService().getRoot(), treeModel); isFiltering = false; } 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 eec1066..7f7d613 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 @@ -20,7 +20,8 @@ import net.java.sip.communicator.util.swing.plaf.*; */ public class SearchField extends SIPCommTextField - implements TextFieldChangeListener + implements TextFieldChangeListener, + FilterQueryListener { private final Logger logger = Logger.getLogger(SearchField.class); @@ -174,26 +175,11 @@ public class SearchField if (filterString != null && filterString.length() > 0) { - boolean hasMatching + FilterQuery filterQuery = contactList.applyFilter(TreeContactList.searchFilter); - // If don't have matching contacts we enter the unknown contact - // view. - if (!hasMatching) - { - enableUnknownContactView(true); - } - // If the unknown contact view was previously enabled, but we - // have found matching contacts we enter the normal view. - else - { - if (!lastHasMatching) - enableUnknownContactView(false); - - contactList.selectFirstContact(); - } - - lastHasMatching = hasMatching; + if (filterQuery != null) + filterQuery.setQueryListener(this); } else { @@ -218,4 +204,37 @@ public class SearchField } }); } + + /** + * 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) + { + /// If don't have matching contacts we enter the unknown contact + // view. + enableUnknownContactView(true); + + lastHasMatching = false; + query.setQueryListener(null); + } + + /** + * 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. + if (!lastHasMatching) + enableUnknownContactView(false); + + GuiActivator.getContactList().selectFirstContact(); + + lastHasMatching = true; + 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 057148c..ef798c2 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 @@ -20,8 +20,7 @@ import net.java.sip.communicator.service.contactsource.*; * @author Yana Stamcheva */ public class SearchFilter - implements ContactListFilter, - ContactQueryListener + implements ContactListSourceFilter { /** * The default contact source search type. @@ -44,12 +43,6 @@ public class SearchFilter private Pattern filterPattern; /** - * The <tt>ContactListTreeModel</tt>, where results from the search - * are added. - */ - private ContactListTreeModel resultTreeModel; - - /** * The <tt>MetaContactListSource</tt> to search in. */ private final MetaContactListSource mclSource; @@ -85,31 +78,37 @@ public class SearchFilter */ public void applyFilter(ContactListTreeModel treeModel) { - resultTreeModel = treeModel; - - if (contactSources == null) - contactSources = TreeContactList.getContactSources(); - if (searchSourceType == DEFAULT_SOURCE) // First add the MetaContactListSource mclSource.filter(filterPattern, treeModel); + } - for (ExternalContactSource contactSource : contactSources) - { - ContactSourceService sourceService - = contactSource.getContactSourceService(); - if (sourceService instanceof ExtendedContactSourceService) - currentQuery - = ((ExtendedContactSourceService) sourceService) - .queryContactSource(filterPattern); - else - currentQuery = sourceService.queryContactSource(filterString); - - // Add first available results. - this.addMatching(currentQuery.getQueryResults()); - - currentQuery.addContactQueryListener(this); - } + /** + * Applies this filter to the given <tt>contactSource</tt> and stores the + * result in the given <tt>treeModel</tt>. + * + * @param contactSource the <tt>ExternalContactSource</tt> to apply the + * filter to + * @param treeModel the <tt>ContactListTreeModel</tt> in which the results + * are stored + */ + public void applyFilter(ExternalContactSource contactSource, + ContactListTreeModel treeModel) + { + ContactSourceService sourceService + = contactSource.getContactSourceService(); + + if (sourceService instanceof ExtendedContactSourceService) + currentQuery + = ((ExtendedContactSourceService) sourceService) + .queryContactSource(filterPattern); + else + currentQuery = sourceService.queryContactSource(filterString); + + // Add first available results. + this.addMatching(currentQuery.getQueryResults(), treeModel); + + currentQuery.addContactQueryListener(GuiActivator.getContactList()); } /** @@ -202,55 +201,28 @@ public class SearchFilter } /** - * 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) - { - addSourceContact(event.getContact()); - } - } - - /** - * Indicates that the status of a query 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 list of <tt>sourceContacts</tt> in the current result tree model. + * Adds the list of <tt>sourceContacts</tt> in the given <tt>treeModel</tt>. * @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) + private void addMatching( List<SourceContact> sourceContacts, + ContactListTreeModel treeModel) { Iterator<SourceContact> contactsIter = sourceContacts.iterator(); while (contactsIter.hasNext()) { - addSourceContact(contactsIter.next()); + addSourceContact(contactsIter.next(), treeModel); } } /** * Adds the given <tt>sourceContact</tt> to the result tree model. * @param sourceContact the <tt>SourceContact</tt> to add + * @param treeModel the <tt>ContactListTreeModel</tt> storing the result */ - private void addSourceContact(SourceContact sourceContact) + private void addSourceContact( SourceContact sourceContact, + ContactListTreeModel treeModel) { ContactSourceService contactSource = sourceContact.getContactSource(); @@ -263,12 +235,14 @@ public class SearchFilter // SourceContact over the pattern && (contactSource instanceof ExtendedContactSourceService) || isMatching(sourceContact)) + { GuiActivator.getContactList().addContact( - resultTreeModel, + treeModel, sourceUI.getUIContact(sourceContact), sourceUI.getUIGroup(), - true, + false, false); + } } /** @@ -299,4 +273,25 @@ public class SearchFilter } } } + + public Collection<ExternalContactSource> getContactSources() + { + if (contactSources == null) + contactSources = TreeContactList.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() + { + if (searchSourceType == DEFAULT_SOURCE) + return true; + else + return false; + } } 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 4d5c4c4..c4d2881 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 @@ -36,6 +36,7 @@ public class TreeContactList extends DefaultTreeContactList implements MetaContactListListener, ContactPresenceStatusListener, + ContactQueryListener, MouseListener, MouseMotionListener, TreeExpansionListener @@ -52,13 +53,6 @@ public class TreeContactList private ContactListTreeModel treeModel; /** - * The temporary tree model is used to collect the results from a filter - * operation. This is used in order to separate search and filter matching - * operations from the UI refresh operations. - */ - private ContactListTreeModel tempTreeModel; - - /** * The right button menu. */ private JPopupMenu rightButtonMenu; @@ -132,6 +126,11 @@ public class TreeContactList private final Object filterLock = new Object(); /** + * The filter query used to track advanced source filtering. + */ + FilterQuery filterQuery; + + /** * Creates the <tt>TreeContactList</tt>. */ public TreeContactList() @@ -173,7 +172,7 @@ public class TreeContactList public void run() { // We synchronize the matching and all MetaContactListener - // events on the tempTreeModel in order to prevent modification + // events on the filterLock in order to prevent modification // to be done on the actual treeModel while we're working with // the temporary model. synchronized (filterLock) @@ -215,7 +214,7 @@ public class TreeContactList public void run() { // We synchronize the matching and all MetaContactListener - // events on the tempTreeModel in order to prevent modification + // events on the filterLock in order to prevent modification // to be done on the actual treeModel while we're working with // the temporary model. synchronized (filterLock) @@ -259,7 +258,7 @@ public class TreeContactList public void run() { // We synchronize the matching and all MetaContactListener - // events on the tempTreeModel in order to prevent modification + // events on the filterLock in order to prevent modification // to be done on the actual treeModel while we're working with // the temporary model. synchronized (filterLock) @@ -290,7 +289,7 @@ public class TreeContactList public void run() { // We synchronize the matching and all MetaContactListener - // events on the tempTreeModel in order to prevent modification + // events on the filterLock in order to prevent modification // to be done on the actual treeModel while we're working with // the temporary model. synchronized (filterLock) @@ -323,7 +322,7 @@ public class TreeContactList public void run() { // We synchronize the matching and all MetaContactListener - // events on the tempTreeModel in order to prevent modification + // events on the filterLock in order to prevent modification // to be done on the actual treeModel while we're working with // the temporary model. synchronized (filterLock) @@ -351,7 +350,7 @@ public class TreeContactList public void run() { // We synchronize the matching and all MetaContactListener - // events on the tempTreeModel in order to prevent modification + // events on the filterLock in order to prevent modification // to be done on the actual treeModel while we're working with // the temporary model. synchronized (filterLock) @@ -389,7 +388,7 @@ public class TreeContactList public void run() { // We synchronize the matching and all MetaContactListener - // events on the tempTreeModel in order to prevent modification + // events on the filterLock in order to prevent modification // to be done on the actual treeModel while we're working with // the temporary model. synchronized (filterLock) @@ -449,7 +448,7 @@ public class TreeContactList public void run() { // We synchronize the matching and all MetaContactListener - // events on the tempTreeModel in order to prevent modification + // events on the filterLock in order to prevent modification // to be done on the actual treeModel while we're working with // the temporary model. synchronized (filterLock) @@ -476,7 +475,7 @@ public class TreeContactList public void run() { // We synchronize the matching and all MetaContactListener - // events on the tempTreeModel in order to prevent modification + // events on the filterLock in order to prevent modification // to be done on the actual treeModel while we're working with // the temporary model. synchronized (filterLock) @@ -509,7 +508,7 @@ public class TreeContactList public void run() { // We synchronize the matching and all MetaContactListener - // events on the tempTreeModel in order to prevent modification + // events on the filterLock in order to prevent modification // to be done on the actual treeModel while we're working with // the temporary model. synchronized (filterLock) @@ -545,7 +544,7 @@ public class TreeContactList public void run() { // We synchronize the matching and all MetaContactListener - // events on the tempTreeModel in order to prevent modification + // events on the filterLock in order to prevent modification // to be done on the actual treeModel while we're working with // the temporary model. synchronized (filterLock) @@ -603,7 +602,7 @@ public class TreeContactList public void run() { // We synchronize the matching and all MetaContactListener - // events on the tempTreeModel in order to prevent modification + // events on the filterLock in order to prevent modification // to be done on the actual treeModel while we're working with // the temporary model. synchronized (filterLock) @@ -669,7 +668,7 @@ public class TreeContactList public void run() { // We synchronize the matching and all MetaContactListener - // events on the tempTreeModel in order to prevent modification + // events on the filterLock in order to prevent modification // to be done on the actual treeModel while we're working with // the temporary model. synchronized (filterLock) @@ -685,6 +684,65 @@ public class TreeContactList } /** + * Indicates that a contact has been received for a query. + * @param event the <tt>ContactReceivedEvent</tt> that notified us + */ + public void contactReceived(ContactReceivedEvent event) + { + final SourceContact sourceContact = event.getContact(); + + SwingUtilities.invokeLater(new Runnable() + { + public void run() + { + // We synchronize the matching and all MetaContactListener + // events on the filterLock in order to prevent modification + // to be done on the actual treeModel while we're working with + // the temporary model. + synchronized (filterLock) + { + ContactSourceService contactSource + = sourceContact.getContactSource(); + + ExternalContactSource sourceUI + = TreeContactList.getContactSource(contactSource); + + UIContact uiContact = sourceUI.getUIContact(sourceContact); + + if (sourceUI == null) + return; + + // ExtendedContactSourceService has already matched the + // SourceContact over the pattern + if((contactSource instanceof ExtendedContactSourceService) + || currentFilter.isMatching(uiContact)) + { + addContact(uiContact, sourceUI.getUIGroup()); + } + else + uiContact = null; + } + } + }); + } + + /** + * Indicates that the status of a query has changed. + * @param event the <tt>ContactQueryStatusEvent</tt> that notified us + */ + public void queryStatusChanged(ContactQueryStatusEvent event) + { + int eventType = event.getEventType(); + + if (eventType == ContactQueryStatusEvent.QUERY_ERROR) + { + //TODO: Show the error to the user?? + } + + event.getQuerySource().removeContactQueryListener(this); + } + + /** * Returns the right button menu opened over the contact list. * * @return the right button menu opened over the contact list @@ -716,7 +774,7 @@ public class TreeContactList public void setActiveContact(MetaContact metaContact, boolean isActive) { // We synchronize the matching and all MetaContactListener - // events on the tempTreeModel in order to prevent modification + // events on the filterLock in order to prevent modification // to be done on the actual treeModel while we're working with // the temporary model. synchronized (filterLock) @@ -944,6 +1002,9 @@ public class TreeContactList { currentFilter.stopFilter(); this.isFiltering = false; + + if (filterQuery != null) + filterQuery.cancel(); } /** @@ -954,18 +1015,81 @@ public class TreeContactList */ public boolean applyDefaultFilter() { - return applyFilter(defaultFilter); + return applyFilter(defaultFilter, new ContactListTreeModel(), null); + } + + /** + * Applies the given <tt>filter</tt>. + * @param filter the <tt>ContactListFilter</tt> to apply. + * @return <tt>true</tt> if the filter has any matches, <tt>false</tt> + * otherwise + */ + public boolean applyFilter(ContactListFilter filter) + { + return applyFilter(filter, new ContactListTreeModel(), null); + } + + /** + * Applies the given <tt>ContactListSourceFilter</tt>. + * @param filter the <tt>ContactListSourceFilter</tt> to apply + * @return the <tt>FilterQuery</tt> through which the filter could be + * tracked + */ + public FilterQuery applyFilter(final ContactListSourceFilter filter) + { + final ContactListTreeModel tempTreeModel = new ContactListTreeModel(); + + filterQuery = new FilterQuery(); + + // If the filter has a default contact source, we apply it first. + if (filter.hasDefaultSource()) + filterQuery.setSucceeded(applyFilter(filter, tempTreeModel, null)); + + Iterator<ExternalContactSource> filterSources + = filter.getContactSources().iterator(); + + // Then we apply the filter on all its contact sources. + while (filterSources.hasNext()) + { + final ExternalContactSource filterSource = filterSources.next(); + + if (filterQuery.isCanceled()) + return filterQuery; + + filterQuery.addWaitResult(); + new Thread() + { + public void run() + { + boolean isSucceeded + = applyFilter( filter, + tempTreeModel, + filterSource); + + if (!filterQuery.isSucceeded() && isSucceeded) + filterQuery.setSucceeded(true); + + filterQuery.removeWaitResult(); + } + }.start(); + } + return filterQuery; } /** * Applies the given <tt>filter</tt> and changes the content of the * contact list according to it. * @param filter the new filter to set + * @param tempTreeModel the treeModel, where the filter results are stored + * @param contactSource the <tt>ExternalContactSource</tt> to apply the + * filter to * @return <tt>true</tt> to indicate that the filter has found a match, * <tt>false</tt> if no matches were found and the contact list is then * empty. */ - public boolean applyFilter(ContactListFilter filter) + private boolean applyFilter(ContactListFilter filter, + ContactListTreeModel tempTreeModel, + ExternalContactSource contactSource) { // We set the isFiltering to true to indicate that we're currently // filtering. @@ -974,8 +1098,6 @@ public class TreeContactList if (currentFilter == null || !currentFilter.equals(filter)) this.currentFilter = filter; - tempTreeModel = new ContactListTreeModel(); - // We synchronize the matching and all MetaContactListener events on // the searchTreeModel in order to prevent modification to be done on // the actual treeModel while we're working with the temporary model. @@ -983,7 +1105,15 @@ public class TreeContactList { treeModel.clearDependencies(); - currentFilter.applyFilter(tempTreeModel); + // If we have a specific contact source and we're dealing with + // a ContactListSourceFilter then we would apply the filter only + // to this source. + if (contactSource != null + && filter instanceof ContactListSourceFilter) + ((ContactListSourceFilter) currentFilter) + .applyFilter(contactSource, tempTreeModel); + else + currentFilter.applyFilter(tempTreeModel); treeModel = tempTreeModel; } @@ -1026,8 +1156,6 @@ public class TreeContactList if (tempTreeModel.getChildCount(tempTreeModel.getRoot()) > 0) hasResults = true; - tempTreeModel = null; - return hasResults; } @@ -1060,7 +1188,7 @@ public class TreeContactList public void run() { // We synchronize the matching and all MetaContactListener - // events on the tempTreeModel in order to prevent modification + // events on the filterLock in order to prevent modification // to be done on the actual treeModel while we're working with // the temporary model. synchronized (filterLock) @@ -1668,8 +1796,9 @@ public class TreeContactList switch (event.getType()) { case ServiceEvent.REGISTERED: - contactSources.add( - new ExternalContactSource((ContactSourceService) service)); + ExternalContactSource contactSource + = new ExternalContactSource((ContactSourceService) service); + contactSources.add(contactSource); break; case ServiceEvent.UNREGISTERING: ExternalContactSource cSource @@ -1704,7 +1833,7 @@ public class TreeContactList public void run() { // We synchronize the matching and all MetaContactListener - // events on the tempTreeModel in order to prevent + // events on the filterLock in order to prevent // modification to be done on the actual treeModel while // we're working with the temporary model. synchronized (filterLock) |