1 /* 2 * Copyright 2009, Adrien Destugues, pulkomandy@gmail.com. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "FormatSettingsView.h" 8 9 #include <stdlib.h> 10 11 #include <Alert.h> 12 #include <Application.h> 13 #include <Catalog.h> 14 #include <CheckBox.h> 15 #include <ControlLook.h> 16 #include <GridLayout.h> 17 #include <GridLayoutBuilder.h> 18 #include <GroupLayout.h> 19 #include <GroupLayoutBuilder.h> 20 #include <LayoutBuilder.h> 21 #include <Locale.h> 22 #include <MutableLocaleRoster.h> 23 #include <Message.h> 24 #include <Menu.h> 25 #include <MenuField.h> 26 #include <MenuItem.h> 27 #include <PopUpMenu.h> 28 #include <RadioButton.h> 29 #include <ScrollView.h> 30 #include <ScrollBar.h> 31 #include <SeparatorView.h> 32 #include <SpaceLayoutItem.h> 33 #include <String.h> 34 #include <StringView.h> 35 #include <TextControl.h> 36 #include <Window.h> 37 38 #include "LocalePreflet.h" 39 40 41 using BPrivate::MutableLocaleRoster; 42 43 44 #undef B_TRANSLATION_CONTEXT 45 #define B_TRANSLATION_CONTEXT "TimeFormatSettings" 46 47 48 // #pragma mark - 49 50 51 FormatSettingsView::FormatSettingsView() 52 : 53 BView("WindowsSettingsView", B_FRAME_EVENTS) 54 { 55 fUseLanguageStringsCheckBox = new BCheckBox( 56 B_TRANSLATE("Use month/day-names from preferred language"), 57 new BMessage(kStringsLanguageChange)); 58 59 BStringView* fullDateLabel 60 = new BStringView("", B_TRANSLATE("Full format:")); 61 fullDateLabel->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 62 B_ALIGN_VERTICAL_UNSET)); 63 BStringView* longDateLabel 64 = new BStringView("", B_TRANSLATE("Long format:")); 65 longDateLabel->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 66 B_ALIGN_VERTICAL_UNSET)); 67 BStringView* mediumDateLabel 68 = new BStringView("", B_TRANSLATE("Medium format:")); 69 mediumDateLabel->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 70 B_ALIGN_VERTICAL_UNSET)); 71 BStringView* shortDateLabel 72 = new BStringView("", B_TRANSLATE("Short format:")); 73 shortDateLabel->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 74 B_ALIGN_VERTICAL_UNSET)); 75 76 fFullDateExampleView = new BStringView("", ""); 77 fFullDateExampleView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 78 B_ALIGN_VERTICAL_UNSET)); 79 fLongDateExampleView = new BStringView("", ""); 80 fLongDateExampleView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 81 B_ALIGN_VERTICAL_UNSET)); 82 fMediumDateExampleView = new BStringView("", ""); 83 fMediumDateExampleView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 84 B_ALIGN_VERTICAL_UNSET)); 85 fShortDateExampleView = new BStringView("", ""); 86 fShortDateExampleView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 87 B_ALIGN_VERTICAL_UNSET)); 88 89 f24HourRadioButton = new BRadioButton("", B_TRANSLATE("24 hour"), 90 new BMessage(kClockFormatChange)); 91 f12HourRadioButton = new BRadioButton("", B_TRANSLATE("12 hour"), 92 new BMessage(kClockFormatChange)); 93 94 float spacing = be_control_look->DefaultItemSpacing(); 95 96 BStringView* fullTimeLabel 97 = new BStringView("", B_TRANSLATE("Full format:")); 98 fullTimeLabel->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 99 B_ALIGN_VERTICAL_UNSET)); 100 BStringView* longTimeLabel 101 = new BStringView("", B_TRANSLATE("Long format:")); 102 longTimeLabel->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 103 B_ALIGN_VERTICAL_UNSET)); 104 BStringView* mediumTimeLabel 105 = new BStringView("", B_TRANSLATE("Medium format:")); 106 mediumTimeLabel->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 107 B_ALIGN_VERTICAL_UNSET)); 108 BStringView* shortTimeLabel 109 = new BStringView("", B_TRANSLATE("Short format:")); 110 shortTimeLabel->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 111 B_ALIGN_VERTICAL_UNSET)); 112 113 fFullTimeExampleView = new BStringView("", ""); 114 fFullTimeExampleView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 115 B_ALIGN_VERTICAL_UNSET)); 116 fLongTimeExampleView = new BStringView("", ""); 117 fLongTimeExampleView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 118 B_ALIGN_VERTICAL_UNSET)); 119 fMediumTimeExampleView = new BStringView("", ""); 120 fMediumTimeExampleView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 121 B_ALIGN_VERTICAL_UNSET)); 122 fShortTimeExampleView = new BStringView("", ""); 123 fShortTimeExampleView->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 124 B_ALIGN_VERTICAL_UNSET)); 125 126 BStringView* positiveNumberLabel 127 = new BStringView("", B_TRANSLATE("Positive:")); 128 positiveNumberLabel->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 129 B_ALIGN_VERTICAL_UNSET)); 130 BStringView* negativeNumberLabel 131 = new BStringView("", B_TRANSLATE("Negative:")); 132 negativeNumberLabel->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 133 B_ALIGN_VERTICAL_UNSET)); 134 135 fPositiveNumberExampleView = new BStringView("", ""); 136 fPositiveNumberExampleView->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, 137 B_ALIGN_VERTICAL_UNSET)); 138 fNegativeNumberExampleView = new BStringView("", ""); 139 fNegativeNumberExampleView->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, 140 B_ALIGN_VERTICAL_UNSET)); 141 142 BStringView* positiveMonetaryLabel 143 = new BStringView("", B_TRANSLATE("Positive:")); 144 positiveMonetaryLabel->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 145 B_ALIGN_VERTICAL_UNSET)); 146 BStringView* negativeMonetaryLabel 147 = new BStringView("", B_TRANSLATE("Negative:")); 148 negativeMonetaryLabel->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 149 B_ALIGN_VERTICAL_UNSET)); 150 151 fPositiveMonetaryExampleView = new BStringView("", ""); 152 fPositiveMonetaryExampleView->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, 153 B_ALIGN_VERTICAL_UNSET)); 154 fNegativeMonetaryExampleView = new BStringView("", ""); 155 fNegativeMonetaryExampleView->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, 156 B_ALIGN_VERTICAL_UNSET)); 157 158 Refresh(true); 159 160 fDateBox = new BBox(B_TRANSLATE("Date")); 161 fTimeBox = new BBox(B_TRANSLATE("Time")); 162 fNumberBox = new BBox(B_TRANSLATE("Numbers")); 163 fMonetaryBox = new BBox(B_TRANSLATE("Currency")); 164 165 fDateBox->SetLabel(B_TRANSLATE("Date")); 166 fTimeBox->SetLabel(B_TRANSLATE("Time")); 167 fNumberBox->SetLabel(B_TRANSLATE("Numbers")); 168 fMonetaryBox->SetLabel(B_TRANSLATE("Currency")); 169 170 fDateBox->AddChild(BLayoutBuilder::Grid<>(spacing, spacing / 2) 171 .SetInsets(spacing, spacing, spacing, spacing) 172 .Add(fullDateLabel, 0, 0) 173 .Add(fFullDateExampleView, 1, 0) 174 .Add(BSpaceLayoutItem::CreateGlue(), 2, 0) 175 .Add(longDateLabel, 0, 1) 176 .Add(fLongDateExampleView, 1, 1) 177 .Add(BSpaceLayoutItem::CreateGlue(), 2, 1) 178 .Add(mediumDateLabel, 0, 2) 179 .Add(fMediumDateExampleView, 1, 2) 180 .Add(BSpaceLayoutItem::CreateGlue(), 2, 2) 181 .Add(shortDateLabel, 0, 3) 182 .Add(fShortDateExampleView, 1, 3) 183 .Add(BSpaceLayoutItem::CreateGlue(), 2, 3) 184 .View()); 185 186 fTimeBox->AddChild(BLayoutBuilder::Grid<>(spacing, spacing / 2) 187 .SetInsets(spacing, spacing, spacing, spacing) 188 .AddGroup(B_HORIZONTAL, spacing, 0, 0, 2) 189 .Add(f24HourRadioButton, 0) 190 .Add(f12HourRadioButton, 0) 191 .AddGlue() 192 .End() 193 .Add(fullTimeLabel, 0, 1) 194 .Add(fFullTimeExampleView, 1, 1) 195 .Add(BSpaceLayoutItem::CreateGlue(), 2, 1) 196 .Add(longTimeLabel, 0, 2) 197 .Add(fLongTimeExampleView, 1, 2) 198 .Add(BSpaceLayoutItem::CreateGlue(), 2, 2) 199 .Add(mediumTimeLabel, 0, 3) 200 .Add(fMediumTimeExampleView, 1, 3) 201 .Add(BSpaceLayoutItem::CreateGlue(), 2, 3) 202 .Add(shortTimeLabel, 0, 4) 203 .Add(fShortTimeExampleView, 1, 4) 204 .Add(BSpaceLayoutItem::CreateGlue(), 2, 4) 205 .View()); 206 207 fNumberBox->AddChild(BLayoutBuilder::Grid<>(spacing, spacing / 2) 208 .SetInsets(spacing, spacing, spacing, spacing) 209 .Add(positiveNumberLabel, 0, 0) 210 .Add(fPositiveNumberExampleView, 1, 0) 211 .Add(BSpaceLayoutItem::CreateGlue(), 2, 0) 212 .Add(negativeNumberLabel, 0, 1) 213 .Add(fNegativeNumberExampleView, 1, 1) 214 .Add(BSpaceLayoutItem::CreateGlue(), 2, 1) 215 .View()); 216 217 fMonetaryBox->AddChild(BLayoutBuilder::Grid<>(spacing, spacing / 2) 218 .SetInsets(spacing, spacing, spacing, spacing) 219 .Add(positiveMonetaryLabel, 0, 0) 220 .Add(fPositiveMonetaryExampleView, 1, 0) 221 .Add(BSpaceLayoutItem::CreateGlue(), 2, 0) 222 .Add(negativeMonetaryLabel, 0, 1) 223 .Add(fNegativeMonetaryExampleView, 1, 1) 224 .Add(BSpaceLayoutItem::CreateGlue(), 2, 1) 225 .View()); 226 227 BGroupLayout* rootLayout = new BGroupLayout(B_VERTICAL, spacing); 228 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 229 SetLayout(rootLayout); 230 BLayoutBuilder::Group<>(rootLayout) 231 .Add(fUseLanguageStringsCheckBox) 232 .Add(fDateBox) 233 .Add(fTimeBox) 234 .AddGroup(B_HORIZONTAL, spacing) 235 .Add(fNumberBox) 236 .Add(fMonetaryBox) 237 .AddGlue() 238 .End() 239 .AddGlue(); 240 } 241 242 243 FormatSettingsView::~FormatSettingsView() 244 { 245 } 246 247 248 void 249 FormatSettingsView::AttachedToWindow() 250 { 251 fUseLanguageStringsCheckBox->SetTarget(this); 252 f24HourRadioButton->SetTarget(this); 253 f12HourRadioButton->SetTarget(this); 254 } 255 256 257 void 258 FormatSettingsView::MessageReceived(BMessage* message) 259 { 260 switch (message->what) { 261 case kClockFormatChange: 262 { 263 BFormattingConventions conventions; 264 BLocale::Default()->GetFormattingConventions(&conventions); 265 conventions.SetExplicitUse24HourClock( 266 f24HourRadioButton->Value() ? true : false); 267 MutableLocaleRoster::Default()->SetDefaultFormattingConventions( 268 conventions); 269 270 _UpdateExamples(); 271 Window()->PostMessage(kMsgSettingsChanged); 272 break; 273 } 274 275 case kStringsLanguageChange: 276 { 277 BFormattingConventions conventions; 278 BLocale::Default()->GetFormattingConventions(&conventions); 279 conventions.SetUseStringsFromPreferredLanguage( 280 fUseLanguageStringsCheckBox->Value() ? true : false); 281 MutableLocaleRoster::Default()->SetDefaultFormattingConventions( 282 conventions); 283 284 _UpdateExamples(); 285 286 Window()->PostMessage(kMsgSettingsChanged); 287 break; 288 } 289 290 default: 291 BView::MessageReceived(message); 292 } 293 } 294 295 296 void 297 FormatSettingsView::Revert() 298 { 299 MutableLocaleRoster::Default()->SetDefaultFormattingConventions( 300 fInitialConventions); 301 302 _UpdateExamples(); 303 } 304 305 306 void 307 FormatSettingsView::Refresh(bool setInitial) 308 { 309 BFormattingConventions conventions; 310 BLocale::Default()->GetFormattingConventions(&conventions); 311 if (setInitial) 312 fInitialConventions = conventions; 313 314 if (!conventions.Use24HourClock()) { 315 f12HourRadioButton->SetValue(B_CONTROL_ON); 316 fLocaleIs24Hour = false; 317 } else { 318 f24HourRadioButton->SetValue(B_CONTROL_ON); 319 fLocaleIs24Hour = true; 320 } 321 322 fUseLanguageStringsCheckBox->SetValue( 323 conventions.UseStringsFromPreferredLanguage() 324 ? B_CONTROL_ON : B_CONTROL_OFF); 325 326 _UpdateExamples(); 327 } 328 329 330 // Return true if the Revert button should be enabled (i.e. something has been 331 // changed) 332 bool 333 FormatSettingsView::IsReversible() const 334 { 335 BFormattingConventions conventions; 336 BLocale::Default()->GetFormattingConventions(&conventions); 337 338 return conventions != fInitialConventions; 339 } 340 341 342 void 343 FormatSettingsView::_UpdateExamples() 344 { 345 time_t timeValue = (time_t)time(NULL); 346 BString result; 347 348 BLocale::Default()->FormatDate(&result, timeValue, B_FULL_DATE_FORMAT); 349 fFullDateExampleView->SetText(result); 350 351 BLocale::Default()->FormatDate(&result, timeValue, B_LONG_DATE_FORMAT); 352 fLongDateExampleView->SetText(result); 353 354 BLocale::Default()->FormatDate(&result, timeValue, B_MEDIUM_DATE_FORMAT); 355 fMediumDateExampleView->SetText(result); 356 357 BLocale::Default()->FormatDate(&result, timeValue, B_SHORT_DATE_FORMAT); 358 fShortDateExampleView->SetText(result); 359 360 BLocale::Default()->FormatTime(&result, timeValue, B_FULL_TIME_FORMAT); 361 fFullTimeExampleView->SetText(result); 362 363 BLocale::Default()->FormatTime(&result, timeValue, B_LONG_TIME_FORMAT); 364 fLongTimeExampleView->SetText(result); 365 366 BLocale::Default()->FormatTime(&result, timeValue, B_MEDIUM_TIME_FORMAT); 367 fMediumTimeExampleView->SetText(result); 368 369 BLocale::Default()->FormatTime(&result, timeValue, B_SHORT_TIME_FORMAT); 370 fShortTimeExampleView->SetText(result); 371 372 status_t status = BLocale::Default()->FormatNumber(&result, 1234.5678); 373 if (status == B_OK) 374 fPositiveNumberExampleView->SetText(result); 375 else 376 fPositiveNumberExampleView->SetText("ERROR"); 377 378 status = BLocale::Default()->FormatNumber(&result, -1234.5678); 379 if (status == B_OK) 380 fNegativeNumberExampleView->SetText(result); 381 else 382 fNegativeNumberExampleView->SetText("ERROR"); 383 384 status = BLocale::Default()->FormatMonetary(&result, 1234.56); 385 if (status == B_OK) 386 fPositiveMonetaryExampleView->SetText(result); 387 else 388 fPositiveMonetaryExampleView->SetText("ERROR"); 389 390 status = BLocale::Default()->FormatMonetary(&result, -1234.56); 391 if (status == B_OK) 392 fNegativeMonetaryExampleView->SetText(result); 393 else 394 fNegativeMonetaryExampleView->SetText("ERROR"); 395 } 396