From 82a115e8bc9b595045f77913ac6f8aebb0870278 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Wed, 21 Jul 2010 14:09:48 +0000 Subject: [PATCH] * BCountry : add copy constructor and assignment operator * The locale roster uses them instead of messing with pointers, to avoid ownership problems * The Locale preflet works on a copy of the default country instead of altering it directly git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37649 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/locale/Country.h | 2 + src/kits/locale/Country.cpp | 40 ++++++++++++++++++ src/kits/locale/LocaleRoster.cpp | 25 ++++++----- .../locale/TimeFormatSettingsView.cpp | 42 ++++++++++--------- .../locale/TimeFormatSettingsView.h | 3 +- 5 files changed, 78 insertions(+), 34 deletions(-) diff --git a/headers/os/locale/Country.h b/headers/os/locale/Country.h index 2a10b432d4..4bb572291a 100644 --- a/headers/os/locale/Country.h +++ b/headers/os/locale/Country.h @@ -36,6 +36,8 @@ class BCountry { public: BCountry(const char* languageCode, const char* countryCode); BCountry(const char* languageAndCountryCode = "en_US"); + BCountry(const BCountry& other); + BCountry& operator=(const BCountry& other); virtual ~BCountry(); virtual bool Name(BString&) const; diff --git a/src/kits/locale/Country.cpp b/src/kits/locale/Country.cpp index 2b029ee6f4..efe06b79ec 100644 --- a/src/kits/locale/Country.cpp +++ b/src/kits/locale/Country.cpp @@ -63,6 +63,46 @@ BCountry::BCountry(const char* languageAndCountryCode) } +BCountry::BCountry(const BCountry& other) +{ + fICULocale = new ICU_VERSION::Locale(*other.fICULocale); + fICULongDateFormatter = new ICU_VERSION::SimpleDateFormat( + *static_cast(other.fICULongDateFormatter)); + fICUShortDateFormatter = new ICU_VERSION::SimpleDateFormat( + *static_cast(other.fICUShortDateFormatter)); + fICULongTimeFormatter = new ICU_VERSION::SimpleDateFormat( + *static_cast(other.fICULongTimeFormatter)); + fICUShortTimeFormatter = new ICU_VERSION::SimpleDateFormat( + *static_cast(other.fICUShortTimeFormatter)); +} + + +BCountry& +BCountry::operator=(const BCountry& other) +{ + if (this == &other) + return *this; + + delete fICULongTimeFormatter; + delete fICUShortTimeFormatter; + delete fICULongDateFormatter; + delete fICUShortDateFormatter; + delete fICULocale; + + fICULocale = new ICU_VERSION::Locale(*other.fICULocale); + fICULongDateFormatter = new ICU_VERSION::SimpleDateFormat( + *static_cast(other.fICULongDateFormatter)); + fICUShortDateFormatter = new ICU_VERSION::SimpleDateFormat( + *static_cast(other.fICUShortDateFormatter)); + fICULongTimeFormatter = new ICU_VERSION::SimpleDateFormat( + *static_cast(other.fICULongTimeFormatter)); + fICUShortTimeFormatter = new ICU_VERSION::SimpleDateFormat( + *static_cast(other.fICUShortTimeFormatter)); + + return *this; +} + + BCountry::~BCountry() { delete fICULongTimeFormatter; diff --git a/src/kits/locale/LocaleRoster.cpp b/src/kits/locale/LocaleRoster.cpp index 667169289c..8f2b202f5a 100644 --- a/src/kits/locale/LocaleRoster.cpp +++ b/src/kits/locale/LocaleRoster.cpp @@ -186,7 +186,7 @@ struct RosterData { BMessage fPreferredLanguages; // BString fCountryCodeName; // BString fCountryDateFormat; - BCountry* fDefaultCountry; + BCountry fDefaultCountry; RosterData(); ~RosterData(); @@ -241,19 +241,20 @@ RosterData::RosterData() fPreferredLanguages.AddString("language", "en"); BString codeName; + if (settingsMessage.FindString("country", &codeName) == B_OK) - fDefaultCountry = new BCountry(codeName); + fDefaultCountry = BCountry(codeName); else - fDefaultCountry = new BCountry("en_US"); + fDefaultCountry = BCountry("en_US"); BString timeFormat; if (settingsMessage.FindString("shortTimeFormat", &timeFormat) == B_OK) - fDefaultCountry->SetTimeFormat(timeFormat, false); + fDefaultCountry.SetTimeFormat(timeFormat, false); if (settingsMessage.FindString("longTimeFormat", &timeFormat) == B_OK) - fDefaultCountry->SetTimeFormat(timeFormat, true); + fDefaultCountry.SetTimeFormat(timeFormat, true); return; } @@ -262,7 +263,7 @@ RosterData::RosterData() // Something went wrong (no settings file or invalid BMessage // set everything to default values fPreferredLanguages.AddString("language", "en"); - fDefaultCountry = new BCountry("en_US"); + fDefaultCountry = BCountry("en_US"); log_team(LOG_ERR, "*** No language preference found!\n"); } @@ -271,7 +272,6 @@ RosterData::~RosterData() { BAutolock lock(fLock); assert(lock.IsLocked()); - delete fDefaultCountry; CleanupCatalogAddOns(); closelog(); } @@ -540,10 +540,7 @@ BLocaleRoster::GetDefaultCountry(BCountry **country) const if (!country) return B_BAD_VALUE; - BAutolock lock(gRosterData.fLock); - assert(lock.IsLocked()); - - *country = gRosterData.fDefaultCountry; + *country = &gRosterData.fDefaultCountry; return B_OK; } @@ -567,11 +564,13 @@ BLocaleRoster::GetLanguage(const char* languageCode, void BLocaleRoster::SetDefaultCountry(BCountry* newDefault) const { + if (newDefault == NULL) + return; + BAutolock lock(gRosterData.fLock); assert(lock.IsLocked()); - delete gRosterData.fDefaultCountry; - gRosterData.fDefaultCountry = newDefault; + gRosterData.fDefaultCountry = *newDefault; } diff --git a/src/preferences/locale/TimeFormatSettingsView.cpp b/src/preferences/locale/TimeFormatSettingsView.cpp index df049f0232..36f3bb82c0 100644 --- a/src/preferences/locale/TimeFormatSettingsView.cpp +++ b/src/preferences/locale/TimeFormatSettingsView.cpp @@ -147,7 +147,7 @@ IsSpecialDateChar(char charToTest) FormatView::FormatView(BCountry* country) : BView("WindowsSettingsView", B_FRAME_EVENTS), - fCountry(country) + fCountry(*country) { SetLayout(new BGroupLayout(B_HORIZONTAL)); @@ -185,8 +185,8 @@ FormatView::FormatView(BCountry* country) f12HrRadioButton = new BRadioButton("", B_TRANSLATE("12 hour"), new BMessage(kClockFormatChange)); - fCountry->TimeFormat(fOriginalTimeFormat, false); - fCountry->TimeFormat(fOriginalLongTimeFormat, true); + fCountry.TimeFormat(fOriginalTimeFormat, false); + fCountry.TimeFormat(fOriginalLongTimeFormat, true); if (fOriginalTimeFormat.FindFirst("a") != B_ERROR) { f12HrRadioButton->SetValue(B_CONTROL_ON); fCountryIs24Hr = false; @@ -461,7 +461,7 @@ FormatView::MessageReceived(BMessage* message) timeFormat.Append(" a"); } } - fCountry->SetTimeFormat(timeFormat.String(), false); + fCountry.SetTimeFormat(timeFormat.String(), false); newMessage.AddString("shortTimeFormat", timeFormat); timeFormat = fOriginalLongTimeFormat; @@ -479,7 +479,7 @@ FormatView::MessageReceived(BMessage* message) timeFormat.Append(" a"); } } - fCountry->SetTimeFormat(timeFormat.String(), true); + fCountry.SetTimeFormat(timeFormat.String(), true); newMessage.AddString("longTimeFormat", timeFormat); _UpdateExamples(); Window()->PostMessage(kSettingsContentsModified); @@ -504,8 +504,11 @@ FormatView::SetDefaults() settings.SetClockTo24Hr(false); */ - delete fCountry; - be_locale_roster->GetDefaultCountry(&fCountry); + BCountry* defaultCountry; + be_locale_roster->GetDefaultCountry(&defaultCountry); + fCountry = *defaultCountry; + // We work on a copy of the default country and set the changes when + // closing the preflet _UpdateExamples(); _SendNotices(); } @@ -544,13 +547,12 @@ FormatView::Revert() void FormatView::SetCountry(BCountry* country) { - delete fCountry; - fCountry = country; + fCountry = *country; fOriginalTimeFormat.Truncate(0); - fCountry->TimeFormat(fOriginalTimeFormat, false); + fCountry.TimeFormat(fOriginalTimeFormat, false); fOriginalLongTimeFormat.Truncate(0); - fCountry->TimeFormat(fOriginalLongTimeFormat, true); + fCountry.TimeFormat(fOriginalLongTimeFormat, true); if (fOriginalTimeFormat.FindFirst("a") != B_ERROR) { f12HrRadioButton->SetValue(B_CONTROL_ON); @@ -616,19 +618,19 @@ FormatView::_UpdateExamples() time_t timeValue = (time_t)time(NULL); BString timeFormat; - fCountry->FormatDate(&timeFormat, timeValue, true); + fCountry.FormatDate(&timeFormat, timeValue, true); fLongDateExampleView->SetText(timeFormat); - fCountry->FormatDate(&timeFormat, timeValue, false); + fCountry.FormatDate(&timeFormat, timeValue, false); fShortDateExampleView->SetText(timeFormat); - fCountry->FormatTime(&timeFormat, timeValue, true); + fCountry.FormatTime(&timeFormat, timeValue, true); fLongTimeExampleView->SetText(timeFormat); - fCountry->FormatTime(&timeFormat, timeValue, false); + fCountry.FormatTime(&timeFormat, timeValue, false); fShortTimeExampleView->SetText(timeFormat); - status_t Error = fCountry->FormatNumber(&timeFormat, 1234.5678); + status_t Error = fCountry.FormatNumber(&timeFormat, 1234.5678); if (Error == B_OK) fNumberFormatExampleView->SetText(timeFormat); else @@ -658,7 +660,7 @@ FormatView::_ParseDateFormat() { // TODO parse the short date too BString dateFormatString; - fCountry->DateFormat(dateFormatString, true); + fCountry.DateFormat(dateFormatString, true); const char* dateFormat = dateFormatString.String(); // Travel trough the string and parse it @@ -710,7 +712,7 @@ FormatView::_ParseDateFormat() // Short date is a bit more tricky, we want to extract the separator dateFormatString.Truncate(0); - fCountry->DateFormat(dateFormatString, false); + fCountry.DateFormat(dateFormatString, false); dateFormat = dateFormatString.String(); // Travel trough the string and parse it @@ -776,7 +778,7 @@ FormatView::_UpdateLongDateFormatString() } // TODO save this in the settings preflet and make the roster load it back - fCountry->SetDateFormat(newDateFormat.String()); + fCountry.SetDateFormat(newDateFormat.String()); newDateFormat.Truncate(0); @@ -787,5 +789,5 @@ FormatView::_UpdateLongDateFormatString() newDateFormat.Append(fDateString[2]); // TODO save this in the settings preflet and make the roster load it back - fCountry->SetDateFormat(newDateFormat.String(), false); + fCountry.SetDateFormat(newDateFormat.String(), false); } diff --git a/src/preferences/locale/TimeFormatSettingsView.h b/src/preferences/locale/TimeFormatSettingsView.h index d036bdd092..624b88cf15 100644 --- a/src/preferences/locale/TimeFormatSettingsView.h +++ b/src/preferences/locale/TimeFormatSettingsView.h @@ -7,6 +7,7 @@ #include +#include #include #include @@ -81,7 +82,7 @@ private: BString fOriginalLongTimeFormat; bool fCountryIs24Hr; - BCountry* fCountry; + BCountry fCountry; BBox* fDateBox; BBox* fTimeBox;