--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines_old/contactsmodel/cntview/findview.cpp Fri Jun 11 13:29:23 2010 +0300
@@ -0,0 +1,502 @@
+// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <cntview.h>
+#include "CNTSTD.H"
+#include <cntviewsortplugin.h>
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <cntviewsortpluginbase.h>
+#endif
+
+//#define CNTVIEW_API_PROFILING
+// To see the diferences between class versions check the in source documentation of TContactViewEvent
+const TUint KClassVersion1 = 1;
+const TUint KClassVersion2 = 2;
+
+/* Default C++ Constructor */
+CContactFindView::CContactFindView(const CContactDatabase& aDb,CContactViewBase& aView, TSearchType aSearchType)
+:CContactViewBase(aDb),iView(aView),iSearchType(aSearchType), iClassVersion(KClassVersion1)
+
+ {}
+
+CContactFindView::~CContactFindView()
+/** Destructor */
+ {
+ iView.Close(*this);
+ DeleteFindContacts();
+ DestroyFindWordsArray();
+ }
+
+/* Helper method to delete find results */
+void CContactFindView::DeleteFindContacts()
+ {
+ iFindContacts.ResetAndDestroy();
+ }
+
+EXPORT_C CContactFindView* CContactFindView::NewL(const CContactDatabase& aDb,CContactViewBase& aView,MContactViewObserver& aObserver,MDesCArray* aFindWords)
+/** Allocates and constructs a new CContactFindView version 1 object, using a default search
+type of CContactViewBase::EFullSearch.
+
+When adding/deleting contacts in the view, MContactViewObserver observer will receive
+TContactViewEvent events with iInt parameter set to KErrNone.
+
+@param aDb The database containing the contact items.
+@param aView The underlying contact view.
+@param aObserver An observer that receives notifications when this view is
+ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady
+event when the view is ready. An attempt to use the view before this notification
+causes a panic.
+@param aFindWords The array of search terms. The view does not take ownership
+of this - it makes its own copy of it to prevent it from going out of scope.
+@return The newly constructed find view object. */
+ {
+ return NewL(aDb,aView,aObserver,aFindWords,EFullSearch);
+ }
+
+EXPORT_C CContactFindView* CContactFindView::NewL(const CContactDatabase& aDb,CContactViewBase& aView,MContactViewObserver& aObserver,MDesCArray* aFindWords, TSearchType aSearchType)
+/** Allocates and constructs a new CContactFindView version 1 object, specifying a search
+type.
+
+When adding/deleting contacts in the view, MContactViewObserver observer will receive
+TContactViewEvent events with iInt parameter set to KErrNone.
+
+@param aDb The database containing the contact items.
+@param aView The underlying contact view.
+@param aObserver An observer that receives notifications when this view is
+ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady
+event when the view is ready. An attempt to use the view before this notification
+causes a panic.
+@param aFindWords The array of search terms. The view does not take ownership
+of this - it makes its own copy of it to prevent it from going out of scope.
+@param aSearchType The search type. This controls whether a search term can
+occur anywhere in a contact item field, or just at the beginning of the field.
+@return The newly constructed find view object. */
+ {
+#ifdef CNTVIEW_API_PROFILING
+ RDebug::Print(_L("[CNTMODEL] CContactFindView::NewL()\n"));
+#endif
+ CContactFindView* self=new(ELeave) CContactFindView(aDb, aView, aSearchType);
+ CleanupStack::PushL(self);
+ self->ConstructL(aObserver,aFindWords);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+EXPORT_C CContactFindView* CContactFindView::NewL(CContactViewBase& aView,const CContactDatabase& aDb,MContactViewObserver& aObserver,MDesCArray* aFindWords)
+/** Allocates and constructs a new CContactFindView version 2 object, using a default search
+type of CContactViewBase::EFullSearch.
+
+When adding/deleting contacts in the view, MContactViewObserver observer will receive
+TContactViewEvent events with iInt parameter set to index into the observed view of the added/deleted item
+
+@param aDb The database containing the contact items.
+@param aView The underlying contact view.
+@param aObserver An observer that receives notifications when this view is
+ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady
+event when the view is ready. An attempt to use the view before this notification
+causes a panic.
+@param aFindWords The array of search terms. The view does not take ownership
+of this - it makes its own copy of it to prevent it from going out of scope.
+@return The newly constructed find view object. */
+ {
+ return NewL(aView,aDb,aObserver,aFindWords,EFullSearch);
+ }
+
+EXPORT_C CContactFindView* CContactFindView::NewL(CContactViewBase& aView,const CContactDatabase& aDb,MContactViewObserver& aObserver,MDesCArray* aFindWords, TSearchType aSearchType)
+/** Allocates and constructs a new CContactFindView version 2 object, specifying a search
+ type.
+
+When adding/deleting contacts in the view, MContactViewObserver observer will receive
+TContactViewEvent events with iInt parameter set to index into the observed view of the added/deleted item
+
+@param aDb The database containing the contact items.
+@param aView The underlying contact view.
+@param aObserver An observer that receives notifications when this view is
+ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady
+event when the view is ready. An attempt to use the view before this notification
+causes a panic.
+@param aFindWords The array of search terms. The view does not take ownership
+of this - it makes its own copy of it to prevent it from going out of scope.
+@param aSearchType The search type. This controls whether a search term can
+occur anywhere in a contact item field, or just at the beginning of the field.
+@return The newly constructed find view object. */
+ {
+#ifdef CNTVIEW_API_PROFILING
+ RDebug::Print(_L("[CNTMODEL] CContactFindView::NewL()\n"));
+#endif
+ CContactFindView* self=new(ELeave) CContactFindView(aDb, aView, aSearchType);
+ CleanupStack::PushL(self);
+ self->ConstructL(aObserver,aFindWords);
+ self->iClassVersion = KClassVersion2;
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/*
+ * Second phase constructor
+ * @param aObserver view observer
+ * @param aFindWords Array of words to find
+ */
+void CContactFindView::ConstructL(MContactViewObserver& aObserver,MDesCArray* aFindWords)
+ {
+ CContactViewBase::ConstructL();
+ OpenL(aObserver);
+ iView.OpenL(*this);
+ CopyNewFindWordsL(aFindWords);
+ }
+
+/* Helper method for deleting iFindWords member */
+void CContactFindView::DestroyFindWordsArray()
+ {
+ if(iFindWords)
+ {
+ iFindWords->Reset();
+ delete iFindWords;
+ iFindWords=NULL;
+ }
+ }
+
+/* Duplicate array provided by client to prevent it going out of scope */
+void CContactFindView::CopyNewFindWordsL(MDesCArray* aFindWords)
+ {
+ DestroyFindWordsArray();
+ const TInt count = aFindWords->MdcaCount();
+ CPtrCArray* findWordArray = new (ELeave) CPtrCArray(count);
+ CleanupStack::PushL(findWordArray);
+ findWordArray->CopyL(*aFindWords);
+ CleanupStack::Pop(findWordArray);
+ iFindWords=findWordArray;
+ }
+
+EXPORT_C void CContactFindView::UpdateFindViewL()
+/** Populates the view.
+
+This deletes any existing matching contacts list and searches the underlying
+view for items matching the search criteria. */
+ {
+ DeleteFindContacts();
+ if (iSearchType==EFullSearch)
+ iView.ContactsMatchingCriteriaL(*iFindWords,iFindContacts);
+ else
+ iView.ContactsMatchingPrefixL(*iFindWords,iFindContacts);
+ }
+
+/**
+ * This is a reserved virtual exported function that is used for BC proofing
+ * against present and future additions of new exported virtual functions.
+ @return Any return values of the helper methods called from this function or NULL.
+ */
+TAny* CContactFindView::CContactViewBase_Reserved_1(TFunction aFunction,TAny* aParams)
+ {
+ return CContactViewBase::CContactViewBase_Reserved_1(aFunction,aParams);
+ }
+
+/* Refines an existing find view selection based on new criteria */
+void CContactFindView::TightenFindViewCriteriaL()
+ {
+ RPointerArray<CViewContact> updatedContacts;
+ CleanupClosePushL(updatedContacts);
+ const TInt viewCount = iFindContacts.Count();
+ CViewContact* contact;
+ TBool match = EFalse;
+ for (TInt ii=0;ii<viewCount;++ii)
+ {
+ contact =(iFindContacts)[ii];
+ match=MatchesCriteriaL(*contact,*iFindWords, iSearchType,iExtension);
+ if (match)
+ {
+ TContactItemId id = contact->Id();
+ CViewContact* matchContact = CViewContact::NewLC(id);
+ User::LeaveIfError(updatedContacts.Append(matchContact));
+ CleanupStack::Pop(matchContact);
+ }
+ }
+ DeleteFindContacts();
+ iFindContacts=updatedContacts;
+ CleanupStack::Pop(&updatedContacts);
+ }
+
+EXPORT_C void CContactFindView::RefineFindViewL(MDesCArray* aFindWords)
+/** Refines the search criteria and updates the find view.
+
+This may involve either narrowing or replacing the search criteria.
+
+This function can be used to narrow the existing search criteria, by specifying
+an array of search terms that consists of the existing search terms (as passed
+to the NewL()) with additional terms appended to it. In this case, the function
+searches the existing list of matching contact items only. This assumes that
+UpdateFindViewL() has previously been called.
+
+It can alternatively be used to replace entirely the existing search criteria.
+In this case, the whole underlying view is searched again.
+
+@param aFindWords The new search criteria. This can be a superset of the existing
+search criteria, i.e. the existing criteria with additional terms appended
+to it; otherwise it replaces the existing search criteria entirely. */
+ {
+ const TInt originalFindWords=iFindWords->MdcaCount();
+ if(aFindWords->MdcaCount()>=originalFindWords)
+ {
+ TInt compare = KErrNotFound;
+ TBool hit=EFalse;
+ //Check that the new words are equal to a greater than the original find words.
+ for (TInt ii=0;ii<originalFindWords;++ii)
+ {
+ TPtrC originalWord(iFindWords->MdcaPoint(ii));
+ //RDebug::Print(_L("orig=== %S"),&originalWord);
+ //RDebug::Print(_L("new=== %S"),&aFindWords->MdcaPoint(ii));
+ compare = aFindWords->MdcaPoint(ii).CompareF(originalWord);
+ if(compare>=0)
+ {
+ hit=ETrue;
+ }
+ else
+ {
+ //its something completely different we need to do a fresh search
+ hit=EFalse;
+ break;
+ }
+ }
+ if(hit)
+ {
+ //Results is a subset of what we already have so just refine it.
+ CopyNewFindWordsL(aFindWords);
+ TightenFindViewCriteriaL();
+ return;
+ }
+ }
+ CopyNewFindWordsL(aFindWords);
+ //Do a new find from scratch
+ UpdateFindViewL();
+ }
+
+/* Handle events from the parent view */
+void CContactFindView::HandleContactViewEvent(const CContactViewBase& aView,const TContactViewEvent& aEvent)
+ {
+ ASSERT(&aView==&iView);
+ TContactViewEvent event=aEvent;
+
+ TInt err = KErrNone;
+
+ switch (event.iEventType)
+ {
+ case TContactViewEvent::EUnavailable:
+ case TContactViewEvent::ESortError:
+ case TContactViewEvent::EServerError:
+ iState=ENotReady;
+ break;
+ case TContactViewEvent::ESortOrderChanged:
+ case TContactViewEvent::EReady:
+ {
+ if(&iView==&aView)
+ {
+ TRAP(err,UpdateFindViewL());
+ iState=EReady;
+ }
+ }
+ break;
+ case TContactViewEvent::EItemAdded:
+ if(&iView==&aView)
+ {
+ TRAP(err,HandleAddEventL(event));
+ }
+ break;
+ case TContactViewEvent::EItemRemoved:
+ if(&iView==&aView)
+ {
+ TRAP(err,HandleRemoveEventL(event));
+ }
+ break;
+ case TContactViewEvent::EGroupChanged:
+ break;
+ default:
+ ASSERT(EFalse);
+ }
+
+ if (err != KErrNone)
+ {
+ NotifyObservers(TContactViewEvent(TContactViewEvent::ESortError,err));
+ }
+ else
+ {
+ NotifyObservers(event);
+ }
+ }
+
+/* Handles a EItemRemoved event from the underlying view */
+void CContactFindView::HandleRemoveEventL(TContactViewEvent& aEvent)
+ {
+ aEvent.iInt = KErrNone;
+ const TInt pos = FindL(aEvent.iContactId);
+ if (pos != KErrNotFound)
+ {
+ delete iFindContacts[pos];
+ iFindContacts.Remove(pos);
+ if(iClassVersion == KClassVersion2) //update the iInt with correct value
+ {
+ aEvent.iInt = pos;
+ }
+ }
+ }
+
+/* Handles a EItemAdded event from the underlying view */
+void CContactFindView::HandleAddEventL(TContactViewEvent& aEvent)
+ {
+ // The id contained in aEvent can refer to a inexistent contact by now
+ // The contact may have been deleted or changed index position,
+ // so check that the contact with that id still exist first
+ TInt underlyingViewIndex = iView.FindL(aEvent.iContactId);
+ User::LeaveIfError(underlyingViewIndex);
+ aEvent.iInt = KErrNone;
+ // get contact data from view rather than re-read from disk (speeds up access time)
+ const CViewContact& contact = iView.ContactAtL(underlyingViewIndex);
+ const TBool match=MatchesCriteriaL(contact,*iFindWords, iSearchType,iExtension);
+ if (match)
+ {
+ CViewContact* thisContact = CViewContact::NewL(contact);
+ // Insert using Sort Plugin compare method
+ const TInt insertError = InsertContact(thisContact);
+ if(insertError!=KErrNone)
+ {
+ delete thisContact;
+ User::Leave(insertError);
+ }
+
+ if(iClassVersion == KClassVersion2) //update iInt with the correct value
+ {
+ TInt pos = FindL(aEvent.iContactId);
+ if ( pos != KErrNotFound ) // contact is a member of our list
+ {
+ aEvent.iInt = pos; //update the iInt according
+ }
+ }
+ }
+ }
+
+TContactItemId CContactFindView::AtL(TInt aIndex) const
+/** Gets the contact item ID at the specified index into the find view.
+
+@param aIndex Index of the contact item ID into the find view.
+@leave KErrNotFound aIndex is outside the bounds of the array.
+@return The contact item ID. */
+ {
+ if(aIndex>=iFindContacts.Count())
+ {
+ //Out of Bounds.
+ User::Leave(KErrNotFound);
+ }
+ return (iFindContacts)[aIndex]->Id();
+ }
+
+const CViewContact& CContactFindView::ContactAtL(TInt aIndex) const
+/** Gets the contact item at the specified index into the view.
+
+@param aIndex Index into the view of the required item.
+@leave KErrNotFound aIndex is outside the bounds of the array.
+@return The contact item. */
+ {
+ if(aIndex>=iFindContacts.Count())
+ {
+ //Out of Bounds.
+ User::Leave(KErrNotFound);
+ }
+ return *(iFindContacts)[aIndex];
+ }
+
+TInt CContactFindView::CountL() const
+/** Gets the number of contact item IDs in the find view.
+
+@return The number of contact items in the find view. */
+ {
+ return iFindContacts.Count();
+ }
+
+TInt CContactFindView::FindL(TContactItemId aId) const
+/** Finds the index into the array of the specified contact item.
+
+@param aId The contact item ID to search for.
+@leave KErrNotReady The view is not ready for use.
+@return The index of the first matching item in the find view or KErrNotFound
+if no matching item can be found.
+*/
+ {
+ if(iState != EReady)
+ {
+ User::Leave(KErrNotReady);
+ }
+ TInt index=KErrNotFound;
+ CViewContact* contact = CViewContact::NewLC(aId);
+ index = iFindContacts.Find(contact,TIdentityRelation<CViewContact>(IdsMatch));
+ CleanupStack::PopAndDestroy(contact);
+ return index;
+ }
+
+HBufC* CContactFindView::AllFieldsLC(TInt aIndex,const TDesC& aSeparator) const
+/** Returns a descriptor containing the contents of all fields in an item in the
+view.
+
+The fields are separated by aSeparator.
+
+@param aIndex The index into the view of the contact item.
+@param aSeparator The string to use to separate the fields.
+@return Pointer to the contact item descriptor. */
+ {
+ return FieldsWithSeparatorLC(iFindContacts,aIndex,aSeparator);
+ }
+
+TContactViewPreferences CContactFindView::ContactViewPreferences()
+/** Gets the underlying view's view preferences.
+
+@return The view preferences. */
+ {
+ return iView.ContactViewPreferences();
+ }
+
+const RContactViewSortOrder& CContactFindView::SortOrderL() const
+/** Gets the underlying view's sort order.
+
+@return The sort order. */
+ {
+ return iView.SortOrderL();
+ }
+
+/**
+ * Do binary search of Contacts Array, and insert new contact.
+ * Uses current Sort Plugin, if any.
+ *
+ * @internalComponent
+ * @released
+ */
+TInt CContactFindView::InsertContact(const CViewContact* aNewContact)
+ {
+ TInt error = KErrNone;
+
+ if (iFindContacts.Count() == 0)
+ { // easy
+ error = iFindContacts.Append(aNewContact);
+ }
+ else
+ {
+ // To insert in correct order we use parent view & its Sort method (Plug-in).
+ // Virtual Function 3 calls CContactViewBase::InsertContactInView() method
+ // in the parent view.
+ TVirtualFunction3Params vFuncParams(iFindContacts,aNewContact);
+
+ error = reinterpret_cast<TInt>(iView.CContactViewBase_Reserved_1(CContactViewBase::ECContactViewBaseVirtualFunction3, &vFuncParams));
+ }
+
+ return error;
+ }
+