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 B_LOCALE_CHANGED: 262 { 263 // Time updated 12/24 hour clock 264 BFormattingConventions conventions; 265 BLocale::Default()->GetFormattingConventions(&conventions); 266 if (conventions.Use24HourClock()) 267 f24HourRadioButton->SetValue(B_CONTROL_ON); 268 else 269 f12HourRadioButton->SetValue(B_CONTROL_ON); 270 271 _UpdateExamples(); 272 Window()->PostMessage(kMsgSettingsChanged); 273 break; 274 } 275 276 case kClockFormatChange: 277 { 278 BFormattingConventions conventions; 279 BLocale::Default()->GetFormattingConventions(&conventions); 280 conventions.SetExplicitUse24HourClock( 281 f24HourRadioButton->Value() == B_CONTROL_ON); 282 MutableLocaleRoster::Default()->SetDefaultFormattingConventions( 283 conventions); 284 285 _UpdateExamples(); 286 Window()->PostMessage(kMsgSettingsChanged); 287 break; 288 } 289 290 case kStringsLanguageChange: 291 { 292 BFormattingConventions conventions; 293 BLocale::Default()->GetFormattingConventions(&conventions); 294 conventions.SetUseStringsFromPreferredLanguage( 295 fUseLanguageStringsCheckBox->Value() ? true : false); 296 MutableLocaleRoster::Default()->SetDefaultFormattingConventions( 297 conventions); 298 299 _UpdateExamples(); 300 301 Window()->PostMessage(kMsgSettingsChanged); 302 break; 303 } 304 305 default: 306 BView::MessageReceived(message); 307 } 308 } 309 310 311 void 312 FormatSettingsView::Revert() 313 { 314 MutableLocaleRoster::Default()->SetDefaultFormattingConventions( 315 fInitialConventions); 316 317 _UpdateExamples(); 318 } 319 320 321 void 322 FormatSettingsView::Refresh(bool setInitial) 323 { 324 BFormattingConventions conventions; 325 BLocale::Default()->GetFormattingConventions(&conventions); 326 if (setInitial) 327 fInitialConventions = conventions; 328 329 if (!conventions.Use24HourClock()) { 330 f12HourRadioButton->SetValue(B_CONTROL_ON); 331 fLocaleIs24Hour = false; 332 } else { 333 f24HourRadioButton->SetValue(B_CONTROL_ON); 334 fLocaleIs24Hour = true; 335 } 336 337 fUseLanguageStringsCheckBox->SetValue( 338 conventions.UseStringsFromPreferredLanguage() 339 ? B_CONTROL_ON : B_CONTROL_OFF); 340 341 _UpdateExamples(); 342 } 343 344 345 // Return true if the Revert button should be enabled (i.e. something has been 346 // changed) 347 bool 348 FormatSettingsView::IsReversible() const 349 { 350 BFormattingConventions conventions; 351 BLocale::Default()->GetFormattingConventions(&conventions); 352 353 return conventions != fInitialConventions; 354 } 355 356 357 void 358 FormatSettingsView::_UpdateExamples() 359 { 360 time_t timeValue = (time_t)time(NULL); 361 BString result; 362 363 BLocale::Default()->FormatDate(&result, timeValue, B_FULL_DATE_FORMAT); 364 fFullDateExampleView->SetText(result); 365 366 BLocale::Default()->FormatDate(&result, timeValue, B_LONG_DATE_FORMAT); 367 fLongDateExampleView->SetText(result); 368 369 BLocale::Default()->FormatDate(&result, timeValue, B_MEDIUM_DATE_FORMAT); 370 fMediumDateExampleView->SetText(result); 371 372 BLocale::Default()->FormatDate(&result, timeValue, B_SHORT_DATE_FORMAT); 373 fShortDateExampleView->SetText(result); 374 375 BLocale::Default()->FormatTime(&result, timeValue, B_FULL_TIME_FORMAT); 376 fFullTimeExampleView->SetText(result); 377 378 BLocale::Default()->FormatTime(&result, timeValue, B_LONG_TIME_FORMAT); 379 fLongTimeExampleView->SetText(result); 380 381 BLocale::Default()->FormatTime(&result, timeValue, B_MEDIUM_TIME_FORMAT); 382 fMediumTimeExampleView->SetText(result); 383 384 BLocale::Default()->FormatTime(&result, timeValue, B_SHORT_TIME_FORMAT); 385 fShortTimeExampleView->SetText(result); 386 387 status_t status = BLocale::Default()->FormatNumber(&result, 1234.5678); 388 if (status == B_OK) 389 fPositiveNumberExampleView->SetText(result); 390 else 391 fPositiveNumberExampleView->SetText("ERROR"); 392 393 status = BLocale::Default()->FormatNumber(&result, -1234.5678); 394 if (status == B_OK) 395 fNegativeNumberExampleView->SetText(result); 396 else 397 fNegativeNumberExampleView->SetText("ERROR"); 398 399 status = BLocale::Default()->FormatMonetary(&result, 1234.56); 400 if (status == B_OK) 401 fPositiveMonetaryExampleView->SetText(result); 402 else 403 fPositiveMonetaryExampleView->SetText("ERROR"); 404 405 status = BLocale::Default()->FormatMonetary(&result, -1234.56); 406 if (status == B_OK) 407 fNegativeMonetaryExampleView->SetText(result); 408 else 409 fNegativeMonetaryExampleView->SetText("ERROR"); 410 } 411