src/hbcore/i18n/hbstringutil.cpp
changeset 0 16d8024aca5e
child 1 f7ac710697a9
equal deleted inserted replaced
-1:000000000000 0:16d8024aca5e
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbCore module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 
       
    26 #include <hbextendedlocale.h>
       
    27 #include <QtAlgorithms>
       
    28 
       
    29 #include "hbstringutil_p.h"
       
    30 #include "hbstringutil.h"
       
    31 
       
    32 #if defined(__SYMBIAN32__)
       
    33 #include <e32std.h>
       
    34 #include <e32def.h>
       
    35 #include <e32des16.h>
       
    36 #include <collate.h>
       
    37 #define Q_OS_SYMBIAN
       
    38 #endif
       
    39 
       
    40 #ifndef QT_NO_REGEXP
       
    41 #include <QRegExp>
       
    42 #endif
       
    43 
       
    44 /*!
       
    45     @beta
       
    46     @hbcore
       
    47     \class HbStringUtil
       
    48     \brief The HbStringUtil class can be used to execute operations on strings,
       
    49     such as comparisons and finding data sequences.
       
    50 
       
    51     \ingroup i18n
       
    52 
       
    53     \warning This class is only useful in Symbian platforms since it uses Symbian
       
    54     methods in order to implement different functionalities.
       
    55 
       
    56     \sa HbStringUtil
       
    57 */
       
    58 
       
    59 /*!
       
    60     \enum HbStringUtil::Option
       
    61 
       
    62     This enum describes the way collation is done for matchC, compareC
       
    63     Pass one of these values to setReadChannel() to set the
       
    64     current read channel of QProcess.
       
    65 
       
    66     \value Default          Use the default System flags.
       
    67      
       
    68     \value IgnoreNone       Don't ignore anything.
       
    69     
       
    70     \value SwapCase         Reverse case ordering.
       
    71     
       
    72     \value AccentsBackwards Compare secondary keys which represent accents in reverse order.
       
    73     
       
    74     \value SwapKana         Reverse order for katakana/hiragana.
       
    75     
       
    76     \value FoldCase         Fold to lower case, file comparisons.
       
    77     
       
    78     \value MatchingTable    Table used for matching.
       
    79     
       
    80     \value IgnoreCombining  Ignore check for adjacent combining characters. 
       
    81     
       
    82     \sa compareC, matchC
       
    83 */
       
    84 
       
    85 /*!
       
    86     \deprecated HbStringUtil::collationMethods()
       
    87         is deprecated.
       
    88     
       
    89     Returns the number of collation methods supported.
       
    90     On Symbian platform uses Mem::CollationMethods,
       
    91     elsewhere return 0.
       
    92      
       
    93     \return The number of collation methods available.
       
    94  */
       
    95 int HbStringUtil::collationMethods()
       
    96 {
       
    97     qWarning("HbStringUtil::collationMethods is DEPRECATED. Do not use this function.");
       
    98 #if defined( Q_OS_SYMBIAN )
       
    99     return Mem::CollationMethods();
       
   100 #else
       
   101     return 0;
       
   102 #endif 
       
   103 }
       
   104 
       
   105 /*!
       
   106     Searches source string's collated data for a
       
   107     match with collated data supplied in pattern string
       
   108     
       
   109     \param strFrom Source string.
       
   110     \param strToMatch Pattern string.
       
   111     \param maxLevel Determines the tightness of the collation.
       
   112     Level 0 - Character identity; 
       
   113     Level 1 - Character identity and accents; 
       
   114     Level 2 - Character identity, accents and case; 
       
   115     Level 3 - Character identity, accents, case and Unicode value; 
       
   116     \param flags The flags that will be used. Default value is Default.
       
   117     \param wildChar Wild card character.
       
   118     \param wildSequenceChar Wild card sequence character.
       
   119     \param escapeChar The escape character, for example,  '?', '*'.
       
   120     \return If a match is found the offset within source string's
       
   121     data where the match first occurs. -1 if match is not found.
       
   122     
       
   123     Example
       
   124     \snippet{unittest_hbstringutil/unittest_hbstringutil.cpp,3}
       
   125  */
       
   126 int HbStringUtil::matchC( const QString &strFrom, const QString &strToMatch,
       
   127                                     int maxLevel, Options flags,
       
   128                                     int wildChar, int wildSequenceChar, int escapeChar )
       
   129 {
       
   130 #if defined( Q_OS_SYMBIAN )
       
   131     TPtrC s1Ptr( strFrom.utf16() );
       
   132     TPtrC s2Ptr( strToMatch.utf16() );
       
   133 
       
   134 	if ( (maxLevel < 0) || (maxLevel > 3) ) {
       
   135 		maxLevel = 0;
       
   136 	}
       
   137     if ( (flags < 0) || (flags > 127) ) {
       
   138         flags = Default;
       
   139     }
       
   140 
       
   141     TCollationMethod m = *Mem::GetDefaultMatchingTable();
       
   142     m.iFlags |= flags;
       
   143 
       
   144     return s1Ptr.MatchC(s2Ptr, wildChar, wildSequenceChar, escapeChar, maxLevel, &m);
       
   145 #else
       
   146     Q_UNUSED(maxLevel);
       
   147     Q_UNUSED(flags);
       
   148     Q_UNUSED(wildChar);
       
   149     Q_UNUSED(wildSequenceChar);
       
   150     Q_UNUSED(escapeChar);
       
   151 #ifdef QT_NO_REGEXP
       
   152     // if no regular expressions defined do standard MatchF
       
   153     return strFrom.indexOf( strToMatch, 0, Qt::CaseSensitive );
       
   154 #else    
       
   155     // works with standard wildcards is not correct
       
   156     QRegExp locStrToMatch( strToMatch, Qt::CaseSensitive, QRegExp::Wildcard );    
       
   157     return strFrom.indexOf( locStrToMatch, 0 );
       
   158 #endif    
       
   159     
       
   160 #endif
       
   161 }
       
   162 
       
   163 /*!
       
   164     Compares source string's data with the other string's
       
   165     data using the specified collation method.
       
   166     
       
   167     \param string1 Source string.
       
   168     \param string2 String whose data is to be compared with the source string.
       
   169     \param maxLevel Maximum level to use for comparing.
       
   170     Level 0 - Character identity; 
       
   171     Level 1 - Character identity and accents; 
       
   172     Level 2 - Character identity, accents and case; 
       
   173     Level 3 - Character identity, accents, case and Unicode value; 
       
   174     \param flags The flags that will be used. Default value is Default.
       
   175     \return Positive if source string is greater, negative if it is less and 
       
   176     zero	if the content of both strings match.
       
   177     
       
   178     Example
       
   179     \snippet{unittest_hbstringutil/unittest_hbstringutil.cpp,1}
       
   180  */
       
   181 int HbStringUtil::compareC( const QString &string1, const QString &string2,
       
   182                                         int maxLevel, Options flags )
       
   183 {
       
   184 #if defined( Q_OS_SYMBIAN )
       
   185     TPtrC s1Ptr(string1.utf16());
       
   186     TPtrC s2Ptr(string2.utf16());
       
   187    
       
   188 	if ( (maxLevel < 0) || (maxLevel > 3) ) {
       
   189 		maxLevel = 3;
       
   190 	}
       
   191     if ( (flags < 0) || (flags > 127) ) {
       
   192         flags = Default;
       
   193     }
       
   194     
       
   195     TCollationMethod m = *Mem::CollationMethodByIndex( 0 );
       
   196     m.iFlags |= flags;
       
   197 
       
   198     return s1Ptr.CompareC( s2Ptr, maxLevel, &m);
       
   199 #else
       
   200     Q_UNUSED(maxLevel);
       
   201     Q_UNUSED(flags);
       
   202     return string1.localeAwareCompare( string2 );
       
   203 #endif    
       
   204 }
       
   205 
       
   206 /*!
       
   207     Searches for the first occurence of the specified collated 
       
   208     data sequence in the aStrFrom to the specified maximum
       
   209     collation level.
       
   210     
       
   211     \param strFrom Source string.
       
   212     \param strToFind String whose data is to be compared with the source string.
       
   213     \param maxLevel The maximum collation level.
       
   214     Level 0 - Character identity; 
       
   215     Level 1 - Character identity and accents; 
       
   216     Level 2 - Character identity, accents and case; 
       
   217     Level 3 - Character identity, accents, case and Unicode value; 
       
   218     \return Offset of the data sequence from the beginning of the
       
   219     aStrFrom. -1 if the data sequence cannot be found.
       
   220     
       
   221     Example
       
   222     \snippet{unittest_hbstringutil/unittest_hbstringutil.cpp,5}
       
   223  */
       
   224 int HbStringUtil::findC( const QString &strFrom,
       
   225                          const QString &strToFind,
       
   226                          int           maxLevel )
       
   227 {
       
   228 #if defined( Q_OS_SYMBIAN )
       
   229     TPtrC s1Ptr( strFrom.utf16() );
       
   230     TPtrC s2Ptr( strToFind.utf16() );
       
   231     
       
   232 	if ( (maxLevel < 0) || (maxLevel > 3) ) {
       
   233 		maxLevel = 0;
       
   234 	}
       
   235     return s1Ptr.FindC( s2Ptr.Ptr(),
       
   236                         s2Ptr.Length(),
       
   237                         maxLevel );
       
   238 #else
       
   239     Q_UNUSED(maxLevel);
       
   240     return strFrom.indexOf( strToFind, 0, Qt::CaseSensitive );
       
   241 #endif 
       
   242 }
       
   243 
       
   244 /*!
       
   245     Searches source string's folded data for a
       
   246     match with folded data supplied in pattern string
       
   247     
       
   248     \param strFrom Source string.
       
   249     \param strToMatch Pattern string.
       
   250     \return If a match is found the offset within source string's
       
   251     data where the match first occurs. -1 if match is not found.
       
   252     
       
   253     Example
       
   254     \snippet{unittest_hbstringutil/unittest_hbstringutil.cpp,4}
       
   255  */
       
   256 int HbStringUtil::matchF( const QString &strFrom,
       
   257                           const QString &strToMatch )
       
   258 {
       
   259 #if defined( Q_OS_SYMBIAN )
       
   260     TPtrC s1Ptr( strFrom.utf16() );
       
   261     TPtrC s2Ptr( strToMatch.utf16() );
       
   262     return s1Ptr.MatchF( s2Ptr );
       
   263 #else
       
   264     // folding is just case insensitive      
       
   265 #ifdef QT_NO_REGEXP
       
   266     // if no regular expressions defined do standard FindF
       
   267     return strFrom.indexOf( strToMatch, 0, Qt::CaseInsensitive );
       
   268 #else    
       
   269     QRegExp locStrToMatch( strToMatch, Qt::CaseInsensitive, QRegExp::Wildcard );
       
   270     return strFrom.indexOf( locStrToMatch, 0 );
       
   271 #endif
       
   272     
       
   273 #endif      
       
   274 }
       
   275 
       
   276 /*!
       
   277     Searches for the first occurence of the specified folded 
       
   278     data sequence in the strFrom.
       
   279     
       
   280     \param strFrom Source string.
       
   281     \param strToFind String whose data is to be compared with the source string.
       
   282     \return Offset of the data sequence from the beginning of the
       
   283     strFrom. -1 if the data sequence cannot be found. Zero,
       
   284     if the length of search data sequence is zero.
       
   285     
       
   286     Example
       
   287     \snippet{unittest_hbstringutil/unittest_hbstringutil.cpp,6}
       
   288  */
       
   289 int HbStringUtil::findF( const QString &strFrom,
       
   290                          const QString &strToFind )
       
   291 {
       
   292 #if defined( Q_OS_SYMBIAN )
       
   293     TPtrC s1Ptr( strFrom.utf16() );
       
   294     TPtrC s2Ptr( strToFind.utf16() );
       
   295     return s1Ptr.FindF( s2Ptr );
       
   296 #else
       
   297     // folding is just case insensitive    
       
   298     return strFrom.indexOf( strToFind, 0, Qt::CaseInsensitive );   
       
   299 #endif 
       
   300 }
       
   301 
       
   302 /*!
       
   303     Compares source string's folded data with the other string's
       
   304     folded data.
       
   305     
       
   306     \param string1 Source string.
       
   307     \param string2 String whose data is to be compared with the source string.
       
   308     \return Positive if source string is greater, negative if it is less and 
       
   309     zero if the content of both strings match.
       
   310     
       
   311     Example
       
   312     \snippet{unittest_hbstringutil/unittest_hbstringutil.cpp,2}
       
   313  */
       
   314 int HbStringUtil::compareF( const QString &string1,
       
   315                             const QString &string2 )
       
   316 {
       
   317 #if defined( Q_OS_SYMBIAN )
       
   318     TPtrC s1Ptr( string1.utf16() );
       
   319     TPtrC s2Ptr( string2.utf16() );
       
   320     return s1Ptr.CompareF( s2Ptr );
       
   321 #else
       
   322     // folding is just case insensitive     
       
   323     return string1.compare( string2, Qt::CaseInsensitive );   
       
   324 #endif 
       
   325 }
       
   326 
       
   327 /*!
       
   328     \deprecated HbStringUtil::collate( const uint chr )
       
   329         is deprecated.
       
   330     
       
   331     Converts the character to its collated form.
       
   332     Collating is the process of removing differences between characters 
       
   333     that are considered unimportant for the purposes of ordering characters.
       
   334     The result of the conversion depends on the locale
       
   335     
       
   336     \param chr The charcter to be collated.
       
   337     \return The converted character.
       
   338  */
       
   339 uint HbStringUtil::collate( const uint chr )
       
   340 {
       
   341     qWarning("HbStringUtil::collate is DEPRECATED. Do not use this function.");
       
   342 #if defined( Q_OS_SYMBIAN )
       
   343     return User::Collate( chr );
       
   344 #else
       
   345     return chr;
       
   346 #endif 
       
   347 }
       
   348 
       
   349 /*!
       
   350     Returns the starting digit range of the native digit
       
   351     \param ch native digit
       
   352     \return starting digit range
       
   353  */
       
   354 static QChar nativeDigitBase(QChar ch)
       
   355 {
       
   356 	DigitType d[] = { WesternDigit, ArabicIndicDigit, EasternArabicIndicDigit, DevanagariDigit, ThaiDigit };
       
   357     int i = 0;
       
   358     int num = sizeof(d)/sizeof(d[0]);
       
   359     while(i<num) {
       
   360         if (ch>QChar(d[i]) && ch<QChar(d[i]+10)) { return d[i]; }
       
   361         i++;
       
   362     }
       
   363     return ch;
       
   364 }
       
   365 
       
   366 /*!
       
   367     Converts digits to native digits based on current UI language.
       
   368     \param str digits to be converted.
       
   369  */
       
   370 QString HbStringUtil::convertDigits( const QString str ) 
       
   371 {
       
   372 	HbExtendedLocale locale = HbExtendedLocale::system();
       
   373 	DigitType digitType = WesternDigit;
       
   374 	if (locale.language() == HbExtendedLocale::Arabic) {
       
   375 		digitType = ArabicIndicDigit;
       
   376 	}
       
   377 	if (locale.language() == HbExtendedLocale::Persian) {
       
   378 		digitType = EasternArabicIndicDigit;
       
   379 	}
       
   380 	if (locale.language() == HbExtendedLocale::Urdu) {
       
   381 		digitType = EasternArabicIndicDigit;
       
   382 	}
       
   383 	QString converted = HbStringUtil::convertDigitsTo(str, digitType);
       
   384 	return converted;
       
   385 }
       
   386 
       
   387 /*!
       
   388     Converts the digit from Latin to native or native to latin or native to native
       
   389     \param str digits to be converted.
       
   390     \param digitType type of the digit to be converted to
       
   391  */
       
   392 QString HbStringUtil::convertDigitsTo( const QString str, const DigitType digitType ) 
       
   393 {
       
   394     QString convDigit;
       
   395 	int length = str.length();
       
   396     for(int i=0; i<length; i++) 
       
   397        {
       
   398        ushort digit = str[i].unicode();
       
   399        ushort digitBase = nativeDigitBase(str[i]).unicode();
       
   400        ushort convertedDigit = 0;
       
   401        switch (digitBase) 
       
   402            {
       
   403            case WesternDigit:
       
   404            case ArabicIndicDigit:
       
   405            case EasternArabicIndicDigit:
       
   406            case DevanagariDigit:
       
   407            case ThaiDigit:
       
   408                convertedDigit += digitType + digit - digitBase; 
       
   409                convDigit[i] = QChar(convertedDigit);
       
   410                break;
       
   411            default:
       
   412         	   convDigit[i] = QChar(digit);
       
   413                break;
       
   414            };
       
   415        }
       
   416     return convDigit;
       
   417 }
       
   418 
       
   419 /*!
       
   420     Sorts QStrings into alphabetically order (overwrites the strList's original content)
       
   421     
       
   422     \param strList List of QStrings which need to be sorted.
       
   423     
       
   424     Example
       
   425     \snippet{unittest_hbstringutil/unittest_hbstringutil.cpp,7}
       
   426  */
       
   427 void HbStringUtil::sort( QStringList &strList )
       
   428 {
       
   429 	if ( strList.size() > 1 ) {
       
   430 		qSort(strList.begin(), strList.end(), hbStringUtil_SortHelper);
       
   431 	}
       
   432 }
       
   433 
       
   434 bool hbStringUtil_SortHelper( const QString &s1, const QString &s2 )
       
   435 {
       
   436 	if ( HbStringUtil::compareC(s1, s2) < 0 ) {
       
   437 		// s1 is before s2
       
   438 		return true;
       
   439 	} else {
       
   440 		// s1 is after s2 (or they are equal) 
       
   441 		return false;
       
   442 	}			
       
   443 }