--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook/View/src/CPbkJapaneseFindPrimitives.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,299 @@
+/*
+* Copyright (c) 2002 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:
+* MPbkFindPrimitives implementation for Japanese Phonebook.
+*
+*/
+
+
+// INCLUDE FILES
+#include "CPbkJapaneseFindPrimitives.h"
+#include <MPbkContactNameFormat.h>
+#include <MPbkFieldData.h>
+#include <PbkViewContactFieldDataAdapter.h>
+#include <PbkEngUtils.h>
+//#define PBK_ENABLE_DEBUG_PRINT
+#include <PbkDebug.h>
+
+namespace {
+
+const TInt KMinTextBufSize = 32;
+
+// ================= LOCAL FUNCTIONS =======================
+
+/**
+ * Normalizes text by converting all sequences of space characters to a
+ * single space.
+ *
+ * @param aBuffer buffer where the normalized text will be stored. The buffer
+ * will be reallocated if necessary.
+ * @param aText the text to be normalized.
+ * @return normalized text.
+ */
+const TDesC& NormalizeL(HBufC*& aBuffer, const TDesC& aText)
+ {
+ const TInt textLength = aText.Length();
+ aBuffer = PbkEngUtils::AllocL(aBuffer, Max(textLength,KMinTextBufSize));
+ TPtr bufPtr(aBuffer->Des());
+ bufPtr.Zero();
+ TBool uncommittedSpace = EFalse;
+ for (TInt i=0; i < textLength; ++i)
+ {
+ TChar ch(aText[i]);
+ if (ch.IsSpace())
+ {
+ uncommittedSpace = ETrue;
+ }
+ else
+ {
+ if (uncommittedSpace)
+ {
+ bufPtr.Append(' ');
+ uncommittedSpace = EFalse;
+ }
+ bufPtr.Append(ch);
+ }
+ }
+ // copy final trailing space
+ if (uncommittedSpace)
+ {
+ bufPtr.Append(' ');
+ }
+
+ return (*aBuffer);
+ }
+
+}
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+inline CPbkJapaneseFindPrimitives::CPbkJapaneseFindPrimitives(MPbkContactNameFormat& aNameFormatter) :
+ iNameFormatter(aNameFormatter)
+ {
+ }
+
+CPbkJapaneseFindPrimitives* CPbkJapaneseFindPrimitives::NewL(MPbkContactNameFormat& aNameFormatter)
+ {
+ CPbkJapaneseFindPrimitives* self = new(ELeave) CPbkJapaneseFindPrimitives(aNameFormatter);
+ return self;
+ }
+
+CPbkJapaneseFindPrimitives::~CPbkJapaneseFindPrimitives()
+ {
+ delete iFindText;
+ delete iFieldText;
+ delete iInitialFindText;
+ iViewSortOrder.Close();
+ }
+
+inline TBool CPbkJapaneseFindPrimitives::IsWordSeparator(TChar aCh)
+ {
+ return aCh.IsSpace();
+ }
+
+void CPbkJapaneseFindPrimitives::SetContactViewSortOrderL
+ (const RContactViewSortOrder& aSortOrder)
+ {
+ iViewSortOrder.CopyL(aSortOrder);
+ }
+
+/**
+ * Stores the initial find text.
+ *
+ * @see InitialFindText
+ * @see MatchesInitialFindText
+ */
+inline void CPbkJapaneseFindPrimitives::StoreInitialFindTextL
+ (const TDesC& aInitialFindText)
+ {
+ iInitialFindText = PbkEngUtils::CopyL
+ (iInitialFindText, aInitialFindText, aInitialFindText.Length()+1);
+ TPtr ptr(iInitialFindText->Des());
+ ptr.Append('*');
+ }
+
+/**
+ * Returns the initial find text passed to StoreInitialFindTextL.
+ *
+ * @see StoreInitialFindTextL
+ * @see MatchesInitialFindText
+ */
+inline TPtrC CPbkJapaneseFindPrimitives::InitialFindText() const
+ {
+ TPtrC result;
+ if (iInitialFindText)
+ {
+ // Strip trailing '*' appended for matching in StoreInitialFindTextL
+ return iInitialFindText->Left(iInitialFindText->Length()-1);
+ }
+ return result;
+ }
+
+/**
+ * Matches (Using TDesC::MatchC) the initial find text against aText. Returns
+ * ETrue if aText matches the initial find text.
+ *
+ * @see StoreInitialFindTextL
+ * @see InitialFindText
+ */
+inline TBool CPbkJapaneseFindPrimitives::DoMatchesInitialFindText
+ (const TDesC& aText) const
+ {
+ if (iInitialFindText)
+ {
+ return (aText.MatchC(*iInitialFindText) != KErrNotFound);
+ }
+ return EFalse;
+ }
+
+/**
+ * Does a prefix matching of aFindText to aContactData.
+ *
+ * @param aContactData contact data to match against. Matching is done in
+ * field order.
+ * @param aFindText normalized (see NormalizeL) find text.
+ */
+inline TBool CPbkJapaneseFindPrimitives::IsMatchL
+ (const MPbkFieldDataArray& aContactData, const TDesC& aFindText)
+ {
+ TPtrC findText(aFindText);
+ const TInt fieldCount = aContactData.PbkFieldCount();
+ for (TInt i=0; i < fieldCount; ++i)
+ {
+ const TDesC& fieldText =
+ NormalizeL(iFieldText, aContactData.PbkFieldAt(i).PbkFieldText());
+ TInt matchLen = Min(fieldText.Length(), findText.Length());
+ if (fieldText.Left(matchLen).MatchC
+ (findText.Left(matchLen)) != KErrNotFound)
+ {
+ // Require space in find text between fields
+ if (matchLen < findText.Length())
+ {
+ if (TChar(findText[matchLen]).IsSpace() &&
+ i < fieldCount-1)
+ {
+ // Skip space
+ ++matchLen;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+ // Consume findText
+ findText.Set(findText.Mid(matchLen));
+ }
+ }
+
+ // Find text must be fully consumed for a match
+ return (findText.Length() == 0);
+ }
+
+
+
+/**
+ * Converts aViewContact to MPbkFieldDataArray and calls
+ * IsMatchL(const MPbkFieldDataArray& aContactData, const TDesC& aFindText).
+ */
+TBool CPbkJapaneseFindPrimitives::IsMatchL
+ (const CViewContact& aViewContact, const TDesC& aFindText)
+ {
+ TBool ret = EFalse;
+
+ // Convert aViewContact to MPbkFieldDataArray
+ const TPbkViewContactFieldDataArray contactData
+ (aViewContact, iViewSortOrder);
+
+ // Filter contactData to contain only fields used in find
+ const MPbkFieldDataArray& titleData =
+ iNameFormatter.FilterContactTitleFields(contactData);
+
+ // Try to match with title fields first
+ ret = IsMatchL(titleData, aFindText);
+
+ // Do matching
+ if (!ret)
+ {
+ // If title field find was not succesfull, try with
+ // reading fields only
+ const MPbkFieldDataArray& findData =
+ iNameFormatter.FilterContactFieldsForFind(contactData);
+
+ ret = IsMatchL(findData, aFindText);
+ }
+
+ return ret;
+ }
+
+TBool CPbkJapaneseFindPrimitives::IsFindMatchL
+ (const CViewContact& aViewContact, const TDesC& aFindText)
+ {
+ // Normalize aFindText by removing all extra spaces
+ const TDesC& findText = NormalizeL(iFindText,aFindText);
+
+ // Do matching
+ return IsMatchL(aViewContact,findText);
+ }
+
+void CPbkJapaneseFindPrimitives::GetInitialMatchesL
+ (CContactViewBase& aView,
+ const TDesC& aFindText,
+ RPointerArray<CViewContact>& aMatchedContacts)
+ {
+ // Make first match with CContactViewBase::ContactsMatchingPrefixL
+ MDesCArray* findWords = PbkEngUtils::BreakInWordsLC
+ (aFindText, IsWordSeparator);
+ aView.ContactsMatchingPrefixL(*findWords, aMatchedContacts);
+ CleanupStack::PopAndDestroy(); // findWords
+ PBK_DEBUG_PRINT(PBK_DEBUG_STRING("CPbkJapaneseFindPrimitives::GetInitialMatchesL(%S): contact model returned %d matches"),
+ &aFindText, aMatchedContacts.Count());
+
+ StoreInitialFindTextL(aFindText);
+
+ // Filter away contacts that do not fullfill this implementation's criteria
+ const TDesC& normFindText = NormalizeL(iFindText,aFindText);
+ for (TInt i=aMatchedContacts.Count()-1; i >= 0; --i)
+ {
+ CViewContact* contact = aMatchedContacts[i];
+ if (!IsMatchL(*contact,normFindText))
+ {
+ aMatchedContacts.Remove(i);
+ delete contact;
+ }
+ }
+ }
+
+TBool CPbkJapaneseFindPrimitives::MatchesInitialFindTextL(const TDesC& aText)
+ {
+ // NOTE: This must work the same way as cntmodel's matching! Otherwise
+ // we get problems in hungarian or czech matching with double-characters.
+ // The main problem case is in CFindState::SetFindTextL(). If you
+ // make this work differently from cntmodel's match, make sure
+ // it still works with hungarian "gy" or czech "ch" and "agy" etc...
+ return DoMatchesInitialFindText(aText);
+ }
+
+TBool CPbkJapaneseFindPrimitives::MatchesInitialFindTextL(const CViewContact& aViewContact)
+ {
+ TPtrC findText(InitialFindText());
+ if (findText.Length() > 0)
+ {
+ return IsMatchL(aViewContact,findText);
+ }
+ return EFalse;
+ }
+
+
+// End of File