11541Srgrimes/* 21541Srgrimes * Copyright 2008-2010, Stephan A��mus <superstippi@gmx.de>. 31541Srgrimes * Copyright 1998, Eric Shepherd. 41541Srgrimes * All rights reserved. Distributed under the terms of the Be Sample Code 51541Srgrimes * license. 61541Srgrimes */ 71541Srgrimes 81541Srgrimes//! Be Newsletter Volume II, Issue 35; September 2, 1998 (Eric Shepherd) 91541Srgrimes 101541Srgrimes#include "SettingsMessage.h" 111541Srgrimes 121541Srgrimes#include <new> 131541Srgrimes 141541Srgrimes#include <Autolock.h> 151541Srgrimes#include <Entry.h> 161541Srgrimes#include <File.h> 171541Srgrimes#include <Messenger.h> 181541Srgrimes#include <String.h> 191541Srgrimes 201541Srgrimes 211541SrgrimesSettingsMessage::SettingsMessage(directory_which directory, 221541Srgrimes const char* filename) 231541Srgrimes : 241541Srgrimes BMessage('pref'), 251541Srgrimes fListeners(0) 261541Srgrimes{ 271541Srgrimes fStatus = find_directory(directory, &fPath); 281541Srgrimes 291541Srgrimes if (fStatus == B_OK) 301541Srgrimes fStatus = fPath.Append(filename); 311541Srgrimes 321541Srgrimes if (fStatus == B_OK) 331541Srgrimes fStatus = Load(); 341541Srgrimes} 351541Srgrimes 361541Srgrimes 371541SrgrimesSettingsMessage::~SettingsMessage() 3850477Speter{ 391541Srgrimes Save(); 401541Srgrimes 411541Srgrimes for (int32 i = fListeners.CountItems() - 1; i >= 0; i--) 421541Srgrimes delete reinterpret_cast<BMessenger*>(fListeners.ItemAtFast(i)); 431541Srgrimes} 441541Srgrimes 451541Srgrimes 461541Srgrimesstatus_t 471541SrgrimesSettingsMessage::InitCheck() const 481541Srgrimes{ 491541Srgrimes return fStatus; 501541Srgrimes} 511541Srgrimes 521541Srgrimes 531541Srgrimesstatus_t 541541SrgrimesSettingsMessage::Load() 551541Srgrimes{ 561541Srgrimes BAutolock _(this); 5715311Sbde 581541Srgrimes BFile file(fPath.Path(), B_READ_ONLY); 591541Srgrimes status_t status = file.InitCheck(); 601541Srgrimes 611541Srgrimes if (status == B_OK) 621541Srgrimes status = Unflatten(&file); 631541Srgrimes 641541Srgrimes return status; 651541Srgrimes} 661541Srgrimes 671541Srgrimes 681541Srgrimesstatus_t 691541SrgrimesSettingsMessage::Save() const 701541Srgrimes{ 711541Srgrimes BAutolock _(const_cast<SettingsMessage*>(this)); 721541Srgrimes 731541Srgrimes BFile file(fPath.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); 741541Srgrimes status_t status = file.InitCheck(); 751541Srgrimes 761541Srgrimes if (status == B_OK) 771541Srgrimes status = Flatten(&file); 781541Srgrimes 791541Srgrimes return status; 801541Srgrimes} 811541Srgrimes 821541Srgrimes 831541Srgrimesbool 841541SrgrimesSettingsMessage::AddListener(const BMessenger& listener) 851541Srgrimes{ 861541Srgrimes BAutolock _(this); 871541Srgrimes 881541Srgrimes BMessenger* listenerCopy = new(std::nothrow) BMessenger(listener); 891541Srgrimes if (listenerCopy && fListeners.AddItem(listenerCopy)) 901541Srgrimes return true; 911541Srgrimes delete listenerCopy; 921541Srgrimes return false; 931541Srgrimes} 941541Srgrimes 951541Srgrimes 961541Srgrimesvoid 971541SrgrimesSettingsMessage::RemoveListener(const BMessenger& listener) 981541Srgrimes{ 991541Srgrimes BAutolock _(this); 10013030Sbde 10113030Sbde for (int32 i = fListeners.CountItems() - 1; i >= 0; i--) { 10213030Sbde BMessenger* listenerItem = reinterpret_cast<BMessenger*>( 10313030Sbde fListeners.ItemAtFast(i)); 10413030Sbde if (*listenerItem == listener) { 10569727Sphk fListeners.RemoveItem(i); 1061541Srgrimes delete listenerItem; 1071541Srgrimes return; 1081541Srgrimes } 1091541Srgrimes } 1101541Srgrimes} 1111541Srgrimes 1121541Srgrimes 1131541Srgrimes// #pragma mark - 1141541Srgrimes 1151541Srgrimes 1161541Srgrimesstatus_t 1171541SrgrimesSettingsMessage::SetValue(const char* name, bool value) 118{ 119 status_t ret = ReplaceBool(name, value); 120 if (ret != B_OK) 121 ret = AddBool(name, value); 122 if (ret == B_OK) 123 _NotifyValueChanged(name); 124 return ret; 125} 126 127 128status_t 129SettingsMessage::SetValue(const char* name, int8 value) 130{ 131 status_t ret = ReplaceInt8(name, value); 132 if (ret != B_OK) 133 ret = AddInt8(name, value); 134 if (ret == B_OK) 135 _NotifyValueChanged(name); 136 return ret; 137} 138 139 140status_t 141SettingsMessage::SetValue(const char* name, int16 value) 142{ 143 status_t ret = ReplaceInt16(name, value); 144 if (ret != B_OK) 145 ret = AddInt16(name, value); 146 if (ret == B_OK) 147 _NotifyValueChanged(name); 148 return ret; 149} 150 151 152status_t 153SettingsMessage::SetValue(const char* name, uint16 value) 154{ 155 status_t ret = ReplaceUInt16(name, value); 156 if (ret != B_OK) 157 ret = AddUInt16(name, value); 158 if (ret == B_OK) 159 _NotifyValueChanged(name); 160 return ret; 161} 162 163 164status_t 165SettingsMessage::SetValue(const char* name, int32 value) 166{ 167 status_t ret = ReplaceInt32(name, value); 168 if (ret != B_OK) 169 ret = AddInt32(name, value); 170 if (ret == B_OK) 171 _NotifyValueChanged(name); 172 return ret; 173} 174 175 176status_t 177SettingsMessage::SetValue(const char* name, uint32 value) 178{ 179 status_t ret = ReplaceUInt32(name, value); 180 if (ret != B_OK) 181 ret = AddUInt32(name, value); 182 if (ret == B_BAD_TYPE && HasData(name, B_INT32_TYPE)) { 183 // For compatibility with older versions of this class, replace an int32 184 RemoveData(name); 185 ret = AddUInt32(name, value); 186 } 187 if (ret == B_OK) 188 _NotifyValueChanged(name); 189 return ret; 190} 191 192 193status_t 194SettingsMessage::SetValue(const char* name, int64 value) 195{ 196 status_t ret = ReplaceInt64(name, value); 197 if (ret != B_OK) 198 ret = AddInt64(name, value); 199 if (ret == B_OK) 200 _NotifyValueChanged(name); 201 return ret; 202} 203 204 205status_t 206SettingsMessage::SetValue(const char* name, uint64 value) 207{ 208 status_t ret = ReplaceUInt64(name, value); 209 if (ret != B_OK) 210 ret = AddUInt64(name, value); 211 if (ret == B_OK) 212 _NotifyValueChanged(name); 213 return ret; 214} 215 216 217status_t 218SettingsMessage::SetValue(const char* name, float value) 219{ 220 status_t ret = ReplaceFloat(name, value); 221 if (ret != B_OK) 222 ret = AddFloat(name, value); 223 if (ret == B_OK) 224 _NotifyValueChanged(name); 225 return ret; 226} 227 228 229status_t 230SettingsMessage::SetValue(const char* name, double value) 231{ 232 status_t ret = ReplaceDouble(name, value); 233 if (ret != B_OK) 234 ret = AddDouble(name, value); 235 if (ret == B_OK) 236 _NotifyValueChanged(name); 237 return ret; 238} 239 240 241status_t 242SettingsMessage::SetValue(const char* name, const char* value) 243{ 244 status_t ret = ReplaceString(name, value); 245 if (ret != B_OK) 246 ret = AddString(name, value); 247 if (ret == B_OK) 248 _NotifyValueChanged(name); 249 return ret; 250} 251 252 253status_t 254SettingsMessage::SetValue(const char* name, const BString& value) 255{ 256 status_t ret = ReplaceString(name, value); 257 if (ret != B_OK) 258 ret = AddString(name, value); 259 if (ret == B_OK) 260 _NotifyValueChanged(name); 261 return ret; 262} 263 264 265status_t 266SettingsMessage::SetValue(const char* name, const BPoint& value) 267{ 268 status_t ret = ReplacePoint(name, value); 269 if (ret != B_OK) 270 ret = AddPoint(name, value); 271 if (ret == B_OK) 272 _NotifyValueChanged(name); 273 return ret; 274} 275 276 277status_t 278SettingsMessage::SetValue(const char* name, const BRect& value) 279{ 280 status_t ret = ReplaceRect(name, value); 281 if (ret != B_OK) 282 ret = AddRect(name, value); 283 if (ret == B_OK) 284 _NotifyValueChanged(name); 285 return ret; 286} 287 288 289status_t 290SettingsMessage::SetValue(const char* name, const entry_ref& value) 291{ 292 status_t ret = ReplaceRef(name, &value); 293 if (ret != B_OK) 294 ret = AddRef(name, &value); 295 if (ret == B_OK) 296 _NotifyValueChanged(name); 297 return ret; 298} 299 300 301status_t 302SettingsMessage::SetValue(const char* name, const BMessage& value) 303{ 304 status_t ret = ReplaceMessage(name, &value); 305 if (ret != B_OK) 306 ret = AddMessage(name, &value); 307 if (ret == B_OK) 308 _NotifyValueChanged(name); 309 return ret; 310} 311 312 313status_t 314SettingsMessage::SetValue(const char* name, const BFlattenable* value) 315{ 316 status_t ret = ReplaceFlat(name, const_cast<BFlattenable*>(value)); 317 if (ret != B_OK) 318 ret = AddFlat(name, const_cast<BFlattenable*>(value)); 319 if (ret == B_OK) 320 _NotifyValueChanged(name); 321 return ret; 322} 323 324 325status_t 326SettingsMessage::SetValue(const char* name, type_code type, const void* data, 327 ssize_t numBytes) 328{ 329 status_t ret = ReplaceData(name, type, data, numBytes); 330 if (ret != B_OK) 331 ret = AddData(name, type, data, numBytes); 332 if (ret == B_OK) 333 _NotifyValueChanged(name); 334 return ret; 335} 336 337 338status_t 339SettingsMessage::SetValue(const char* name, const BFont& value) 340{ 341 font_family family; 342 font_style style; 343 value.GetFamilyAndStyle(&family, &style); 344 345 BMessage fontMessage; 346 status_t ret = fontMessage.AddString("family", family); 347 if (ret == B_OK) 348 ret = fontMessage.AddString("style", style); 349 if (ret == B_OK) 350 ret = fontMessage.AddFloat("size", value.Size()); 351 352 if (ret == B_OK) { 353 if (ReplaceMessage(name, &fontMessage) != B_OK) 354 ret = AddMessage(name, &fontMessage); 355 } 356 if (ret == B_OK) 357 _NotifyValueChanged(name); 358 return ret; 359} 360 361 362// #pragma mark - 363 364 365bool 366SettingsMessage::GetValue(const char* name, bool defaultValue) const 367{ 368 bool value; 369 if (FindBool(name, &value) != B_OK) 370 return defaultValue; 371 return value; 372} 373 374 375int8 376SettingsMessage::GetValue(const char* name, int8 defaultValue) const 377{ 378 int8 value; 379 if (FindInt8(name, &value) != B_OK) 380 return defaultValue; 381 return value; 382} 383 384 385int16 386SettingsMessage::GetValue(const char* name, int16 defaultValue) const 387{ 388 int16 value; 389 if (FindInt16(name, &value) != B_OK) 390 return defaultValue; 391 return value; 392} 393 394 395uint16 396SettingsMessage::GetValue(const char* name, uint16 defaultValue) const 397{ 398 uint16 value; 399 if (FindUInt16(name, &value) != B_OK) 400 return defaultValue; 401 return value; 402} 403 404 405int32 406SettingsMessage::GetValue(const char* name, int32 defaultValue) const 407{ 408 int32 value; 409 if (FindInt32(name, &value) != B_OK) 410 return defaultValue; 411 return value; 412} 413 414 415uint32 416SettingsMessage::GetValue(const char* name, uint32 defaultValue) const 417{ 418 uint32 value; 419 if (FindUInt32(name, &value) == B_OK) 420 return value; 421 // For compatibility with older versions of this class, also accept an int32 422 int32 signedValue; 423 if (FindInt32(name, &signedValue) == B_OK && signedValue >= 0) 424 return signedValue; 425 return defaultValue; 426} 427 428 429int64 430SettingsMessage::GetValue(const char* name, int64 defaultValue) const 431{ 432 int64 value; 433 if (FindInt64(name, &value) != B_OK) 434 return defaultValue; 435 return value; 436} 437 438 439uint64 440SettingsMessage::GetValue(const char* name, uint64 defaultValue) const 441{ 442 uint64 value; 443 if (FindUInt64(name, &value) != B_OK) 444 return defaultValue; 445 return value; 446} 447 448 449float 450SettingsMessage::GetValue(const char* name, float defaultValue) const 451{ 452 float value; 453 if (FindFloat(name, &value) != B_OK) 454 return defaultValue; 455 return value; 456} 457 458 459double 460SettingsMessage::GetValue(const char* name, double defaultValue) const 461{ 462 double value; 463 if (FindDouble(name, &value) != B_OK) 464 return defaultValue; 465 return value; 466} 467 468 469BString 470SettingsMessage::GetValue(const char* name, const BString& defaultValue) const 471{ 472 BString value; 473 if (FindString(name, &value) != B_OK) 474 return defaultValue; 475 return value; 476} 477 478 479const char* 480SettingsMessage::GetValue(const char* name, const char* defaultValue) const 481{ 482 const char* value; 483 if (FindString(name, &value) != B_OK) 484 return defaultValue; 485 return value; 486} 487 488 489BPoint 490SettingsMessage::GetValue(const char *name, BPoint defaultValue) const 491{ 492 BPoint value; 493 if (FindPoint(name, &value) != B_OK) 494 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