Added support for attaching listeners to the SettingsMessage, to be notified

when a named value changes.

git-svn-id: http://svn.haiku-os.org/webpositive/webkit/trunk@338 94f232f2-1747-11df-bad5-a5bfde151594
This commit is contained in:
stippi 2010-03-22 18:04:31 +00:00 committed by Alexandre Deckner
parent 9ccfda9c50
commit 0ba16dd4c1
2 changed files with 161 additions and 45 deletions

View File

@ -9,14 +9,19 @@
#include "SettingsMessage.h" #include "SettingsMessage.h"
#include <new>
#include <Entry.h> #include <Entry.h>
#include <File.h> #include <File.h>
#include <Messenger.h>
#include <String.h> #include <String.h>
SettingsMessage::SettingsMessage(directory_which directory, SettingsMessage::SettingsMessage(directory_which directory,
const char* filename) const char* filename)
: BMessage('pref') :
BMessage('pref'),
fListeners(4)
{ {
fStatus = find_directory(directory, &fPath); fStatus = find_directory(directory, &fPath);
@ -31,6 +36,9 @@ SettingsMessage::SettingsMessage(directory_which directory,
SettingsMessage::~SettingsMessage() SettingsMessage::~SettingsMessage()
{ {
Save(); Save();
for (int32 i = fListeners.CountItems() - 1; i >= 0; i--)
delete reinterpret_cast<BMessenger*>(fListeners.ItemAtFast(i));
} }
@ -67,139 +75,212 @@ SettingsMessage::Save() const
} }
bool
SettingsMessage::AddListener(const BMessenger& listener)
{
BMessenger* listenerCopy = new(std::nothrow) BMessenger(listener);
if (listenerCopy && fListeners.AddItem(listenerCopy))
return true;
delete listenerCopy;
return false;
}
void
SettingsMessage::RemoveListener(const BMessenger& listener)
{
for (int32 i = fListeners.CountItems() - 1; i >= 0; i--) {
BMessenger* listenerItem = reinterpret_cast<BMessenger*>(
fListeners.ItemAtFast(i));
if (*listenerItem == listener) {
fListeners.RemoveItem(i);
delete listenerItem;
return;
}
}
}
// #pragma mark - // #pragma mark -
status_t status_t
SettingsMessage::SetValue(const char* name, bool value) SettingsMessage::SetValue(const char* name, bool value)
{ {
if (ReplaceBool(name, value) == B_OK) status_t ret = ReplaceBool(name, value);
return B_OK; if (ret != B_OK)
return AddBool(name, value); ret = AddBool(name, value);
if (ret == B_OK)
_NotifyValueChanged(name);
return ret;
} }
status_t status_t
SettingsMessage::SetValue(const char* name, int8 value) SettingsMessage::SetValue(const char* name, int8 value)
{ {
if (ReplaceInt8(name, value) == B_OK) status_t ret = ReplaceInt8(name, value);
return B_OK; if (ret != B_OK)
return AddInt8(name, value); ret = AddInt8(name, value);
if (ret == B_OK)
_NotifyValueChanged(name);
return ret;
} }
status_t status_t
SettingsMessage::SetValue(const char* name, int16 value) SettingsMessage::SetValue(const char* name, int16 value)
{ {
if (ReplaceInt16(name, value) == B_OK) status_t ret = ReplaceInt16(name, value);
return B_OK; if (ret != B_OK)
return AddInt16(name, value); ret = AddInt16(name, value);
if (ret == B_OK)
_NotifyValueChanged(name);
return ret;
} }
status_t status_t
SettingsMessage::SetValue(const char* name, int32 value) SettingsMessage::SetValue(const char* name, int32 value)
{ {
if (ReplaceInt32(name, value) == B_OK) status_t ret = ReplaceInt32(name, value);
return B_OK; if (ret != B_OK)
return AddInt32(name, value); ret = AddInt32(name, value);
if (ret == B_OK)
_NotifyValueChanged(name);
return ret;
} }
status_t status_t
SettingsMessage::SetValue(const char* name, uint32 value) SettingsMessage::SetValue(const char* name, uint32 value)
{ {
if (ReplaceInt32(name, (int32)value) == B_OK) status_t ret = ReplaceUInt32(name, value);
return B_OK; if (ret != B_OK)
return AddInt32(name, (int32)value); ret = AddUInt32(name, value);
if (ret == B_OK)
_NotifyValueChanged(name);
return ret;
} }
status_t status_t
SettingsMessage::SetValue(const char* name, int64 value) SettingsMessage::SetValue(const char* name, int64 value)
{ {
if (ReplaceInt64(name, value) == B_OK) status_t ret = ReplaceInt64(name, value);
return B_OK; if (ret != B_OK)
return AddInt64(name, value); ret = AddInt64(name, value);
if (ret == B_OK)
_NotifyValueChanged(name);
return ret;
} }
status_t status_t
SettingsMessage::SetValue(const char* name, float value) SettingsMessage::SetValue(const char* name, float value)
{ {
if (ReplaceFloat(name, value) == B_OK) status_t ret = ReplaceFloat(name, value);
return B_OK; if (ret != B_OK)
return AddFloat(name, value); ret = AddFloat(name, value);
if (ret == B_OK)
_NotifyValueChanged(name);
return ret;
} }
status_t status_t
SettingsMessage::SetValue(const char* name, double value) SettingsMessage::SetValue(const char* name, double value)
{ {
if (ReplaceDouble(name, value) == B_OK) status_t ret = ReplaceDouble(name, value);
return B_OK; if (ret != B_OK)
return AddDouble(name, value); ret = AddDouble(name, value);
if (ret == B_OK)
_NotifyValueChanged(name);
return ret;
} }
status_t status_t
SettingsMessage::SetValue(const char* name, const char* value) SettingsMessage::SetValue(const char* name, const char* value)
{ {
if (ReplaceString(name, value) == B_OK) status_t ret = ReplaceString(name, value);
return B_OK; if (ret != B_OK)
return AddString(name, value); ret = AddString(name, value);
if (ret == B_OK)
_NotifyValueChanged(name);
return ret;
} }
status_t status_t
SettingsMessage::SetValue(const char* name, const BString& value) SettingsMessage::SetValue(const char* name, const BString& value)
{ {
return SetValue(name, value.String()); status_t ret = ReplaceString(name, value);
if (ret != B_OK)
ret = AddString(name, value);
if (ret == B_OK)
_NotifyValueChanged(name);
return ret;
} }
status_t status_t
SettingsMessage::SetValue(const char* name, const BPoint& value) SettingsMessage::SetValue(const char* name, const BPoint& value)
{ {
if (ReplacePoint(name, value) == B_OK) status_t ret = ReplacePoint(name, value);
return B_OK; if (ret != B_OK)
return AddPoint(name, value); ret = AddPoint(name, value);
if (ret == B_OK)
_NotifyValueChanged(name);
return ret;
} }
status_t status_t
SettingsMessage::SetValue(const char* name, const BRect& value) SettingsMessage::SetValue(const char* name, const BRect& value)
{ {
if (ReplaceRect(name, value) == B_OK) status_t ret = ReplaceRect(name, value);
return B_OK; if (ret != B_OK)
return AddRect(name, value); ret = AddRect(name, value);
if (ret == B_OK)
_NotifyValueChanged(name);
return ret;
} }
status_t status_t
SettingsMessage::SetValue(const char* name, const entry_ref& value) SettingsMessage::SetValue(const char* name, const entry_ref& value)
{ {
if (ReplaceRef(name, &value) == B_OK) status_t ret = ReplaceRef(name, &value);
return B_OK; if (ret != B_OK)
return AddRef(name, &value); ret = AddRef(name, &value);
if (ret == B_OK)
_NotifyValueChanged(name);
return ret;
} }
status_t status_t
SettingsMessage::SetValue(const char* name, const BMessage& value) SettingsMessage::SetValue(const char* name, const BMessage& value)
{ {
if (ReplaceMessage(name, &value) == B_OK) status_t ret = ReplaceMessage(name, &value);
return B_OK; if (ret != B_OK)
return AddMessage(name, &value); ret = AddMessage(name, &value);
if (ret == B_OK)
_NotifyValueChanged(name);
return ret;
} }
status_t status_t
SettingsMessage::SetValue(const char* name, const BFlattenable* value) SettingsMessage::SetValue(const char* name, const BFlattenable* value)
{ {
if (ReplaceFlat(name, const_cast<BFlattenable*>(value)) == B_OK) status_t ret = ReplaceFlat(name, const_cast<BFlattenable*>(value));
return B_OK; if (ret != B_OK)
return AddFlat(name, const_cast<BFlattenable*>(value)); ret = AddFlat(name, const_cast<BFlattenable*>(value));
if (ret == B_OK)
_NotifyValueChanged(name);
return ret;
} }
@ -221,6 +302,8 @@ SettingsMessage::SetValue(const char* name, const BFont& value)
if (ReplaceMessage(name, &fontMessage) != B_OK) if (ReplaceMessage(name, &fontMessage) != B_OK)
ret = AddMessage(name, &fontMessage); ret = AddMessage(name, &fontMessage);
} }
if (ret == B_OK)
_NotifyValueChanged(name);
return ret; return ret;
} }
@ -383,3 +466,20 @@ SettingsMessage::GetValue(const char* name, const BFont& defaultValue) const
return value; return value;
} }
// #pragma mark - private
void
SettingsMessage::_NotifyValueChanged(const char* name) const
{
BMessage message(MSG_SETTINGS_VALUE_CHANGED);
message.AddString("name", name);
int32 count = fListeners.CountItems();
for (int32 i = 0; i < count; i++) {
BMessenger* listener = reinterpret_cast<BMessenger*>(
fListeners.ItemAtFast(i));
listener->SendMessage(&message);
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2008 Stephan Aßmus <superstippi@gmx.de>. * Copyright 2008-2010 Stephan Aßmus <superstippi@gmx.de>.
* Copyright 1998 Eric Shepherd. * Copyright 1998 Eric Shepherd.
* All rights reserved. Distributed under the terms of the Be Sample Code * All rights reserved. Distributed under the terms of the Be Sample Code
* license. * license.
@ -7,13 +7,22 @@
#ifndef SETTINGS_MESSAGE_H #ifndef SETTINGS_MESSAGE_H
#define SETTINGS_MESSAGE_H #define SETTINGS_MESSAGE_H
#include <FindDirectory.h> #include <FindDirectory.h>
#include <Font.h> #include <Font.h>
#include <List.h>
#include <Message.h> #include <Message.h>
#include <Path.h> #include <Path.h>
class BMessenger;
class BString; class BString;
enum {
MSG_SETTINGS_VALUE_CHANGED = 'stvc'
};
class SettingsMessage : public BMessage { class SettingsMessage : public BMessage {
public: public:
SettingsMessage(directory_which directory, SettingsMessage(directory_which directory,
@ -25,6 +34,9 @@ public:
status_t Load(); status_t Load();
status_t Save() const; status_t Save() const;
bool AddListener(const BMessenger& listener);
void RemoveListener(const BMessenger& listener);
status_t SetValue(const char* name, bool value); status_t SetValue(const char* name, bool value);
status_t SetValue(const char* name, int8 value); status_t SetValue(const char* name, int8 value);
status_t SetValue(const char* name, int16 value); status_t SetValue(const char* name, int16 value);
@ -76,9 +88,13 @@ public:
BFont GetValue(const char* name, BFont GetValue(const char* name,
const BFont& defaultValue) const; const BFont& defaultValue) const;
private:
void _NotifyValueChanged(const char* name) const;
private: private:
BPath fPath; BPath fPath;
status_t fStatus; status_t fStatus;
BList fListeners;
}; };
#endif // SETTINGS_MESSAGE_H #endif // SETTINGS_MESSAGE_H