src/hbcore/i18n/hbextendedlocale.cpp
changeset 0 16d8024aca5e
child 1 f7ac710697a9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hbcore/i18n/hbextendedlocale.cpp	Mon Apr 19 14:02:13 2010 +0300
@@ -0,0 +1,2000 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (developer.feedback@nokia.com)
+**
+** This file is part of the HbCore module of the UI Extensions for Mobile.
+**
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at developer.feedback@nokia.com.
+**
+****************************************************************************/
+
+#include <qglobal.h>
+#include <QDate>
+#include <QtDebug>
+#include <qvariant.h>
+#if defined(Q_OS_SYMBIAN)
+#include <e32std.h>
+#include <e32def.h>
+#include <e32des16.h>
+#include <e32const.h>
+#include <e32base.h> 
+#endif
+
+#include "hbextendedlocale.h"
+
+static const int CURRENCY_FORMAT_SIZE_STEP = 8; 
+
+#if defined(Q_OS_SYMBIAN)
+
+static TExtendedLocale _symbianLocale;
+
+QT_BEGIN_NAMESPACE
+
+TPtrC QString2TPtrC( const QString& string )
+{
+    return TPtrC16(static_cast<const TUint16*>(string.utf16()), string.length());
+}
+HBufC* QString2HBufC(const QString& aString)
+{
+    HBufC *buffer;
+#ifdef QT_NO_UNICODE
+    TPtrC8 ptr(reinterpret_cast<const TUint8*>(aString.toLocal8Bit().constData()));
+#else
+    TPtrC16 ptr(QString2TPtrC(aString));
+#endif
+    buffer = HBufC::New(ptr.Length());
+    Q_CHECK_PTR(buffer);
+    buffer->Des().Copy(ptr);
+    return buffer;
+}
+
+QString TDesC2QString(const TDesC& aDescriptor)
+{
+#ifdef QT_NO_UNICODE
+    return QString::fromLocal8Bit(aDescriptor.Ptr(), aDescriptor.Length());
+#else
+    return QString::fromUtf16(aDescriptor.Ptr(), aDescriptor.Length());
+#endif
+}
+
+QT_END_NAMESPACE
+
+#endif
+
+/*!
+    @stable
+    @hbcore
+    \class HbExtendedLocale
+    \brief The HbExtendedLocale class is extension class to QLocale.
+    It provides methods to access Symbian locale data absent from QLocale.
+    Methods mainly focus to date and time related issues.
+
+    Examples:
+
+    \snippet{unittest_hbextendedlocale/unittest_hbextendedlocale.cpp,1}
+    
+    \snippet{unittest_hbextendedlocale/unittest_hbextendedlocale.cpp,2}
+
+    \snippet{unittest_hbextendedlocale/unittest_hbextendedlocale.cpp,3}
+
+    \snippet{unittest_hbextendedlocale/unittest_hbextendedlocale.cpp,4}
+    
+    \snippet{unittest_hbextendedlocale/unittest_hbextendedlocale.cpp,5}
+    
+    \snippet{unittest_hbextendedlocale/unittest_hbextendedlocale.cpp,6}
+    
+    \snippet{unittest_hbextendedlocale/unittest_hbextendedlocale.cpp,7}
+    
+    \snippet{unittest_hbextendedlocale/unittest_hbextendedlocale.cpp,8}
+
+    \snippet{unittest_hbextendedlocale/unittest_hbextendedlocale.cpp,9}
+
+    \snippet{unittest_hbextendedlocale/unittest_hbextendedlocale.cpp,10}
+    
+    \snippet{unittest_hbextendedlocale/unittest_hbextendedlocale.cpp,11}
+    
+    \sa QLocale
+*/
+
+/*!
+    Returns the date separator, which can occur in four different positions:
+    Beginning of the expression
+    Between the first and second part
+    Between the second and third part
+    At the end of the expression
+    Some of the positions may contain an empty string if a separator is not used in that position in the locale in question
+
+    \return one of the four characters used to separate the day,
+    month and year components of the date according to the
+    system locale.
+
+    \param index Index of the separator (0-3)
+ */
+QChar HbExtendedLocale::dateSeparator( int index ) const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();	
+    TChar val = _symbianLocale.GetLocale()->DateSeparator(index);
+    return QChar(val);
+#else
+    if ( index > 0 && index < 3 ) {
+        return QLatin1Char('/');
+    } else {
+        return QChar();
+    }
+#endif
+}
+
+/*!
+    Sets one of the four characters used to separate the day, 
+    month and year components of the date according to the
+    system locale.
+ 
+    \param ch Character to set,
+    \param index Index of the separator (0-3)
+ 
+    \return true for Symbian if succesfull and false for other OS
+ */
+bool HbExtendedLocale::setDateSeparator( const QChar ch, const int index )
+{
+#if defined(Q_OS_SYMBIAN)
+    if ( index < 0 || index > 3 ) {
+        return false;
+    }
+    _symbianLocale.LoadSystemSettings();	
+    TChar symbianch( ch.unicode() );
+    _symbianLocale.GetLocale()->SetDateSeparator(symbianch, index);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(ch);
+    Q_UNUSED(index);
+    return false;
+#endif
+}
+
+/*!
+    Retrieves the time separator (for example, colon or full stop)
+    
+    \return one of the four characters used to separate the hour,
+    minute and second components of the date according to the
+    system locale.
+
+    \param index Index of the separator (0-3)
+ */
+QChar HbExtendedLocale::timeSeparator( int index ) const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    TChar val = _symbianLocale.GetLocale()->TimeSeparator(index);
+    return QChar(val);
+#else
+    if ( index > 0 && index < 3 ) {
+        return QLatin1Char(':');
+    } else {
+        return QChar();
+    }
+#endif
+}
+
+/*!
+    Sets one of the four characters used to separate the hour,
+    minute and second components of the date.
+
+    \param ch Character to set,
+    \param index Index of the separator (0-3)
+    
+    \return true for Symbian if succesfull and false for other OS
+ */
+bool HbExtendedLocale::setTimeSeparator( const QChar ch, const int index )
+{
+#if defined(Q_OS_SYMBIAN)
+    if ( index < 0 || index > 3 ) {
+        return false;
+    }
+    
+    _symbianLocale.LoadSystemSettings();
+    TChar symbianch( ch.unicode() );
+    _symbianLocale.GetLocale()->SetTimeSeparator(symbianch, index);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(ch);
+    Q_UNUSED(index);
+    return false;
+#endif
+}
+
+/*! 
+    \enum HbExtendedLocale::DateStyle
+    returns the order of the date components: day-month-year (the most commonly used format)
+    month-day-year (mostly used in the U.S. and Canada)
+    or year-month-day (used, for example, in Japanese, Chinese and Swedish)
+    This enum defines the order of date components.
+
+      \value American American order (mm/dd/yyyy)
+      \value European European order (dd/mm/yyyy)
+      \value Japanese Japanese order (yyyy/mm/dd)
+
+    \sa dateStyle(), setDateStyle()
+ */
+
+/*!
+    \return date style from system locale. The date style is returned according to DateStyle.
+ */
+HbExtendedLocale::DateStyle HbExtendedLocale::dateStyle() const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    TDateFormat val = _symbianLocale.GetLocale()->DateFormat();
+
+    switch ( val ) {
+    case EDateAmerican:
+        // mm/dd/yyyy
+        return HbExtendedLocale::American;
+    case EDateEuropean:
+        // dd/mm/yyyy
+        return HbExtendedLocale::European;
+    case EDateJapanese:
+        // yyyy/mm/dd
+        return HbExtendedLocale::Japanese;
+    }
+    return HbExtendedLocale::American;
+#else
+    return HbExtendedLocale::American;
+#endif
+}
+
+/*!
+    Sets date style to system locale.
+    The date style is chosen according to the \a style parameter.
+
+    \return true for Symbian and false for other OS
+ */
+bool HbExtendedLocale::setDateStyle( const DateStyle style )
+{
+#if defined(Q_OS_SYMBIAN)
+    TDateFormat set;
+
+    switch ( style ) {
+    default:
+    case HbExtendedLocale::American:
+        set = EDateAmerican;
+        break;
+    case HbExtendedLocale::European:
+        set = EDateEuropean;
+        break;
+    case HbExtendedLocale::Japanese:
+        set = EDateJapanese;
+        break;
+    }
+
+    _symbianLocale.LoadSystemSettings();
+    _symbianLocale.GetLocale()->SetDateFormat(set);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(style);
+    return false;
+#endif
+}
+
+
+/*! 
+    \enum HbExtendedLocale::TimeStyle
+
+    Finds out if the 12-hour or the 24-hour clock is used
+     \value Time12 12 hour clock style
+     \value Time24 24 hour clock style
+
+    \sa timeStyle(), setTimeStyle()
+ */
+
+/*!
+    \return time style from system locale. The time style is returned according to TimeStyle.
+ */
+HbExtendedLocale::TimeStyle HbExtendedLocale::timeStyle() const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    TTimeFormat val = _symbianLocale.GetLocale()->TimeFormat();
+
+    switch ( val ) {
+    case ETime12:
+        return HbExtendedLocale::Time12;
+    case ETime24:
+        return HbExtendedLocale::Time24;
+    }
+    return HbExtendedLocale::Time12;
+#else
+    return HbExtendedLocale::Time12;
+#endif
+}
+
+/*!
+    Sets time style to system locale.
+    The time style is chosen according to the \a style parameter.
+
+    \return true for Symbian and false for other OS
+ */
+bool HbExtendedLocale::setTimeStyle( const TimeStyle style )
+{
+#if defined(Q_OS_SYMBIAN)
+    TTimeFormat set;
+    switch ( style ) {
+    default:
+    case HbExtendedLocale::Time12:
+        set = ETime12;
+        break;
+    case HbExtendedLocale::Time24:
+        set = ETime24;
+        break;
+    }
+    
+    _symbianLocale.LoadSystemSettings();
+    _symbianLocale.GetLocale()->SetTimeFormat(set);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(style);
+    return false;
+#endif
+}
+
+
+/*!
+    Finds out if the AM/PM symbol is separated by a space from the time expression
+
+    \return true if space is inserted between the time and the preceding or trailing am/pm text; otherwise returns false.
+ */
+bool HbExtendedLocale::amPmSpace() const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    return _symbianLocale.GetLocale()->AmPmSpaceBetween();
+#else
+    return true;
+#endif
+}
+
+/*!
+    Sets whether a \a space is inserted between the time and the preceding or trailing am/pm text.
+
+    \return true for Symbian and false for other OS
+ */
+bool HbExtendedLocale::setAmPmSpace( const bool space )
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    _symbianLocale.GetLocale()->SetAmPmSpaceBetween(space);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(space);
+    return false;
+#endif
+}
+
+/*! 
+    \enum HbExtendedLocale::SymbolPos
+
+    \value Before
+     \value After
+
+    Retrieves the position of the AM/PM symbol (before or after the time expression)
+    \sa amPmSymbolPosition(), setAmPmSymbolPosition()
+    \sa currencySymbolPosition(), setCurrencySymbolPosition()
+ */
+
+/*!
+    \return Before if am/pm text is positioned before time; otherwise returns After.
+ */
+HbExtendedLocale::SymbolPos HbExtendedLocale::amPmSymbolPosition() const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    TLocalePos position = _symbianLocale.GetLocale()->AmPmSymbolPosition();
+    if ( position == ELocaleBefore ) {
+    	return HbExtendedLocale::Before;
+    } else if ( position == ELocaleAfter ) {			
+    	return HbExtendedLocale::After;
+    }
+#else
+    return HbExtendedLocale::After;
+#endif
+    return HbExtendedLocale::After;
+}
+
+/*!
+    Sets the am/pm text position.
+    The position is chosen according to the \a position parameter.
+
+    \return true for Symbian if succesfull and false for other OS
+ */
+bool HbExtendedLocale::setAmPmSymbolPosition( const SymbolPos position )
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    if ( position == ( HbExtendedLocale::Before ) ) {
+        _symbianLocale.GetLocale()->SetAmPmSymbolPosition(ELocaleBefore);
+    } else if ( position == ( HbExtendedLocale::After ) ) {
+        _symbianLocale.GetLocale()->SetAmPmSymbolPosition(ELocaleAfter);
+    } else {
+        return false;
+    }
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(position);
+    return false;
+#endif
+}
+
+/*! 
+    \enum HbExtendedLocale::UnitsFormat
+    Retrives the  measurement system (if metric or imperial units are in use) .
+    This enum defines which units are used for measurement.
+
+    \value Imperial This value indicates imperial units, such as inches and
+             miles. There are several distinct imperial systems in the world; this
+             value stands for the official United States imperial units.
+    \value Metric This value indicates metric units, such as meters,
+             centimeters and millimeters.
+
+    \sa unitsDistanceShort(), unitsDistanceLong()
+ */
+
+/*!
+    Retrives the  measurement system (if metric or imperial units are in use) 
+
+    \return short unit distance format from system locale. Format is specified by UnitsFormat.
+ */
+QLocale::MeasurementSystem HbExtendedLocale::unitsDistanceShort() const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    TUnitsFormat val = _symbianLocale.GetLocale()->UnitsDistanceShort();
+    switch ( val ) {
+    case EUnitsMetric:
+        return QLocale::MetricSystem;
+    case EUnitsImperial:
+        return QLocale::ImperialSystem;
+    }
+    return QLocale::MetricSystem;
+#else
+    return QLocale::MetricSystem;
+#endif
+}
+
+/*!
+    Sets short unit distance \a format to system locale.
+
+    \return true for Symbian and false for other OS
+ */
+bool HbExtendedLocale::setUnitsDistanceShort( const QLocale::MeasurementSystem format )
+{
+#if defined(Q_OS_SYMBIAN)    
+    TUnitsFormat set;
+
+    switch ( format ) {
+    default:
+    case QLocale::MetricSystem:
+    	set = EUnitsMetric;
+    	break;
+    case QLocale::ImperialSystem:
+    	set = EUnitsImperial;
+    	break;
+    }
+    
+    _symbianLocale.LoadSystemSettings();
+    _symbianLocale.GetLocale()->SetUnitsDistanceShort(set);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(format);
+    return false;
+#endif
+}
+
+/*!
+    \return long unit distance format from system locale. Format is specified by UnitsFormat.
+ */
+QLocale::MeasurementSystem HbExtendedLocale::unitsDistanceLong() const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    TUnitsFormat val = _symbianLocale.GetLocale()->UnitsDistanceLong();
+    switch ( val ) {
+    case EUnitsMetric:
+        return QLocale::MetricSystem;
+    case EUnitsImperial:
+        return QLocale::ImperialSystem;
+    }
+    return QLocale::MetricSystem;
+#else
+    return QLocale::MetricSystem;
+#endif
+}
+
+/*!
+    Sets long unit distance \a format to system locale.
+
+    \return true for Symbian and false for other OS
+ */
+bool HbExtendedLocale::setUnitsDistanceLong( const QLocale::MeasurementSystem format )
+{
+#if defined(Q_OS_SYMBIAN)
+    TUnitsFormat set;
+
+    switch ( format ) {
+    default:
+    case QLocale::MetricSystem:
+    	set = EUnitsMetric;
+    	break;
+    case QLocale::ImperialSystem:
+    	set = EUnitsImperial;
+    	break;
+    }
+    _symbianLocale.LoadSystemSettings();
+    _symbianLocale.GetLocale()->SetUnitsDistanceLong(set);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(format);
+    return false;
+#endif
+}
+
+/*!
+    Sets general unit distance \a format to system locale.
+
+    \return true for Symbian and -1 for other OS
+ */
+bool HbExtendedLocale::setUnitsGeneral( const QLocale::MeasurementSystem format )
+{
+#if defined(Q_OS_SYMBIAN)
+    TUnitsFormat set;
+
+    switch ( format ) {
+    default:
+    case QLocale::MetricSystem:
+    	set = EUnitsMetric;
+    	break;
+    case QLocale::ImperialSystem:
+    	set = EUnitsImperial;
+    	break;
+    }
+    _symbianLocale.LoadSystemSettings();
+    _symbianLocale.GetLocale()->SetUnitsGeneral(set);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(format);
+    return false;
+#endif
+}
+
+/*! 
+    \enum HbExtendedLocale::NegativeCurrencyFormat
+
+    Retrives the indicator for negative currency.
+    For example, by using a minus sign (with different options as to where it is placed),
+    or by placing the negative currency amount in parenthesis.
+
+    \value LeadingMinusSign      A minus sign is inserted before the currency symbol and value.
+    \value InBrackets            The currency value and symbol are enclosed in brackets (no minus sign is used).
+    \value TrailingMinusSign     A minus sign is inserted after the currency symbol and value.
+    \value InterveningMinusSign  A minus sign is inserted between the currency symbol and the value.
+
+    \sa negativeCurrencyFormat(), setNegativeCurrencyFormat()
+ */
+
+/*!
+    \return the negative currency format from system locale.
+ */
+HbExtendedLocale::NegativeCurrencyFormat HbExtendedLocale::negativeCurrencyFormat() const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    TLocale::TNegativeCurrencyFormat val = _symbianLocale.GetLocale()->NegativeCurrencyFormat();
+    switch ( val ) {
+    default:
+    case TLocale::ELeadingMinusSign:
+        return HbExtendedLocale::LeadingMinusSign;
+    case TLocale::EInBrackets:
+        return HbExtendedLocale::InBrackets;
+    case TLocale::ETrailingMinusSign:
+        return HbExtendedLocale::TrailingMinusSign;
+    case TLocale::EInterveningMinusSign:
+        return HbExtendedLocale::InterveningMinusSign;
+    }
+#else
+    return HbExtendedLocale::LeadingMinusSign;
+#endif
+}
+
+/*!
+    Sets negative currency \a format to system locale.
+
+    \return true for Symbian and false for other OS
+ */
+bool HbExtendedLocale::setNegativeCurrencyFormat( const NegativeCurrencyFormat format )
+{
+#if defined(Q_OS_SYMBIAN)
+    TLocale::TNegativeCurrencyFormat set;
+    switch ( format ) {
+    default:
+    case HbExtendedLocale::LeadingMinusSign:
+        set = TLocale::ELeadingMinusSign;
+        break;
+    case HbExtendedLocale::InBrackets:
+        set = TLocale::EInBrackets;
+        break;
+    case HbExtendedLocale::TrailingMinusSign:
+        set = TLocale::ETrailingMinusSign;
+        break;
+    case HbExtendedLocale::InterveningMinusSign:
+        set = TLocale::EInterveningMinusSign;
+        break;
+    }
+    _symbianLocale.LoadSystemSettings();
+    _symbianLocale.GetLocale()->SetNegativeCurrencyFormat(set);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(format);
+    return false;
+#endif
+}
+
+/*!
+    Finds out if the currency symbol is separated by a space from the amount.
+    \return true if negative currency values have a space between the currency symbol and the value; otherwise returns false.
+ */
+bool HbExtendedLocale::negativeCurrencySpace() const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    return !_symbianLocale.GetLocale()->NegativeLoseSpace(); // the not here is intended
+#else
+    return false;
+#endif
+}
+
+/*!
+    Sets whether negative currency values have a space between the currency symbol and the value.
+    
+    \param space True to set a flag which indicates that negative currency values should have
+           the space between the value and the symbol. False to unset it. 
+    
+    \return true for Symbian and false for other OS
+ */
+bool HbExtendedLocale::setNegativeCurrencySpace( const bool space )
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    _symbianLocale.GetLocale()->SetNegativeLoseSpace(!space); // the not here is intended
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(space);
+    return false;
+#endif
+}
+
+/*!
+    Finds out if the currency symbol is placed on the opposite side with negative 
+    currencies compared to where it is placed with non-negative currencies.
+
+    \return true if in negative currency values, the position of the currency
+    symbol is set to be the opposite of the position used for non-negative
+    values; otherwise returns false.
+*/
+bool HbExtendedLocale::negativeCurrencySymbolOpposite() const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    return _symbianLocale.GetLocale()->NegativeCurrencySymbolOpposite();
+#else
+    return false;
+#endif
+}
+
+/*!
+    Sets whether the position of the currency symbol for negative currency
+    values should be the \a opposite of the position used for
+    non-negative values.
+
+    \return true for Symbian and false for other OS
+*/
+bool HbExtendedLocale::setNegativeCurrencySymbolOpposite( const bool opposite )
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    _symbianLocale.GetLocale()->SetNegativeCurrencySymbolOpposite(opposite);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(opposite);
+    return false;
+#endif
+}
+
+/*!
+    Finds out if currency triads are used (the grouping of digits in large numbers, for example, 123 456 789).
+    The Symbian OS only supports the grouping of currency amounts.
+
+    \return true if currency triads are allowed in currency values; otherwise returns false.
+    
+ */
+bool HbExtendedLocale::currencyTriadsAllowed() const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    return _symbianLocale.GetLocale()->CurrencyTriadsAllowed();
+#else
+    return false;
+#endif
+}
+
+/*!
+    Sets whether triads are \a allowed in currency values.
+
+    \return true for Symbian and false for other CS
+ */
+bool HbExtendedLocale::setCurrencyTriadsAllowed( const bool allowed )
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    _symbianLocale.GetLocale()->SetCurrencyTriadsAllowed(allowed);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(allowed);
+    return false;
+#endif
+}
+
+
+/*!
+     \return true if a space is inserted between the currency symbol and
+     a positive currency value; otherwise returns false.
+
+     \note For negative currency values, the space can be inserted using
+           setNegativeCurrencySpace().
+ */
+bool HbExtendedLocale::currencySpace() const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    return _symbianLocale.GetLocale()->CurrencySpaceBetween();
+#else
+    return false;
+#endif
+}
+
+/*!
+     Sets whether a \a space is inserted between the currency symbol and the
+     currency amount.
+
+     \return true for Symbian and false for other OS
+ */
+bool HbExtendedLocale::setCurrencySpace( const bool space )
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    _symbianLocale.GetLocale()->SetCurrencySpaceBetween(space);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(space);
+    return false;
+#endif
+}
+
+
+/*!
+    The currency symbol may contain a different number of characters in different countries/regions.
+    Example: ś, $, Ft, kn, Euro symbol
+    \return the currency symbol.
+ */
+QString HbExtendedLocale::currencySymbol() const
+{
+    // copy from other similar method
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    return QString::fromUtf16(_symbianLocale.GetCurrencySymbol().Ptr(), _symbianLocale.GetCurrencySymbol().Length());
+#else
+    return QString();
+#endif
+}
+
+/*!
+    Sets the currency \a symbol.
+
+    \return true for Symbian if succesfull and false for other OS
+ */
+bool HbExtendedLocale::setCurrencySymbol( const QString &symbol )
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    // prepare for symbol being larger than KMaxCurrencySymbol
+    if ( symbol.length() < KMaxCurrencySymbol ) {
+        TPtrC newCurrencySymbol(symbol.utf16());
+        _symbianLocale.SetCurrencySymbol(newCurrencySymbol);
+        return true;
+    }
+    return false;
+#else
+    Q_UNUSED(symbol);
+    return false;
+#endif
+}
+
+/*!
+    Retrieves position of the currency symbol (before or after the amount).
+     \return the currency symbol position.
+
+     \note For negative currency values, this position may be reversed using 
+           SetNegativeCurrencySymbolOpposite().
+ */
+HbExtendedLocale::SymbolPos HbExtendedLocale::currencySymbolPosition() const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    TLocalePos pos = _symbianLocale.GetLocale()->CurrencySymbolPosition();
+    switch ( pos ) {
+    case ELocaleBefore:
+        return HbExtendedLocale::Before;
+    case ELocaleAfter:
+        return HbExtendedLocale::After;
+    }
+    return HbExtendedLocale::After;
+#else
+    return HbExtendedLocale::Before;
+#endif
+}
+
+/*!
+     Sets the currency symbol \a position.
+
+     \return true for Symbian and false for other OS
+ */
+bool HbExtendedLocale::setCurrencySymbolPosition( const SymbolPos position )
+{
+#if defined(Q_OS_SYMBIAN)
+    TLocalePos pos;
+    switch ( position ) {
+    default:
+    case HbExtendedLocale::Before:
+        pos = ELocaleBefore;
+        break;
+    case HbExtendedLocale::After:
+        pos = ELocaleAfter;
+        break;
+    }
+    _symbianLocale.LoadSystemSettings();
+    _symbianLocale.GetLocale()->SetCurrencySymbolPosition(pos);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(position);
+    return false;
+#endif
+}
+
+/*!
+     \return the number of decimal places to which currency values are set.
+ */
+int HbExtendedLocale::currencyDecimalPlaces() const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    return _symbianLocale.GetLocale()->CurrencyDecimalPlaces();
+#else
+    return 0;
+#endif
+}
+
+/*!
+     Sets the number of decimal \a places to which currency values should be set.
+
+     \return true for Symbian and false for other OS
+ */
+bool HbExtendedLocale::setCurrencyDecimalPlaces( const int places )
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    _symbianLocale.GetLocale()->SetCurrencyDecimalPlaces(places);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(places);
+    return false;
+#endif
+}
+
+/*
+    Helper class to handle overflows that may occur when
+    calling TLocale::FormatCurrency(TDes &aText, TDesOverflow &aOverflowHandler, TInt aAmount);
+    Increases currencyFormatSize by CURRENCY_FORMAT_SIZE_STEP with each overflow.
+ */
+#if defined(Q_OS_SYMBIAN)
+class TestOverflow : public TDesOverflow
+{
+public:
+    void Overflow( TDes& ) { currencyFormatSize += CURRENCY_FORMAT_SIZE_STEP; }
+    void setCurrencyFormatSize( int newCurrencyFormatSize ) { currencyFormatSize = newCurrencyFormatSize; }
+    int getCurrencyFormatSize() { return currencyFormatSize; }
+
+private:
+    int currencyFormatSize;
+};
+#endif
+
+/*!
+    Returns a currency \a amount as a string, based on the locale's
+    currency and numeric format settings.
+    These settings include the currency symbol, the symbol's
+    position and how negative values are formatted.
+
+    \sa setCurrencyDecimalPlaces(), setCurrencySpace(), setCurrencySymbol(),
+        setCurrencySymbolPosition(), setNegativeCurrencySpace(), setNegativeCurrencyFormat(),
+        setCurrencyTriadsAllowed(), setNegativeCurrencySymbolOpposite(),
+        setGroupSeparator(), setDecimalPoint()
+*/
+QString HbExtendedLocale::formatCurrency( const qint64 amount )
+{
+#if defined(Q_OS_SYMBIAN)
+
+    TestOverflow overflow;
+
+    // set buffer minimum size
+    const int base = 10;
+    int bufferMinSize = QString::number(amount, base).length() + CURRENCY_FORMAT_SIZE_STEP;
+    overflow.setCurrencyFormatSize(bufferMinSize);
+
+    HBufC *bufPtr = HBufC::New(bufferMinSize);
+
+    if ( bufPtr == NULL ) {
+        return QString();
+    }
+
+    // stores the previous formatted value size
+    int fSize = 0;
+
+    // Compare current currency formatted value size to previous.
+    // Increase indicates that overflow has occurred.
+    // Initial value of fSize is zero so the iteration is done
+    // at least once.
+
+    while ( fSize < overflow.getCurrencyFormatSize() ) {
+        // fSize value before calling formatCurrency
+        fSize = overflow.getCurrencyFormatSize();
+
+        // handle Panic: USER 18 if aMaxLength is negative.
+        if ( fSize < 0 ) {
+            return QString();
+        }
+
+        HBufC *newBufPtr = bufPtr->ReAlloc(fSize);
+
+        if ( newBufPtr == NULL ) {
+            delete bufPtr;
+            return QString();
+        }
+
+        bufPtr = newBufPtr;
+
+        TPtr modifiableBufPtr(bufPtr->Des());
+
+        _symbianLocale.LoadSystemSettings();
+        _symbianLocale.GetLocale()->FormatCurrency(modifiableBufPtr, overflow, TInt64(amount));
+     }
+
+    return QString::fromUtf16(bufPtr->Ptr(), bufPtr->Length());
+
+#else
+    return QString::number(amount);
+#endif
+}
+
+/*!
+    Sets decimal point character \a ch to system locale.
+
+    \return true for Symbian and false for other OS
+*/
+bool HbExtendedLocale::setDecimalPoint( const QChar ch )
+{
+#if defined(Q_OS_SYMBIAN)
+    TChar symbianch( ch.unicode() );
+    _symbianLocale.LoadSystemSettings();
+    _symbianLocale.GetLocale()->SetDecimalSeparator(symbianch);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(ch);
+    return false;
+#endif
+}
+
+/*!
+    Sets group separator character \a ch to system locale.
+
+    \return true for Symbian and false for other OS
+*/
+bool HbExtendedLocale::setGroupSeparator( const QChar ch )
+{
+#if defined(Q_OS_SYMBIAN)
+    TChar symbianch( ch.unicode() );
+    _symbianLocale.LoadSystemSettings();
+    _symbianLocale.GetLocale()->SetThousandsSeparator(symbianch);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(ch);
+    return false;
+#endif
+}
+
+/*!
+    Sets zero digit \a type to system locale.
+
+    \return true for Symbian and false for other OS
+*/
+bool HbExtendedLocale::setZeroDigit( const DigitType type )
+{
+#if defined(Q_OS_SYMBIAN)
+    TDigitType digit;
+    switch ( type ) {
+        default:
+        case WesternDigit :
+            digit = EDigitTypeWestern;
+            break;
+        case ArabicIndicDigit :
+            digit = EDigitTypeArabicIndic;
+            break;
+        case EasternArabicIndicDigit:
+            digit = EDigitTypeEasternArabicIndic;
+            break;
+        case DevanagariDigit:
+            digit = EDigitTypeDevanagari;
+            break;
+        case ThaiDigit:
+            digit = EDigitTypeThai;
+            break;
+        }
+    _symbianLocale.LoadSystemSettings();
+    _symbianLocale.GetLocale()->SetDigitType(digit);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(type);
+    return false;
+#endif
+}
+
+/*!
+    Mapping from Symbian to ISO locale
+*/
+struct symbianToISO {
+    int symbian_language;
+    char iso_name[8];
+};
+
+#if defined(Q_OS_SYMBIAN)
+static const symbianToISO symbian_to_iso_list[] = {
+    { ELangEnglish,             "en_GB" },
+    { ELangFrench,              "fr_FR" },
+    { ELangGerman,              "de_DE" },
+    { ELangSpanish,             "es_ES" },
+    { ELangItalian,             "it_IT" },
+    { ELangSwedish,             "sv_SE" },
+    { ELangDanish,              "da_DK" },
+    { ELangNorwegian,           "no_NO" },
+    { ELangFinnish,             "fi_FI" },
+    { ELangAmerican,            "en_US" },
+    { ELangSwissFrench,         "fr_CH" },
+    { ELangSwissGerman,         "de_CH" },
+    { ELangPortuguese,          "pt_PT" },
+    { ELangTurkish,             "tr_TR" },
+    { ELangIcelandic,           "is_IS" },
+    { ELangRussian,             "ru_RU" },
+    { ELangHungarian,           "hu_HU" },
+    { ELangDutch,               "nl_NL" },
+    { ELangBelgianFlemish,      "nl_BE" },
+    { ELangAustralian,          "en_AU" },
+    { ELangBelgianFrench,       "fr_BE" },
+    { ELangAustrian,            "de_AT" },
+    { ELangNewZealand,          "en_NZ" },
+    { ELangInternationalFrench, "fr" },
+    { ELangCzech,               "cs_CZ" },
+    { ELangSlovak,              "sk_SK" },
+    { ELangPolish,              "pl_PL" },
+    { ELangSlovenian,           "sl_SI" },
+    { ELangTaiwanChinese,       "zh_TW" },
+    { ELangHongKongChinese,     "zh_HK" },
+    { ELangPrcChinese,          "zh_CN" },
+    { ELangJapanese,            "ja_JP" },
+    { ELangThai,                "th_TH" },
+    { ELangAfrikaans,           "af" }, // SouthAfrika/Namibia
+    { ELangAlbanian,            "sq_AL" },
+    { ELangAmharic,             "am_ET" },
+    { ELangArabic,              "ar_AE" },
+    { ELangArmenian,            "hy_AM" },
+    { ELangTagalog,             "tl_PH" },
+    { ELangBelarussian,         "be_BY" },
+    { ELangBengali,             "bn" }, // Bangladesh/India
+    { ELangBulgarian,           "bg_BG" },
+    { ELangBurmese,             "my_MM" },
+    { ELangCatalan,             "ca_ES" },
+    { ELangCroatian,            "hr_HR" },
+    { ELangCanadianEnglish,     "en_CA" },
+    { ELangInternationalEnglish, "en" },
+    { ELangSouthAfricanEnglish, "en_ZA" },
+    { ELangEstonian,            "et_EE" },
+    { ELangFarsi,               "fa_IR" },
+    { ELangCanadianFrench,      "fr_CA" },
+    { ELangScotsGaelic,         "gd_GB" },
+    { ELangGeorgian,            "ka_GE" },
+    { ELangGreek,               "el_GR" },
+    { ELangCyprusGreek,         "el_GR" },
+    { ELangGujarati,            "gu_IN" },
+    { ELangHebrew,              "he_IL" },
+    { ELangHindi,               "hi_IN" },
+    { ELangIndonesian,          "id_ID" },
+    { ELangIrish,               "ga_IE" },
+    { ELangSwissItalian,        "it_CH" },
+    { ELangKannada,             "kn_IN" },
+    { ELangKazakh,              "kk_KZ" },
+    { ELangKhmer,               "km_KH" },
+    { ELangKorean,              "ko_KR" },
+    { ELangLao,                 "lo_LA" },
+    { ELangLatvian,             "lv_LV" },
+    { ELangLithuanian,          "lt_LT" },
+    { ELangMacedonian,          "mk_MK" },
+    { ELangMalay,               "ms_MY" },
+    { ELangMalayalam,           "ml_IN" },
+    { ELangMarathi,             "mr_IN" },
+    { ELangMoldavian,           "mo_MD" },
+    { ELangMongolian,           "mn_MN" },
+    { ELangNorwegianNynorsk,    "nn_NO" },
+    { ELangBrazilianPortuguese, "pt_BR" },
+    { ELangPunjabi,             "pa" }, // India/Pakistan
+    { ELangRomanian,            "ro_RO" },
+    { ELangSerbian,             "sr_YU" },
+    { ELangSinhalese,           "si_LK" },
+    { ELangSomali,              "so_SO" },
+    { ELangInternationalSpanish, "es" },
+    { ELangLatinAmericanSpanish, "es" },
+    { ELangSwahili,             "sw" }, // Kenya/Tanzania
+    { ELangFinlandSwedish,      "sv_FI" },
+    { ELangTamil,               "ta_IN" },
+    { ELangTelugu,              "te_IN" },
+    { ELangTibetan,             "bo_CN" },
+    { ELangTigrinya,            "ti_ER" },
+    { ELangCyprusTurkish,       "tr_GR" },
+    { ELangTurkmen,             "tk_TM" },
+    { ELangUkrainian,           "uk_UA" },
+    { ELangUrdu,                "ur_PK" }, // India/Pakistan
+    { ELangVietnamese,          "vi_VN" },
+    { ELangWelsh,               "cy_GB" },
+    { ELangZulu,                "zu_ZA" },
+    { ELangSouthSotho,          "st_LS" },
+#ifdef __E32LANG_H__
+// 5.0
+    { ELangBasque,              "eu_ES" },
+    { ELangGalician,            "gl_ES" },
+#endif
+    { ELangEnglish_Apac,        "en" },
+    { ELangEnglish_Taiwan,      "en_TW" },
+    { ELangEnglish_HongKong,    "en_HK" },
+    { ELangEnglish_Prc,         "en_CN" },
+    { ELangEnglish_Japan,       "en_JP"},
+    { ELangEnglish_Thailand,    "en_TH" },
+//  { ELangSantali,             "" }, // dll in 3.2, not in 5.0, defined in 5.0
+    { ELangMalay_Apac,          "ms" }
+};
+#endif
+
+/*!
+    \return ISO name corresponding to the Symbian language \a code.
+    If the code does not does not correspond to any Symbian language,
+    returns a null string.
+    
+    \sa User::Language()
+*/
+QString HbExtendedLocale::symbianLangToISO( const int code )
+{
+#if defined(Q_OS_SYMBIAN)
+    int begin = 0;
+    int end = sizeof(symbian_to_iso_list)/sizeof(symbianToISO);
+    int mid;
+    int cmp = code - symbian_to_iso_list[0].symbian_language;
+    if (cmp < 0) {
+        return QString();
+    }
+    else {
+        if (cmp == 0) {
+            return symbian_to_iso_list[0].iso_name;
+        }
+    }
+    symbianToISO *elt;
+    while (end > begin) {
+        mid = (begin + end) >> 1;
+        elt = const_cast<symbianToISO *>(symbian_to_iso_list+mid);
+        cmp = elt->symbian_language - code;
+        if (cmp < 0) {
+            begin = mid+1;
+        } 
+        else {
+            if (!cmp) {
+                return elt->iso_name;  
+            }
+            else {
+                end = mid;
+            }    
+        } 
+    }
+    if (!cmp) {
+        return elt->iso_name;  
+    }
+    return QString();
+#else
+    Q_UNUSED(code);
+    return QString("not supported");
+#endif
+}
+
+#if defined(Q_OS_SYMBIAN)
+// order is: normal, abbr, nmode, nmode+abbr
+static const char *us_locale_dep[] = {
+    "MM", "dd", "yyyy", "MM", "dd",
+    "M", "d", "yy", "M", "d",
+    "MMMM", "dd", "yyyy", "MMMM", "dd",
+    "MMM", "d", "yy", "MMM", "d" };
+
+static const char *eu_locale_dep[] = {
+    "dd", "MM", "yyyy", "dd", "MM",
+    "d", "M", "yy", "d", "M",
+    "dd", "MMMM", "yyyy", "dd", "MMMM",
+    "d", "MMM", "yy", "d", "MMM" };
+
+static const char *jp_locale_dep[] = {
+    "yyyy", "MM", "dd", "MM", "dd",
+    "yy", "M", "d", "M", "d",
+    "yyyy", "MMMM", "dd", "MMMM", "dd",
+    "yy", "MMM", "d", "MMM", "d" };
+#endif
+
+/*!
+    Returns a Qt version of the given \a sys_fmt Symbian datetime format string.
+    Some convertable fields use data from current system locale,
+    unwanted locale may cause unexpected results.
+*/
+QString HbExtendedLocale::symbianDateTimeToQt( const QString &sys_fmt )
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    TLocale *locale = _symbianLocale.GetLocale();
+
+    QString result;
+    QString other;
+    QString qtformatchars = QString::fromLatin1("adhmsyzAHM");
+
+    QChar c;
+    int i = 0;
+    bool open_escape = false;
+    bool abbrev_next = false;
+    bool locale_indep_ordering = false;
+    bool minus_mode = false;
+    bool plus_mode = false;
+    bool n_mode = false;
+    TTimeFormat tf = locale->TimeFormat();
+
+    while ( i < sys_fmt.size() ) {
+        c = sys_fmt.at(i);
+
+        // let formatting thru
+        if ( c.unicode() == '%' ) {
+            // if we have gathered string, concat it
+            if ( !other.isEmpty() ) {
+                result += other;
+                other.clear();
+            }
+            // if we have open escape, end it
+            if ( open_escape ) {
+                result += QLatin1Char('\'');
+                open_escape = false;
+            }
+
+            ++i;
+            if ( i >= sys_fmt.size() ) {
+                break;
+            }
+
+            c = sys_fmt.at(i);
+
+            // process specials
+            abbrev_next = c.unicode() == '*';
+            plus_mode = c.unicode() == '+';
+            minus_mode = c.unicode() == '-';
+
+            if ( abbrev_next || plus_mode || minus_mode ) {
+                ++i;
+                if ( i >= sys_fmt.size() ) {
+                    break;
+		        }
+
+                c = sys_fmt.at(i);
+                
+                if ( plus_mode || minus_mode ) {
+                    // break on undefined plus/minus mode
+                    if ( c.unicode() != 'A' && c.unicode() != 'B' ) {
+                        break;
+                    }
+                }
+            }
+
+            switch ( c.unicode() ) {
+                case 'F':
+                    // locale indep mode on
+                    locale_indep_ordering = true;
+                    break;
+                    
+                case '/':
+                    // date sep 0-3
+                    ++i;
+                    if ( i >= sys_fmt.size() ) {
+                        break;
+                    }
+
+                    c = sys_fmt.at(i);
+                    if ( c.isDigit() && c.digitValue() <= 3 ) {
+                        TChar s = locale->DateSeparator(c.digitValue());
+                        TUint val = s;
+                        // some indexes return zero for empty
+                        if ( val > 0 ) {
+                            result += QChar(val);
+                        }
+                    }
+                    break;
+                    
+                case 'D':
+                    if ( !locale_indep_ordering ) {
+                        break;
+                    }
+
+                    if ( !abbrev_next ) {
+                        result += QLatin1String("dd");
+                    } else {
+                        result += QLatin1Char('d');
+                    }
+                    break;
+
+                case 'M':
+                    if ( !locale_indep_ordering ) {
+                        break;
+                    }
+
+                    if ( !n_mode ) {
+                        if ( !abbrev_next ) {
+                            result += QLatin1String("MM");
+                        } else {
+                            result += QLatin1String("M");
+                        }
+                    } else {
+                        if ( !abbrev_next ) {
+                            result += QLatin1String("MMMM");
+                        } else {
+                            result += QLatin1String("MMM");
+                        }
+                    }
+                    break;
+                    
+                case 'N':
+                    n_mode = true;
+
+                    if ( !locale_indep_ordering ) {
+                        break;
+                    }
+
+                    if ( !abbrev_next ) {
+                        result += QLatin1String("MMMM");
+                    } else {
+                        result += QLatin1String("MMM");
+                    }
+                    break;
+
+                case 'Y':
+                    if ( !locale_indep_ordering ) {
+                        break;
+                    }
+
+                    if ( !abbrev_next ) {
+                        result += QLatin1String("yyyy");
+                    } else {
+                        result += QLatin1String("yy");
+                    }
+                    break;
+
+                case 'E':
+                    if ( !abbrev_next ) {
+                        result += QLatin1String("dddd");
+                    } else {
+                        result += QLatin1String("ddd");
+                    }    
+                    break;
+
+                case ':':
+                    // timesep 0-3
+                    ++i;
+                    if ( i >= sys_fmt.size() ) {
+                        break;
+                    }
+
+                    c = sys_fmt.at(i);
+                    if ( c.isDigit() && c.digitValue() <= 3 ) {
+                        TChar s = locale->TimeSeparator(c.digitValue());
+                        TUint val = s;
+                        // some indexes return zero for empty
+                        if ( val > 0 ) {
+                            result += QChar(val);
+                        }
+                    }
+                    break;
+                    
+                case 'J':
+                    if ( tf == ETime24 && !abbrev_next ) {
+                        result += QLatin1String("hh");
+                    } else {
+                        result += QLatin1Char('h');
+                    }
+                    break;
+
+                case 'H':
+                    if ( !abbrev_next ) {
+                        result += QLatin1String("hh");
+                    } else {
+                        result += QLatin1Char('h');
+                    }
+                    break;
+
+                case 'I':
+                    result += QLatin1Char('h');
+                    break;
+
+                case 'T':
+                    if ( !abbrev_next ) {
+                        result += QLatin1String("mm");
+                    } else {
+                        result += QLatin1Char('m');
+                    }
+                    break;
+
+                case 'S':
+                    if ( !abbrev_next ) {
+                        result += QLatin1String("ss");
+                    } else {
+                        result += QLatin1Char('s');
+                    }
+                    break;
+
+                case 'B':
+                    // only done for 12h clock
+                    if ( tf == ETime24 ) {
+                        break;
+                    }
+
+                    // fallthru to A
+                case 'A': {
+                    // quickie to get capitalization, can't use s60 string as is because Qt 'hh' format's am/pm logic
+                    TAmPmName ampm = TAmPmName();
+                    TChar first(ampm[0]);
+                    QString qtampm = QString::fromLatin1(first.IsUpper() ? "AP" : "ap");
+
+                    int pos = locale->AmPmSymbolPosition();
+
+                    if ( ( minus_mode && pos != ELocaleBefore ) ||
+                       ( plus_mode && pos != ELocaleAfter ) ) {
+                       break;
+                    }
+
+                    if ( !abbrev_next && locale->AmPmSpaceBetween() ) {
+						if ( pos == ELocaleBefore ) {
+						    qtampm.append(QLatin1Char(' '));
+                        } else {
+                           qtampm.prepend(QLatin1Char(' '));
+                        }
+                    }
+
+                    result += qtampm;
+                    }
+                    break;
+
+                case '.': {
+                    // decimal sep
+                    TChar s = locale->DecimalSeparator();
+                    TUint val = s;
+                    if ( val > 0 ) {
+                        result += QChar(val);
+                    }
+                    }
+                    break;
+
+                case 'C':
+                    // six digits in s60, three digits in qt
+                    if ( !abbrev_next ) {
+                        result += QLatin1String("zzz");
+                    } else {
+                        // next char is number from 0-6, how many digits to display
+                        ++i;
+                        if ( i >= sys_fmt.size() ) {
+                            break;
+                        }
+
+                        c = sys_fmt.at(i);
+
+                        if ( c.isDigit() ) {
+                            // try to match wanted digits
+                            QChar val(c.digitValue());
+
+                            if ( val >= 3 ) {
+                                result += QLatin1String("zzz");
+                            } else if ( val > 0 ) {
+                                result += QLatin1Char('z');
+                            }
+                        }
+                    }
+                    break;
+
+                // these cases fallthru
+                case '1':
+                case '2':
+                case '3':
+                case '4':
+                case '5': {
+
+                    // shouldn't parse these with %F
+                    if ( locale_indep_ordering ) {
+                        break;
+                    }
+
+                    TDateFormat df = locale->DateFormat();
+
+                    const char **locale_dep;
+                    switch ( df ) {
+                        default: // fallthru to american
+                        case EDateAmerican:
+                            locale_dep = us_locale_dep;
+                            break;
+                        case EDateEuropean:
+                            locale_dep = eu_locale_dep;
+                            break;
+                        case EDateJapanese:
+                            locale_dep = jp_locale_dep;
+                            break;
+                    }
+                    int offset = 0;
+                    if ( abbrev_next ) {
+                        offset += 5;
+                    }
+                    if ( n_mode ) {
+                        offset += 10;
+                    }
+
+                    result += QLatin1String(locale_dep[offset + (c.digitValue()-1)]);
+                    }
+                    break;
+
+                case '%': // fallthru percent
+                // any junk gets copied as is
+                default:
+                    result += c;
+                    break;
+
+                case 'Z': // Qt doesn't support these :(
+                case 'X':
+                case 'W':
+                    break;
+            }
+        } else {
+            // double any single quotes, don't begin escape
+            if ( c.unicode() == '\'' ) {
+                // end open escape
+                if ( open_escape ) {
+                    result += other;
+                    other.clear();
+                    result += QLatin1Char('\'');
+                    open_escape = false;
+                }
+
+                other += c;
+            }
+
+            // gather chars and escape them in one go if any format chars are found
+            if ( !open_escape && qtformatchars.indexOf(c) != -1 ) {
+                result += QLatin1Char('\'');
+                open_escape = true;
+            }
+            other += c;
+        }
+
+        ++i;
+    }
+
+    if ( !other.isEmpty() ) {
+        result += other;
+    }
+    if ( open_escape ) {
+        result += QLatin1Char('\'');
+    }
+
+    return result;
+#else
+    Q_UNUSED(sys_fmt);
+    return QString("not supported");
+#endif    
+}
+
+/*! 
+    \enum HbExtendedLocale::WeekDay
+     This enum defines weekdays.
+
+      \sa startOfWeek()
+ */
+
+/*!
+     Gets first day of the week.
+     It is usually Saturday, Sunday or Monday, but the Symbian OS allows setting any weekday as the first.
+     Returns enum WeekDay.
+
+     \return Monday for other OS
+ */
+HbExtendedLocale::WeekDay HbExtendedLocale::startOfWeek() const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    TDay day = _symbianLocale.GetLocale()->StartOfWeek();
+    switch ( day ) {
+    case EMonday:
+        return HbExtendedLocale::Monday;
+    case ETuesday:
+        return HbExtendedLocale::Tuesday;
+    case EWednesday:
+        return HbExtendedLocale::Wednesday;
+    case EThursday:
+        return HbExtendedLocale::Thursday;
+    case EFriday:
+        return HbExtendedLocale::Friday;
+    case ESaturday:
+        return HbExtendedLocale::Saturday;
+    case ESunday:
+        return HbExtendedLocale::Sunday;
+    }
+    return HbExtendedLocale::Monday;
+#else
+    return HbExtendedLocale::Monday;
+#endif
+}
+
+/*!
+    Sets the day which is considered to be the first day of the week.
+    \param day  The first day of the week.
+    \return true for Symbian and false for other OS
+    \sa startOfWeek()
+ */
+
+bool HbExtendedLocale::setStartOfWeek(WeekDay day)
+    {
+#if defined(Q_OS_SYMBIAN)
+    if((day < HbExtendedLocale::Monday) && (day > HbExtendedLocale::Monday ))
+        return false;
+    
+    _symbianLocale.LoadSystemSettings();
+    TDay startofweek = EMonday;
+    switch ( day ) {
+        case HbExtendedLocale::Monday:
+            startofweek = EMonday;
+            break;
+        case HbExtendedLocale::Tuesday:
+            startofweek = ETuesday;
+            break;
+        case HbExtendedLocale::Wednesday:
+            startofweek = EWednesday;
+            break;
+        case HbExtendedLocale::Thursday:
+            startofweek = EThursday;
+            break;
+        case HbExtendedLocale::Friday:
+            startofweek = EFriday;
+            break;
+        case HbExtendedLocale::Saturday:
+            startofweek = ESaturday;
+            break;
+        case HbExtendedLocale::Sunday:
+            startofweek = ESunday;
+            break;                    
+        }
+    _symbianLocale.GetLocale()->SetStartOfWeek(startofweek);
+    _symbianLocale.GetLocale()->Set();
+    return true;
+#else
+    Q_UNUSED(day);
+    return false;
+#endif    
+    }
+
+
+/*!
+     Gets days which are working days of week.
+     Returns QString which describes workdays as binary array.
+     1 meaning workday and 0 as non working day.
+
+     \return 0011111 for other OS
+
+     \sa setWorkDays()
+ */
+QString HbExtendedLocale::workDays() const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    int days = _symbianLocale.GetLocale()->WorkDays();
+    QString s = QString::number(days, 2);
+    while ( s.size() < 7 ) {
+        s.prepend("0");
+    }
+    return s;
+#else
+    return QString("0011111");
+#endif
+}
+
+/*!
+     Sets working days of week.
+     \param days which describes workdays as QString binary array.
+            1 meaning workday and 0 non workday.
+
+     \return true for Symbian if succesfull and false for other OS
+
+     \sa workDays()
+*/
+bool HbExtendedLocale::setWorkDays( const QString &days )
+{
+#if defined(Q_OS_SYMBIAN)
+    if ( days.size() != 7 ) {
+        return false;
+    }
+    bool ok;
+    int mask = days.toInt(&ok, 2);
+    _symbianLocale.LoadSystemSettings();
+    if ( ok ) {
+        _symbianLocale.GetLocale()->SetWorkDays(mask);
+        _symbianLocale.GetLocale()->Set();
+        return true;
+    }
+    return false;
+#else
+    Q_UNUSED(days);
+    return false;
+#endif
+}
+
+/*!
+    Checks whether or not daylight saving is set for the home city
+    \return True if home daylight saving is set, false if home daylight saving is not set
+ */
+
+bool HbExtendedLocale::homeHasDaylightSavingOn() const
+{
+#if defined(Q_OS_SYMBIAN)
+    _symbianLocale.LoadSystemSettings();
+    return (_symbianLocale.GetLocale()->QueryHomeHasDaylightSavingOn());
+#else
+    return false;
+#endif    
+}
+
+/*! \enum HbExtendedLocale::DaylightSavingZone
+    Returns the daylight saving zone in which the home city is located.
+    
+    \value Home Home daylight saving zone
+    \value European European daylight saving zone
+    \value Northern Northern hemisphere (non-European) daylight saving zone
+    \value Southern Southern hemisphere daylight saving zone
+    \value None No daylight saving zone
+    
+    \sa setHomeDaylightSavingZone()
+ */
+HbExtendedLocale::DaylightSavingZone HbExtendedLocale::homeDaylightSavingZone() const
+{
+#if defined(Q_OS_SYMBIAN)    
+    _symbianLocale.LoadSystemSettings();
+    TDaylightSavingZone zone = _symbianLocale.GetLocale()->HomeDaylightSavingZone();
+    switch ( zone ) {
+    case EDstHome:
+        return HbExtendedLocale::HomeZone;
+    case EDstEuropean:
+        return HbExtendedLocale::EuropeanZone;
+    case EDstNorthern:
+        return HbExtendedLocale::NorthernZone;
+    case EDstSouthern:
+        return HbExtendedLocale::SouthernZone;
+    case EDstNone:
+        return HbExtendedLocale::None;
+    }
+    return HbExtendedLocale::None;
+#else
+    return HbExtendedLocale::None;
+#endif    
+}
+
+/*!
+    Gets the locale’s universal time offset
+    \return Offset in seconds from universal time. For other platforms it returns 0.
+ */
+int HbExtendedLocale::universalTimeOffset() const
+{
+#if defined(Q_OS_SYMBIAN)    
+    _symbianLocale.LoadSystemSettings();
+    TTimeIntervalSeconds seconds = _symbianLocale.GetLocale()->UniversalTimeOffset();
+    return seconds.Int();
+#else
+    return 0;
+#endif
+}
+
+HbExtendedLocale::HbExtendedLocale()
+{
+#if defined(Q_OS_SYMBIAN)
+    QLocale::system();
+    _symbianLocale.LoadSystemSettings();	
+#endif
+}
+
+//! Returns new/dummy copy of HbExtendedLocale.
+HbExtendedLocale HbExtendedLocale::system()
+{
+    // make sure QLocale's lp is updated if in future QApplication does not do it
+    // currently this does not do anything
+    // just return default set locale
+    return HbExtendedLocale();
+}
+
+/*!
+    Formats the given date to a string according to the given date format.
+    For example, what date components are included, and if leading zeroes are used.
+    This is a function uses the date formats defined in the hbi18ndef.h header file.
+
+     \param date The date to be formatted.  
+     \param dateFormat The wanted format to be used.  
+       
+     \return The date as a string.   
+ */
+QString HbExtendedLocale::format( const QDate &date, const QString &dateFormat )
+{
+#if defined(Q_OS_SYMBIAN)    
+    QScopedPointer<CTrapCleanup> sp;
+    if (!User::TrapHandler()) {       
+       CTrapCleanup* cleanup = CTrapCleanup::New();
+       if (cleanup) {
+           sp.reset(cleanup);
+       }
+    }    
+	QString resultString;
+    _symbianLocale.LoadSystemSettings();
+    TDateTime s60DateTime;
+         
+    //Convert the QDate to match the Symbian Date
+    
+    int month = date.month();
+    int day = date.day();
+    if (month>=1 && month<=12 && day>=1 && day<=31 ) {
+       if (s60DateTime.Set(date.year(), TMonth(month-1), day-1, 0, 0, 0, 0)) {
+           return QString("");
+       }
+    } 
+    else {     
+        return QString("");
+    }
+	
+	TTime s60Date(s60DateTime);
+	
+	HBufC *s60Format = QString2HBufC(dateFormat);
+    if (!s60Format) {
+        return QString();
+    }
+    QScopedPointer<HBufC> sp1(s60Format);
+		
+	HBufC *s60DateStr = HBufC::New(50);
+    if (!s60DateStr) {
+        return QString();
+    }         
+    QScopedPointer<HBufC> sp2(s60DateStr);
+    
+    TPtr s60FormatPtr = s60Format->Des();    
+	TPtr s60DatePtr = s60DateStr->Des();
+	
+	TRAPD(err, s60Date.FormatL( s60DatePtr, s60FormatPtr ));
+	if( err ){
+		return QString("");
+	}	
+	return TDesC2QString(s60DateStr->Des());
+	
+#else
+    Q_UNUSED(dateFormat);
+	return toString(date, ShortFormat );
+#endif
+}
+
+/*!
+    Formats the given time to a string according to the given time format.
+    For example, what components are included (hours/minutes/seconds), and if leading zeroes and AM/PM or am/pm symbols are used.
+    This is a function uses the time formats defined in the hbi18ndef.h header file.
+
+     \param time The time to be formatted.  
+     \param timeFormat The wanted format to be used.  
+       
+     \return The time as a string.   
+ */
+QString HbExtendedLocale::format( const QTime &time, const QString &timeFormat )
+{
+#if defined(Q_OS_SYMBIAN)
+    QScopedPointer<CTrapCleanup> sp;
+    if (!User::TrapHandler()) {       
+        CTrapCleanup* cleanup = CTrapCleanup::New();
+        if (cleanup) {
+            sp.reset(cleanup);
+        }
+    }    
+
+    QString resultString;
+	
+    TDateTime s60DateTime;
+    if (s60DateTime.Set( 0, TMonth(0), 0, time.hour(), time.minute(), time.second(), time.msec())) {
+        return QString();
+    }
+	
+	TTime s60Time(s60DateTime);
+	
+	HBufC *s60Format = QString2HBufC(timeFormat);
+    if (!s60Format) {
+        return QString();
+    }
+    QScopedPointer<HBufC> sp1(s60Format);
+	
+	
+	HBufC *s60TimeStr = HBufC::New(50);
+    if (!s60TimeStr) {
+        return QString();
+    }         
+    QScopedPointer<HBufC> sp2(s60TimeStr);
+	
+	TPtr s60FormatPtr = s60Format->Des();
+	TPtr s60TimePtr = s60TimeStr->Des();
+	
+	TRAPD(err, s60Time.FormatL( s60TimePtr, s60FormatPtr ));
+	if( err ){
+		return QString("");
+	}
+	return TDesC2QString(s60TimeStr->Des());
+#else 
+    Q_UNUSED(timeFormat);
+	return toString(time, ShortFormat);
+#endif	
+}