From bca1690bfa99e8932b890b881debc817f6d32f06 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Tue, 24 Aug 2010 16:07:39 +0000 Subject: [PATCH] Preliminary support for adjusting the money format in the locale preflet : * API for formatting a number and recovering the field positions * Some changes in the preflet to display the formatted number and start filling in the fields. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38335 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/locale/Locale.cpp | 85 +++++++++++++++++++ src/preferences/locale/FormatSettingsView.cpp | 48 ++++++++++- src/preferences/locale/FormatSettingsView.h | 4 + 3 files changed, 134 insertions(+), 3 deletions(-) diff --git a/src/kits/locale/Locale.cpp b/src/kits/locale/Locale.cpp index b5a5bfe3f1..4810e81076 100644 --- a/src/kits/locale/Locale.cpp +++ b/src/kits/locale/Locale.cpp @@ -15,7 +15,9 @@ #include #include #include +#include #include +#include #include #include @@ -674,6 +676,89 @@ BLocale::FormatMonetary(BString* string, double value) } +status_t +BLocale::FormatMonetary(BString* string, int*& fieldPositions, + BNumberElement*& fieldTypes, int& fieldCount, double value) +{ + UErrorCode err = U_ZERO_ERROR; + ObjectDeleter numberFormatter + = NumberFormat::createCurrencyInstance(*fICULocale, err); + if (U_FAILURE(err)) + return B_NO_MEMORY; + + string->Truncate(0); + + fieldPositions = NULL; + fieldTypes = NULL; + ICU_VERSION::FieldPositionIterator positionIterator; + UnicodeString ICUString; + ICUString = numberFormatter->format(value, ICUString, &positionIterator, + err); + + if (err != U_ZERO_ERROR) + return B_ERROR; + + ICU_VERSION::FieldPosition field; + std::vector fieldPosStorage; + std::vector fieldTypeStorage; + fieldCount = 0; + while (positionIterator.next(field)) { + fieldTypeStorage.push_back(field.getField()); + fieldPosStorage.push_back(field.getBeginIndex() | (field.getEndIndex() << 16)); + fieldCount ++; + + } + + fieldPositions = (int*) malloc(fieldCount * sizeof(int)); + fieldTypes = (BNumberElement*) malloc(fieldCount * sizeof(BNumberElement)); + + for (int i = 0 ; i < fieldCount ; i++ ) { + fieldPositions[i] = fieldPosStorage[i]; + switch (fieldTypeStorage[i]) { + case NumberFormat::kCurrencyField: + fieldTypes[i] = B_NUMBER_ELEMENT_CURRENCY; + break; + case NumberFormat::kIntegerField: + fieldTypes[i] = B_NUMBER_ELEMENT_INTEGER; + break; + case NumberFormat::kFractionField: + fieldTypes[i] = B_NUMBER_ELEMENT_FRACTIONAL; + break; + default: + fieldTypes[i] = B_NUMBER_ELEMENT_INVALID; + break; + } + } + + BStringByteSink stringConverter(string); + + ICUString.toUTF8(stringConverter); + + return B_OK; +} + + +status_t +BLocale::GetCurrencySymbol(BString& result) +{ + UErrorCode error = U_ZERO_ERROR; + NumberFormat* format = NumberFormat::createCurrencyInstance(*fICULocale, + error); + + if (U_FAILURE(error)) + return B_ERROR; + + char* symbol = (char*)malloc(20); + u_strToUTF8(symbol, 20, NULL, format->getCurrency(), -1, &error); + if (U_FAILURE(error)) + return B_BAD_DATA; + result.Append(symbol); + delete format; + delete symbol; + return B_OK; +} + + // #pragma mark - Helpers diff --git a/src/preferences/locale/FormatSettingsView.cpp b/src/preferences/locale/FormatSettingsView.cpp index e0e7a9d922..f80dd10964 100644 --- a/src/preferences/locale/FormatSettingsView.cpp +++ b/src/preferences/locale/FormatSettingsView.cpp @@ -32,6 +32,9 @@ #include #include +#include +#include + using BPrivate::gMutableLocaleRoster; @@ -87,7 +90,7 @@ CreateDateMenu(BMenuField** field, bool longFormat = true) dayMenu->AddItem(new DateMenuItem(B_TRANSLATE("Day in year"), "D", *field)); dayMenu->AddItem(new DateMenuItem(B_TRANSLATE("Day in year (2 digits)"), - "DD", *field)); + "DD", *field)); dayMenu->AddItem(new DateMenuItem(B_TRANSLATE("Day in year (3 digits)"), "DDD", *field)); */ @@ -215,7 +218,7 @@ FormatView::FormatView(const BLocale& locale) new BMessage(kSettingsContentsModified)); // Unit system (US/Metric) (radio) - BTextControl* currencySymbol = new BTextControl("", + fCurrencySymbolView = new BTextControl("", B_TRANSLATE("Currency symbol:"), "", new BMessage(kSettingsContentsModified)); menu = new BPopUpMenu(B_TRANSLATE("Negative marker")); @@ -237,8 +240,11 @@ FormatView::FormatView(const BLocale& locale) BRadioButton* afterRadioButton = new BRadioButton("", B_TRANSLATE("After"), new BMessage(kSettingsContentsModified)); + fMonetaryView = new BStringView("", ""); + _UpdateExamples(); _ParseDateFormat(); + _ParseCurrencyFormat(); fDateBox = new BBox(B_TRANSLATE("Date")); fTimeBox = new BBox(B_TRANSLATE("Time")); @@ -317,7 +323,8 @@ FormatView::FormatView(const BLocale& locale) fCurrencyBox->AddChild(BLayoutBuilder::Group<>(B_VERTICAL, spacing / 2) .SetInsets(spacing, spacing, spacing, spacing) - .Add(currencySymbol) + .Add(fMonetaryView) + .Add(fCurrencySymbolView) .AddGroup(B_HORIZONTAL, spacing) .AddGlue() .Add(beforeRadioButton) @@ -557,8 +564,10 @@ FormatView::SetLocale(const BLocale& locale) if (separator >= kNoSeparator && separator < kSeparatorsEnd) fSeparatorMenuField->Menu()->ItemAt((int32)separator)->SetMarked(true); */ + _UpdateExamples(); _ParseDateFormat(); + _ParseCurrencyFormat(); } @@ -643,6 +652,39 @@ FormatView::_SendNotices() } +void +FormatView::_ParseCurrencyFormat() +{ + BString currencySample; + int* fieldPos = NULL; + int fieldCount; + BNumberElement* fieldID = NULL; + if (fLocale.FormatMonetary(¤cySample, fieldPos, fieldID, fieldCount, + -1234.56) != B_OK) { + fMonetaryView->SetText("ERROR"); + return; + } + + fMonetaryView->SetText(currencySample); + + for (int i = 0; i < fieldCount; i++) { + BString currentSymbol; + currentSymbol.AppendChars(currencySample.CharAt(fieldPos[i]&0xFFFF), + (fieldPos[i]>>16) - (fieldPos[i]&0xFFFF)); + switch (fieldID[i]) { + case B_NUMBER_ELEMENT_CURRENCY: + fCurrencySymbolView->SetText(currentSymbol); + break; + default: + break; + } + } + + free(fieldPos); + free(fieldID); +} + + //! Get the date format from ICU and set the date fields accordingly void FormatView::_ParseDateFormat() diff --git a/src/preferences/locale/FormatSettingsView.h b/src/preferences/locale/FormatSettingsView.h index 55e4aa5bc3..099bf6284e 100644 --- a/src/preferences/locale/FormatSettingsView.h +++ b/src/preferences/locale/FormatSettingsView.h @@ -54,6 +54,7 @@ private: void _UpdateExamples(); void _SendNotices(); void _ParseDateFormat(); + void _ParseCurrencyFormat(); void _UpdateLongDateFormatString(); private: @@ -73,6 +74,9 @@ private: BStringView* fLongTimeExampleView; BStringView* fShortTimeExampleView; BStringView* fNumberFormatExampleView; + BStringView* fMonetaryView; + + BTextControl* fCurrencySymbolView; bool f24HrClock;