зеркало из https://github.com/mozilla/gecko-dev.git
bug 246085 nsCategoryManager should notify observers when items are added/removed from categories
r=dougt sr=darin a=asa
This commit is contained in:
Родитель
b54ef566d9
Коммит
98a9a84fcb
|
@ -308,6 +308,37 @@ NS_Free(void* ptr);
|
||||||
*/
|
*/
|
||||||
#define NS_XPCOM_SHUTDOWN_OBSERVER_ID "xpcom-shutdown"
|
#define NS_XPCOM_SHUTDOWN_OBSERVER_ID "xpcom-shutdown"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This topic is notified when an entry was added to a category in the
|
||||||
|
* category manager. The subject of the notification will be the name of
|
||||||
|
* the added entry as an nsISupportsCString, and the data will be the
|
||||||
|
* name of the category.
|
||||||
|
*
|
||||||
|
* @status FROZEN
|
||||||
|
*/
|
||||||
|
#define NS_XPCOM_CATEGORY_ENTRY_ADDED_OBSERVER_ID \
|
||||||
|
"xpcom-category-entry-added"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This topic is notified when an entry was removed from a category in the
|
||||||
|
* category manager. The subject of the notification will be the name of
|
||||||
|
* the removed entry as an nsISupportsCString, and the data will be the
|
||||||
|
* name of the category.
|
||||||
|
*
|
||||||
|
* @status FROZEN
|
||||||
|
*/
|
||||||
|
#define NS_XPCOM_CATEGORY_ENTRY_REMOVED_OBSERVER_ID \
|
||||||
|
"xpcom-category-entry-removed"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This topic is notified when an a category was cleared in the category
|
||||||
|
* manager. The subject of the notification will be the category manager,
|
||||||
|
* and the data will be the name of the cleared category.
|
||||||
|
*
|
||||||
|
* @status FROZEN
|
||||||
|
*/
|
||||||
|
#define NS_XPCOM_CATEGORY_CLEARED_OBSERVER_ID "xpcom-category-cleared"
|
||||||
|
|
||||||
extern "C" NS_COM nsresult
|
extern "C" NS_COM nsresult
|
||||||
NS_GetDebug(nsIDebug* *result);
|
NS_GetDebug(nsIDebug* *result);
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include "nsSupportsPrimitives.h"
|
#include "nsSupportsPrimitives.h"
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
|
#include "nsIObserverService.h"
|
||||||
#include "nsReadableUtils.h"
|
#include "nsReadableUtils.h"
|
||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
#include "nsQuickSort.h"
|
#include "nsQuickSort.h"
|
||||||
|
@ -517,6 +518,39 @@ nsCategoryManager::get_category(const char* aName) {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsCategoryManager::NotifyObservers( const char *aTopic,
|
||||||
|
const char *aCategoryName,
|
||||||
|
const char *aEntryName )
|
||||||
|
{
|
||||||
|
if (mSuppressNotifications)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIObserverService> observerService
|
||||||
|
(do_GetService("@mozilla.org/observer-service;1"));
|
||||||
|
if (!observerService)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (aEntryName) {
|
||||||
|
nsCOMPtr<nsISupportsCString> entry
|
||||||
|
(do_CreateInstance (NS_SUPPORTS_CSTRING_CONTRACTID));
|
||||||
|
if (!entry)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nsresult rv = entry->SetData(nsDependentCString(aEntryName));
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return;
|
||||||
|
|
||||||
|
observerService->NotifyObservers
|
||||||
|
(entry, aTopic,
|
||||||
|
NS_ConvertUTF8toUTF16(aCategoryName).get());
|
||||||
|
} else {
|
||||||
|
observerService->NotifyObservers
|
||||||
|
(this, aTopic,
|
||||||
|
NS_ConvertUTF8toUTF16(aCategoryName).get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsCategoryManager::GetCategoryEntry( const char *aCategoryName,
|
nsCategoryManager::GetCategoryEntry( const char *aCategoryName,
|
||||||
const char *aEntryName,
|
const char *aEntryName,
|
||||||
|
@ -568,12 +602,19 @@ nsCategoryManager::AddCategoryEntry( const char *aCategoryName,
|
||||||
if (!category)
|
if (!category)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
return category->AddLeaf(aEntryName,
|
nsresult rv = category->AddLeaf(aEntryName,
|
||||||
aValue,
|
aValue,
|
||||||
aPersist,
|
aPersist,
|
||||||
aReplace,
|
aReplace,
|
||||||
_retval,
|
_retval,
|
||||||
&mArena);
|
&mArena);
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
NotifyObservers(NS_XPCOM_CATEGORY_ENTRY_ADDED_OBSERVER_ID,
|
||||||
|
aCategoryName, aEntryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -597,8 +638,15 @@ nsCategoryManager::DeleteCategoryEntry( const char *aCategoryName,
|
||||||
if (!category)
|
if (!category)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
return category->DeleteLeaf(aEntryName,
|
nsresult rv = category->DeleteLeaf(aEntryName,
|
||||||
aDontPersist);
|
aDontPersist);
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
NotifyObservers(NS_XPCOM_CATEGORY_ENTRY_REMOVED_OBSERVER_ID,
|
||||||
|
aCategoryName, aEntryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -614,8 +662,11 @@ nsCategoryManager::DeleteCategory( const char *aCategoryName )
|
||||||
CategoryNode* category = get_category(aCategoryName);
|
CategoryNode* category = get_category(aCategoryName);
|
||||||
PR_Unlock(mLock);
|
PR_Unlock(mLock);
|
||||||
|
|
||||||
if (category)
|
if (category) {
|
||||||
category->Clear();
|
category->Clear();
|
||||||
|
NotifyObservers(NS_XPCOM_CATEGORY_CLEARED_OBSERVER_ID,
|
||||||
|
aCategoryName, nsnull);
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -694,6 +745,13 @@ nsCategoryManager::WriteCategoryManagerToRegistry(PRFileDesc* fd)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_METHOD
|
||||||
|
nsCategoryManager::SuppressNotifications(PRBool aSuppress)
|
||||||
|
{
|
||||||
|
mSuppressNotifications = aSuppress;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
class nsCategoryManagerFactory : public nsIFactory
|
class nsCategoryManagerFactory : public nsIFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -142,6 +142,13 @@ public:
|
||||||
*/
|
*/
|
||||||
NS_METHOD WriteCategoryManagerToRegistry(PRFileDesc* fd);
|
NS_METHOD WriteCategoryManagerToRegistry(PRFileDesc* fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suppress or unsuppress notifications of category changes to the
|
||||||
|
* observer service. This is to be used by nsComponentManagerImpl
|
||||||
|
* on startup while reading the stored category list.
|
||||||
|
*/
|
||||||
|
NS_METHOD SuppressNotifications(PRBool aSuppress);
|
||||||
|
|
||||||
nsCategoryManager() { }
|
nsCategoryManager() { }
|
||||||
private:
|
private:
|
||||||
friend class nsCategoryManagerFactory;
|
friend class nsCategoryManagerFactory;
|
||||||
|
@ -150,10 +157,14 @@ private:
|
||||||
~nsCategoryManager();
|
~nsCategoryManager();
|
||||||
|
|
||||||
CategoryNode* get_category(const char* aName);
|
CategoryNode* get_category(const char* aName);
|
||||||
|
void NotifyObservers(const char* aTopic,
|
||||||
|
const char* aCategoryName,
|
||||||
|
const char* aEntryName);
|
||||||
|
|
||||||
PLArenaPool mArena;
|
PLArenaPool mArena;
|
||||||
nsClassHashtable<nsDepCharHashKey, CategoryNode> mTable;
|
nsClassHashtable<nsDepCharHashKey, CategoryNode> mTable;
|
||||||
PRLock* mLock;
|
PRLock* mLock;
|
||||||
|
PRBool mSuppressNotifications;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1295,6 +1295,8 @@ nsComponentManagerImpl::ReadPersistentRegistry()
|
||||||
if (ReadSectionHeader(reader, "CATEGORIES"))
|
if (ReadSectionHeader(reader, "CATEGORIES"))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
mCategoryManager->SuppressNotifications(PR_TRUE);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (!reader.NextLine())
|
if (!reader.NextLine())
|
||||||
|
@ -1312,6 +1314,8 @@ nsComponentManagerImpl::ReadPersistentRegistry()
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mCategoryManager->SuppressNotifications(PR_FALSE);
|
||||||
|
|
||||||
mRegistryDirty = PR_FALSE;
|
mRegistryDirty = PR_FALSE;
|
||||||
out:
|
out:
|
||||||
if (fd)
|
if (fd)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче