diff --git a/modules/libpref/public/Preferences.h b/modules/libpref/public/Preferences.h index 288e077b3bd3..cfada7ff4821 100644 --- a/modules/libpref/public/Preferences.h +++ b/modules/libpref/public/Preferences.h @@ -52,6 +52,8 @@ #include "nsWeakReference.h" class nsIFile; +class nsCString; +class nsString; namespace mozilla { @@ -73,7 +75,96 @@ public: virtual ~Preferences(); nsresult Init(); - + + /** + * Returns the singleton instance which is addreffed. + */ + static Preferences* GetInstance(); + + /** + * Finallizes global members. + */ + static void Shutdown(); + + /** + * Returns shared pref service instance + * NOTE: not addreffed. + */ + static nsIPrefService* GetService() { return sPreferences; } + + /** + * Returns shared pref branch instance. + * NOTE: not addreffed. + */ + static nsIPrefBranch2* GetRootBranch() + { + return sPreferences ? sPreferences->mRootBranch.get() : nsnull; + } + + /** + * Gets int or bool type pref value with default value if failed to get + * the pref. + */ + static PRBool GetBool(const char* aPref, PRBool aDefault = PR_FALSE) + { + PRBool result = aDefault; + GetBool(aPref, &result); + return result; + } + + static PRInt32 GetInt(const char* aPref, PRInt32 aDefault = 0) + { + PRInt32 result = aDefault; + GetInt(aPref, &result); + return result; + } + + /** + * Gets int or bool type pref value with raw return value of nsIPrefBranch. + * + * @param aPref A pref name. + * @param aResult Must not be NULL. The value is never modified when + * these methods fail. + */ + static nsresult GetBool(const char* aPref, PRBool* aResult); + static nsresult GetInt(const char* aPref, PRInt32* aResult); + + /** + * Gets string type pref value with raw return value of nsIPrefBranch. + * + * @param aPref A pref name. + * @param aResult Must not be NULL. The value is never modified when + * these methods fail. + */ + static nsresult GetChar(const char* aPref, nsCString* aResult); + static nsresult GetChar(const char* aPref, nsString* aResult); + static nsresult GetLocalizedString(const char* aPref, nsString* aResult); + + /** + * Sets various type pref values. + */ + static nsresult SetBool(const char* aPref, PRBool aValue); + static nsresult SetInt(const char* aPref, PRInt32 aValue); + static nsresult SetChar(const char* aPref, const char* aValue); + static nsresult SetChar(const char* aPref, const nsCString &aValue); + static nsresult SetChar(const char* aPref, const PRUnichar* aValue); + static nsresult SetChar(const char* aPref, const nsString &aValue); + + /** + * Clears user set pref. + */ + static nsresult ClearUser(const char* aPref); + + /** + * Adds/Removes the observer for the root pref branch. + * The observer is referenced strongly if AddStrongObserver is used. On the + * other hand, it is referenced weakly, if AddWeakObserver is used. + * See nsIPrefBran2.idl for the detail. + */ + static nsresult AddStrongObserver(nsIObserver* aObserver, const char* aPref); + static nsresult AddWeakObserver(nsIObserver* aObserver, const char* aPref); + static nsresult RemoveObserver(nsIObserver* aObserver, const char* aPref); + protected: nsresult NotifyServiceObservers(const char *aSubject); nsresult UseDefaultPrefFile(); @@ -87,6 +178,14 @@ protected: private: nsCOMPtr mRootBranch; nsCOMPtr mCurrentFile; + + static Preferences* sPreferences; + static PRBool sShutdown; + + /** + * Init static members. TRUE if it succeeded. Otherwise, FALSE. + */ + static PRBool InitStaticMembers(); }; } // namespace mozilla diff --git a/modules/libpref/src/Preferences.cpp b/modules/libpref/src/Preferences.cpp index 640e76bd831b..10167fdd0998 100644 --- a/modules/libpref/src/Preferences.cpp +++ b/modules/libpref/src/Preferences.cpp @@ -84,6 +84,49 @@ static nsresult openPrefFile(nsIFile* aFile); static nsresult pref_InitInitialObjects(void); static nsresult pref_LoadPrefsInDirList(const char *listId); +Preferences* Preferences::sPreferences = nsnull; +PRBool Preferences::sShutdown = PR_FALSE; + +// static +Preferences* +Preferences::GetInstance() +{ + NS_ENSURE_TRUE(!sShutdown, nsnull); + + if (sPreferences) { + NS_ADDREF(sPreferences); + return sPreferences; + } + + InitStaticMembers(); + NS_IF_ADDREF(sPreferences); + return sPreferences; +} + +// static +PRBool +Preferences::InitStaticMembers() +{ + if (sShutdown || sPreferences) { + return sPreferences != nsnull; + } + + sPreferences = new Preferences(); + NS_ADDREF(sPreferences); + if (NS_FAILED(sPreferences->Init()) || !sPreferences->mRootBranch) { + NS_RELEASE(sPreferences); + } + return sPreferences != nsnull; +} + +// static +void +Preferences::Shutdown() +{ + sShutdown = PR_TRUE; // Don't create the singleton instance after here. + NS_IF_RELEASE(sPreferences); +} + //----------------------------------------------------------------------------- /* @@ -951,4 +994,161 @@ static nsresult pref_InitInitialObjects() return pref_LoadPrefsInDirList(NS_EXT_PREFS_DEFAULTS_DIR_LIST); } + +/****************************************************************************** + * + * static utilities + * + ******************************************************************************/ + +// static +nsresult +Preferences::GetBool(const char* aPref, PRBool* aResult) +{ + NS_PRECONDITION(aResult, "aResult must not be NULL"); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return sPreferences->mRootBranch->GetBoolPref(aPref, aResult); +} + +// static +nsresult +Preferences::GetInt(const char* aPref, PRInt32* aResult) +{ + NS_PRECONDITION(aResult, "aResult must not be NULL"); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return sPreferences->mRootBranch->GetIntPref(aPref, aResult); +} + +// static +nsresult +Preferences::GetChar(const char* aPref, nsCString* aResult) +{ + NS_PRECONDITION(aResult, "aResult must not be NULL"); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + nsAdoptingCString result; + nsresult rv = + sPreferences->mRootBranch->GetCharPref(aPref, getter_Copies(result)); + if (NS_SUCCEEDED(rv)) { + *aResult = result; + } + return rv; +} + +// static +nsresult +Preferences::GetChar(const char* aPref, nsString* aResult) +{ + NS_PRECONDITION(aResult, "aResult must not be NULL"); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + nsAdoptingCString result; + nsresult rv = + sPreferences->mRootBranch->GetCharPref(aPref, getter_Copies(result)); + if (NS_SUCCEEDED(rv)) { + CopyUTF8toUTF16(result, *aResult); + } + return rv; +} + +// static +nsresult +Preferences::GetLocalizedString(const char* aPref, nsString* aResult) +{ + NS_PRECONDITION(aResult, "aResult must not be NULL"); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + nsCOMPtr prefLocalString; + nsresult rv = sPreferences->mRootBranch->GetComplexValue(aPref, + NS_GET_IID(nsIPrefLocalizedString), + getter_AddRefs(prefLocalString)); + if (NS_SUCCEEDED(rv)) { + if (prefLocalString) { + prefLocalString->GetData(getter_Copies(*aResult)); + } else { + aResult->Truncate(); + } + } + return rv; +} + +// static +nsresult +Preferences::SetChar(const char* aPref, const char* aValue) +{ + NS_ENSURE_TRUE(InitStaticMembers(), PR_FALSE); + return sPreferences->mRootBranch->SetCharPref(aPref, aValue); +} + +// static +nsresult +Preferences::SetChar(const char* aPref, const nsCString &aValue) +{ + return SetChar(aPref, nsPromiseFlatCString(aValue).get()); +} + +// static +nsresult +Preferences::SetChar(const char* aPref, const PRUnichar* aValue) +{ + NS_ConvertUTF16toUTF8 utf8(aValue); + return SetChar(aPref, utf8.get()); +} + +// static +nsresult +Preferences::SetChar(const char* aPref, const nsString &aValue) +{ + NS_ConvertUTF16toUTF8 utf8(aValue); + return SetChar(aPref, utf8.get()); +} + +// static +nsresult +Preferences::SetBool(const char* aPref, PRBool aValue) +{ + NS_ENSURE_TRUE(InitStaticMembers(), PR_FALSE); + return sPreferences->mRootBranch->SetBoolPref(aPref, aValue); +} + +// static +nsresult +Preferences::SetInt(const char* aPref, PRInt32 aValue) +{ + NS_ENSURE_TRUE(InitStaticMembers(), PR_FALSE); + return sPreferences->mRootBranch->SetIntPref(aPref, aValue); +} + +// static +nsresult +Preferences::ClearUser(const char* aPref) +{ + NS_ENSURE_TRUE(InitStaticMembers(), PR_FALSE); + return sPreferences->mRootBranch->ClearUserPref(aPref); +} + +// static +nsresult +Preferences::AddStrongObserver(nsIObserver* aObserver, + const char* aPref) +{ + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return sPreferences->mRootBranch->AddObserver(aPref, aObserver, PR_FALSE); +} + +// static +nsresult +Preferences::AddWeakObserver(nsIObserver* aObserver, + const char* aPref) +{ + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return sPreferences->mRootBranch->AddObserver(aPref, aObserver, PR_TRUE); +} + +// static +nsresult +Preferences::RemoveObserver(nsIObserver* aObserver, + const char* aPref) +{ + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return sPreferences->mRootBranch->RemoveObserver(aPref, aObserver); +} + } // namespace mozilla diff --git a/modules/libpref/src/nsPrefsFactory.cpp b/modules/libpref/src/nsPrefsFactory.cpp index d61e0cc80c17..0f29fbb5232d 100644 --- a/modules/libpref/src/nsPrefsFactory.cpp +++ b/modules/libpref/src/nsPrefsFactory.cpp @@ -43,7 +43,7 @@ using namespace mozilla; -NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(Preferences, Init) +NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(Preferences, Preferences::GetInstance) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrefLocalizedString, Init) NS_GENERIC_FACTORY_CONSTRUCTOR(nsRelativeFilePref) @@ -70,6 +70,7 @@ static mozilla::Module::ContractIDEntry kPrefContracts[] = { static void UnloadPrefsModule() { + Preferences::Shutdown(); PREF_Cleanup(); }