1194612Sed/* 2194612Sed * Copyright 2008-2010, Stephan A��mus <superstippi@gmx.de>. 3194612Sed * Copyright 1998, Eric Shepherd. 4194612Sed * All rights reserved. Distributed under the terms of the Be Sample Code 5194612Sed * license. 6194612Sed */ 7194612Sed 8194612Sed//! Be Newsletter Volume II, Issue 35; September 2, 1998 (Eric Shepherd) 9194612Sed 10194612Sed#include "SettingsMessage.h" 11194612Sed 12194612Sed#include <new> 13194612Sed 14194612Sed#include <Autolock.h> 15194612Sed#include <Entry.h> 16249423Sdim#include <File.h> 17249423Sdim#include <Messenger.h> 18249423Sdim#include <String.h> 19218893Sdim 20249423Sdim 21194612SedSettingsMessage::SettingsMessage(directory_which directory, 22194612Sed const char* filename) 23218893Sdim : 24194612Sed BMessage('pref'), 25194612Sed fListeners(0) 26249423Sdim{ 27249423Sdim fStatus = find_directory(directory, &fPath); 28198090Srdivacky 29198090Srdivacky if (fStatus == B_OK) 30198090Srdivacky fStatus = fPath.Append(filename); 31198090Srdivacky 32198090Srdivacky if (fStatus == B_OK) 33198090Srdivacky fStatus = Load(); 34198090Srdivacky} 35198090Srdivacky 36198090Srdivacky 37198090SrdivackySettingsMessage::~SettingsMessage() 38198090Srdivacky{ 39198090Srdivacky Save(); 40198090Srdivacky 41194612Sed for (int32 i = fListeners.CountItems() - 1; i >= 0; i--) 42198090Srdivacky delete reinterpret_cast<BMessenger*>(fListeners.ItemAtFast(i)); 43198090Srdivacky} 44198090Srdivacky 45203954Srdivacky 46194612Sedstatus_t 47194612SedSettingsMessage::InitCheck() const 48194612Sed{ 49194612Sed return fStatus; 50194612Sed} 51194612Sed 52194612Sed 53194612Sedstatus_t 54194612SedSettingsMessage::Load() 55263508Sdim{ 56263508Sdim BAutolock _(this); 57263508Sdim 58218893Sdim BFile file(fPath.Path(), B_READ_ONLY); 59223017Sdim status_t status = file.InitCheck(); 60223017Sdim 61203954Srdivacky if (status == B_OK) 62194612Sed status = Unflatten(&file); 63194612Sed 64223017Sdim return status; 65223017Sdim} 66194612Sed 67203954Srdivacky 68263508Sdimstatus_t 69194612SedSettingsMessage::Save() const 70218893Sdim{ 71194612Sed BAutolock _(const_cast<SettingsMessage*>(this)); 72194612Sed 73194612Sed BFile file(fPath.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); 74194612Sed status_t status = file.InitCheck(); 75194612Sed 76194612Sed if (status == B_OK) 77194612Sed status = Flatten(&file); 78194612Sed 79194612Sed return status; 80194612Sed} 81194612Sed 82194612Sed 83194612Sedbool 84194612SedSettingsMessage::AddListener(const BMessenger& listener) 85194612Sed{ 86239462Sdim BAutolock _(this); 87239462Sdim 88239462Sdim BMessenger* listenerCopy = new(std::nothrow) BMessenger(listener); 89239462Sdim if (listenerCopy && fListeners.AddItem(listenerCopy)) 90194612Sed return true; 91194612Sed delete listenerCopy; 92203954Srdivacky return false; 93194612Sed} 94203954Srdivacky 95194612Sed 96194612Sedvoid 97194612SedSettingsMessage::RemoveListener(const BMessenger& listener) 98203954Srdivacky{ 99239462Sdim BAutolock _(this); 100239462Sdim 101194612Sed for (int32 i = fListeners.CountItems() - 1; i >= 0; i--) { 102198090Srdivacky BMessenger* listenerItem = reinterpret_cast<BMessenger*>( 103198090Srdivacky fListeners.ItemAtFast(i)); 104198090Srdivacky if (*listenerItem == listener) { 105198090Srdivacky fListeners.RemoveItem(i); 106203954Srdivacky delete listenerItem; 107198090Srdivacky return; 108198090Srdivacky } 109198090Srdivacky } 110198090Srdivacky} 111198090Srdivacky 112198090Srdivacky 113198090Srdivacky// #pragma mark - 114194612Sed 115194612Sed 116203954Srdivackystatus_t 117198090SrdivackySettingsMessage::SetValue(const char* name, bool value) 118198090Srdivacky{ 119198090Srdivacky status_t ret = ReplaceBool(name, value); 120203954Srdivacky if (ret != B_OK) 121198090Srdivacky ret = AddBool(name, value); 122198090Srdivacky if (ret == B_OK) 123198090Srdivacky _NotifyValueChanged(name); 124198090Srdivacky return ret; 125198090Srdivacky} 126239462Sdim 127239462Sdim 128239462Sdimstatus_t 129239462SdimSettingsMessage::SetValue(const char* name, int8 value) 130194612Sed{ 131194612Sed status_t ret = ReplaceInt8(name, value); 132195340Sed if (ret != B_OK) 133194612Sed ret = AddInt8(name, value); 134203954Srdivacky if (ret == B_OK) 135194612Sed _NotifyValueChanged(name); 136194612Sed return ret; 137194612Sed} 138195340Sed 139203954Srdivacky 140195340Sedstatus_t 141195340SedSettingsMessage::SetValue(const char* name, int16 value) 142195340Sed{ 143194612Sed status_t ret = ReplaceInt16(name, value); 144194612Sed if (ret != B_OK) 145194612Sed ret = AddInt16(name, value); 146195340Sed if (ret == B_OK) 147195340Sed _NotifyValueChanged(name); 148195340Sed return ret; 149195340Sed} 150195340Sed 151234353Sdim 152234353Sdimstatus_t 153249423SdimSettingsMessage::SetValue(const char* name, uint16 value) 154249423Sdim{ 155203954Srdivacky status_t ret = ReplaceUInt16(name, value); 156194612Sed if (ret != B_OK) 157239462Sdim ret = AddUInt16(name, value); 158239462Sdim if (ret == B_OK) 159239462Sdim _NotifyValueChanged(name); 160239462Sdim return ret; 161239462Sdim} 162239462Sdim 163239462Sdim 164239462Sdimstatus_t 165239462SdimSettingsMessage::SetValue(const char* name, int32 value) 166203954Srdivacky{ 167239462Sdim status_t ret = ReplaceInt32(name, value); 168239462Sdim if (ret != B_OK) 169239462Sdim ret = AddInt32(name, value); 170239462Sdim if (ret == B_OK) 171239462Sdim _NotifyValueChanged(name); 172239462Sdim return ret; 173239462Sdim} 174239462Sdim 175239462Sdim 176199989Srdivackystatus_t 177239462SdimSettingsMessage::SetValue(const char* name, uint32 value) 178239462Sdim{ 179239462Sdim status_t ret = ReplaceUInt32(name, value); 180239462Sdim if (ret != B_OK) 181239462Sdim ret = AddUInt32(name, value); 182239462Sdim if (ret == B_BAD_TYPE && HasData(name, B_INT32_TYPE)) { 183199989Srdivacky // For compatibility with older versions of this class, replace an int32 184239462Sdim RemoveData(name); 185239462Sdim ret = AddUInt32(name, value); 186239462Sdim } 187239462Sdim if (ret == B_OK) 188239462Sdim _NotifyValueChanged(name); 189239462Sdim return ret; 190239462Sdim} 191239462Sdim 192239462Sdim 193239462Sdimstatus_t 194239462SdimSettingsMessage::SetValue(const char* name, int64 value) 195239462Sdim{ 196239462Sdim status_t ret = ReplaceInt64(name, value); 197239462Sdim if (ret != B_OK) 198239462Sdim ret = AddInt64(name, value); 199239462Sdim if (ret == B_OK) 200239462Sdim _NotifyValueChanged(name); 201249423Sdim return ret; 202239462Sdim} 203239462Sdim 204239462Sdim 205234353Sdimstatus_t 206239462SdimSettingsMessage::SetValue(const char* name, uint64 value) 207239462Sdim{ 208234353Sdim status_t ret = ReplaceUInt64(name, value); 209239462Sdim if (ret != B_OK) 210239462Sdim ret = AddUInt64(name, value); 211249423Sdim if (ret == B_OK) 212194612Sed _NotifyValueChanged(name); 213195340Sed return ret; 214263508Sdim} 215263508Sdim 216234982Sdim 217249423Sdimstatus_t 218249423SdimSettingsMessage::SetValue(const char* name, float value) 219234353Sdim{ 220206274Srdivacky status_t ret = ReplaceFloat(name, value); 221206274Srdivacky if (ret != B_OK) 222234353Sdim ret = AddFloat(name, value); 223206274Srdivacky if (ret == B_OK) 224206274Srdivacky _NotifyValueChanged(name); 225218893Sdim return ret; 226239462Sdim} 227239462Sdim 228239462Sdim 229239462Sdimstatus_t 230239462SdimSettingsMessage::SetValue(const char* name, double value) 231195340Sed{ 232234982Sdim status_t ret = ReplaceDouble(name, value); 233195340Sed if (ret != B_OK) 234195340Sed ret = AddDouble(name, value); 235263508Sdim if (ret == B_OK) 236263508Sdim _NotifyValueChanged(name); 237263508Sdim return ret; 238263508Sdim} 239263508Sdim 240263508Sdim 241195340Sedstatus_t 242195340SedSettingsMessage::SetValue(const char* name, const char* value) 243195340Sed{ 244195340Sed status_t ret = ReplaceString(name, value); 245249423Sdim if (ret != B_OK) 246234353Sdim ret = AddString(name, value); 247249423Sdim if (ret == B_OK) 248249423Sdim _NotifyValueChanged(name); 249249423Sdim return ret; 250234353Sdim} 251249423Sdim 252249423Sdim 253249423Sdimstatus_t 254234353SdimSettingsMessage::SetValue(const char* name, const BString& value) 255234353Sdim{ 256249423Sdim status_t ret = ReplaceString(name, value); 257249423Sdim if (ret != B_OK) 258249423Sdim ret = AddString(name, value); 259249423Sdim if (ret == B_OK) 260234353Sdim _NotifyValueChanged(name); 261249423Sdim return ret; 262249423Sdim} 263249423Sdim 264249423Sdim 265249423Sdimstatus_t 266249423SdimSettingsMessage::SetValue(const char* name, const BPoint& value) 267249423Sdim{ 268249423Sdim status_t ret = ReplacePoint(name, value); 269249423Sdim if (ret != B_OK) 270249423Sdim ret = AddPoint(name, value); 271249423Sdim if (ret == B_OK) 272249423Sdim _NotifyValueChanged(name); 273249423Sdim return ret; 274249423Sdim} 275249423Sdim 276249423Sdim 277249423Sdimstatus_t 278249423SdimSettingsMessage::SetValue(const char* name, const BRect& value) 279249423Sdim{ 280249423Sdim status_t ret = ReplaceRect(name, value); 281249423Sdim if (ret != B_OK) 282249423Sdim ret = AddRect(name, value); 283249423Sdim if (ret == B_OK) 284249423Sdim _NotifyValueChanged(name); 285249423Sdim return ret; 286249423Sdim} 287249423Sdim 288249423Sdim 289249423Sdimstatus_t 290249423SdimSettingsMessage::SetValue(const char* name, const entry_ref& value) 291249423Sdim{ 292249423Sdim status_t ret = ReplaceRef(name, &value); 293249423Sdim if (ret != B_OK) 294249423Sdim ret = AddRef(name, &value); 295249423Sdim if (ret == B_OK) 296249423Sdim _NotifyValueChanged(name); 297249423Sdim return ret; 298249423Sdim} 299249423Sdim 300249423Sdim 301249423Sdimstatus_t 302249423SdimSettingsMessage::SetValue(const char* name, const BMessage& value) 303249423Sdim{ 304249423Sdim status_t ret = ReplaceMessage(name, &value); 305249423Sdim if (ret != B_OK) 306249423Sdim ret = AddMessage(name, &value); 307249423Sdim if (ret == B_OK) 308249423Sdim _NotifyValueChanged(name); 309249423Sdim return ret; 310249423Sdim} 311249423Sdim 312249423Sdim 313249423Sdimstatus_t 314249423SdimSettingsMessage::SetValue(const char* name, const BFlattenable* value) 315249423Sdim{ 316249423Sdim status_t ret = ReplaceFlat(name, const_cast<BFlattenable*>(value)); 317249423Sdim if (ret != B_OK) 318249423Sdim ret = AddFlat(name, const_cast<BFlattenable*>(value)); 319249423Sdim if (ret == B_OK) 320249423Sdim _NotifyValueChanged(name); 321249423Sdim return ret; 322249423Sdim} 323249423Sdim 324249423Sdim 325249423Sdimstatus_t 326249423SdimSettingsMessage::SetValue(const char* name, type_code type, const void* data, 327249423Sdim ssize_t numBytes) 328249423Sdim{ 329249423Sdim status_t ret = ReplaceData(name, type, data, numBytes); 330249423Sdim if (ret != B_OK) 331249423Sdim ret = AddData(name, type, data, numBytes); 332249423Sdim if (ret == B_OK) 333249423Sdim _NotifyValueChanged(name); 334249423Sdim return ret; 335249423Sdim} 336249423Sdim 337249423Sdim 338249423Sdimstatus_t 339249423SdimSettingsMessage::SetValue(const char* name, const BFont& value) 340249423Sdim{ 341249423Sdim font_family family; 342249423Sdim font_style style; 343249423Sdim value.GetFamilyAndStyle(&family, &style); 344249423Sdim 345249423Sdim BMessage fontMessage; 346249423Sdim status_t ret = fontMessage.AddString("family", family); 347249423Sdim if (ret == B_OK) 348234982Sdim ret = fontMessage.AddString("style", style); 349234982Sdim if (ret == B_OK) 350239462Sdim ret = fontMessage.AddFloat("size", value.Size()); 351239462Sdim 352234982Sdim if (ret == B_OK) { 353234982Sdim if (ReplaceMessage(name, &fontMessage) != B_OK) 354234982Sdim ret = AddMessage(name, &fontMessage); 355234982Sdim } 356195340Sed if (ret == B_OK) 357195340Sed _NotifyValueChanged(name); 358195340Sed return ret; 359202878Srdivacky} 360202878Srdivacky 361202878Srdivacky 362202878Srdivacky// #pragma mark - 363202878Srdivacky 364203954Srdivacky 365202878Srdivackybool 366202878SrdivackySettingsMessage::GetValue(const char* name, bool defaultValue) const 367202878Srdivacky{ 368202878Srdivacky bool value; 369202878Srdivacky if (FindBool(name, &value) != B_OK) 370202878Srdivacky return defaultValue; 371195340Sed return value; 372203954Srdivacky} 373234353Sdim 374234982Sdim 375234982Sdimint8 376234982SdimSettingsMessage::GetValue(const char* name, int8 defaultValue) const 377234982Sdim{ 378234982Sdim int8 value; 379234982Sdim if (FindInt8(name, &value) != B_OK) 380234982Sdim return defaultValue; 381234982Sdim return value; 382234982Sdim} 383234982Sdim 384234982Sdim 385234982Sdimint16 386234982SdimSettingsMessage::GetValue(const char* name, int16 defaultValue) const 387234982Sdim{ 388234982Sdim int16 value; 389234353Sdim if (FindInt16(name, &value) != B_OK) 390234982Sdim return defaultValue; 391234982Sdim return value; 392234982Sdim} 393234982Sdim 394234982Sdim 395234982Sdimuint16 396202878SrdivackySettingsMessage::GetValue(const char* name, uint16 defaultValue) const 397199989Srdivacky{ 398234982Sdim uint16 value; 399234982Sdim if (FindUInt16(name, &value) != B_OK) 400234982Sdim return defaultValue; 401234353Sdim return value; 402234353Sdim} 403203954Srdivacky 404249423Sdim 405249423Sdimint32 406249423SdimSettingsMessage::GetValue(const char* name, int32 defaultValue) const 407249423Sdim{ 408249423Sdim int32 value; 409249423Sdim if (FindInt32(name, &value) != B_OK) 410249423Sdim return defaultValue; 411249423Sdim return value; 412249423Sdim} 413249423Sdim 414249423Sdim 415249423Sdimuint32 416234353SdimSettingsMessage::GetValue(const char* name, uint32 defaultValue) const 417249423Sdim{ 418234353Sdim uint32 value; 419234353Sdim if (FindUInt32(name, &value) == B_OK) 420234353Sdim return value; 421234353Sdim // For compatibility with older versions of this class, also accept an int32 422249423Sdim int32 signedValue; 423249423Sdim if (FindInt32(name, &signedValue) == B_OK && signedValue >= 0) 424249423Sdim return signedValue; 425195340Sed return defaultValue; 426249423Sdim} 427249423Sdim 428249423Sdim 429249423Sdimint64 430249423SdimSettingsMessage::GetValue(const char* name, int64 defaultValue) const 431249423Sdim{ 432249423Sdim int64 value; 433249423Sdim if (FindInt64(name, &value) != B_OK) 434234353Sdim return defaultValue; 435249423Sdim return value; 436234353Sdim} 437234353Sdim 438249423Sdim 439234353Sdimuint64 440234353SdimSettingsMessage::GetValue(const char* name, uint64 defaultValue) const 441234353Sdim{ 442234353Sdim uint64 value; 443234353Sdim if (FindUInt64(name, &value) != B_OK) 444234353Sdim return defaultValue; 445249423Sdim return value; 446234353Sdim} 447234982Sdim 448234982Sdim 449234982Sdimfloat 450234353SdimSettingsMessage::GetValue(const char* name, float defaultValue) const 451234353Sdim{ 452234353Sdim float value; 453234353Sdim if (FindFloat(name, &value) != B_OK) 454234353Sdim return defaultValue; 455234353Sdim return value; 456234353Sdim} 457234353Sdim 458234353Sdim 459234353Sdimdouble 460234353SdimSettingsMessage::GetValue(const char* name, double defaultValue) const 461234353Sdim{ 462249423Sdim double value; 463234353Sdim if (FindDouble(name, &value) != B_OK) 464249423Sdim return defaultValue; 465234982Sdim return value; 466234982Sdim} 467234982Sdim 468249423Sdim 469249423SdimBString 470249423SdimSettingsMessage::GetValue(const char* name, const BString& defaultValue) const 471249423Sdim{ 472234353Sdim BString value; 473263508Sdim if (FindString(name, &value) != B_OK) 474249423Sdim return defaultValue; 475249423Sdim return value; 476249423Sdim} 477249423Sdim 478249423Sdim 479249423Sdimconst char* 480249423SdimSettingsMessage::GetValue(const char* name, const char* defaultValue) const 481249423Sdim{ 482249423Sdim const char* value; 483249423Sdim if (FindString(name, &value) != B_OK) 484249423Sdim return defaultValue; 485249423Sdim return value; 486249423Sdim} 487249423Sdim 488249423Sdim 489249423SdimBPoint 490249423SdimSettingsMessage::GetValue(const char *name, BPoint defaultValue) const 491249423Sdim{ 492249423Sdim BPoint value; 493234353Sdim if (FindPoint(name, &value) != B_OK) 494195340Sed return defaultValue; 495 return value; 496} 497 498 499BRect 500SettingsMessage::GetValue(const char* name, BRect defaultValue) const 501{ 502 BRect value; 503 if (FindRect(name, &value) != B_OK) 504 return defaultValue; 505 return value; 506} 507 508 509entry_ref 510SettingsMessage::GetValue(const char* name, const entry_ref& defaultValue) const 511{ 512 entry_ref value; 513 if (FindRef(name, &value) != B_OK) 514 return defaultValue; 515 return value; 516} 517 518 519BMessage 520SettingsMessage::GetValue(const char* name, const BMessage& defaultValue) const 521{ 522 BMessage value; 523 if (FindMessage(name, &value) != B_OK) 524 return defaultValue; 525 return value; 526} 527 528 529BFont 530SettingsMessage::GetValue(const char* name, const BFont& defaultValue) const 531{ 532 BMessage fontMessage; 533 if (FindMessage(name, &fontMessage) != B_OK) 534 return defaultValue; 535 536 const char* family; 537 const char* style; 538 float size; 539 if (fontMessage.FindString("family", &family) != B_OK 540 || fontMessage.FindString("style", &style) != B_OK 541 || fontMessage.FindFloat("size", &size) != B_OK) { 542 return defaultValue; 543 } 544 545 BFont value; 546 if (value.SetFamilyAndStyle(family, style) != B_OK) 547 return defaultValue; 548 549 value.SetSize(size); 550 551 return value; 552} 553 554 555void* 556SettingsMessage::GetValue(const char* name, type_code type, ssize_t numBytes, 557 const void** defaultValue) const 558{ 559 void* value; 560 if (FindData(name, type, (const void**)&value, &numBytes) != B_OK) 561 return defaultValue; 562 return value; 563} 564 565 566// #pragma mark - private 567 568void 569SettingsMessage::_NotifyValueChanged(const char* name) const 570{ 571 BMessage message(SETTINGS_VALUE_CHANGED); 572 message.AddString("name", name); 573 574 // Add the value of that name to the notification. 575 type_code type; 576 if (GetInfo(name, &type) == B_OK) { 577 const void* data; 578 ssize_t numBytes; 579 if (FindData(name, type, &data, &numBytes) == B_OK) 580 message.AddData("value", type, data, numBytes); 581 } 582 583 int32 count = fListeners.CountItems(); 584 for (int32 i = 0; i < count; i++) { 585 BMessenger* listener = reinterpret_cast<BMessenger*>( 586 fListeners.ItemAtFast(i)); 587 listener->SendMessage(&message); 588 } 589} 590