diff --git a/xpfe/appshell/public/nsFileLocations.h b/xpfe/appshell/public/nsFileLocations.h index fa4c95e435c..ac03623702d 100644 --- a/xpfe/appshell/public/nsFileLocations.h +++ b/xpfe/appshell/public/nsFileLocations.h @@ -27,6 +27,7 @@ #include "nsFileSpec.h" #include "nsIFileLocator.h" +#include "nsIDirectoryService.h" #ifdef XP_MAC #include @@ -40,22 +41,53 @@ public: nsFileLocator(); NS_DECL_ISUPPORTS - + NS_IMETHOD GetFileLocation( PRUint32 aType, - // NOTE: actually either nsSpecialFileSpec:Type, see nsFileLocations.h - // or nsSpecialSystemDirectory::SystemDirectories, see nsSpecialSystemDirectory.h + // NOTE: actually either nsSpecialFileSpec:Type, see nsFileLocations.h + // or nsSpecialSystemDirectory::SystemDirectories, see nsSpecialSystemDirectory.h nsIFileSpec** outSpec); NS_IMETHOD ForgetProfileDir(); protected: + virtual ~nsFileLocator(); }; -// SEE ALSO: -// mozilla/base/public/nsSpecialSystemDirectory.h + + + +class nsFileLocationProvider : public nsIDirectoryServiceProvider +//============================================================================= +{ +public: + nsFileLocationProvider(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIDIRECTORYSERVICEPROVIDER + +protected: + virtual ~nsFileLocationProvider(); + +}; + + + +// +// +// +// +// +// Talk to dougt@netscape.com before adding any more locations to this file!! +// +// +// +// +// +// +// //======================================================================================== class NS_APPSHELL nsSpecialFileSpec : public nsFileSpec @@ -63,60 +95,60 @@ class NS_APPSHELL nsSpecialFileSpec : public nsFileSpec { public: - enum Type - { - // Use a big offset, so that values passed to nsIFileLocator can share the - // same range as the type nsSpecialSystemDirectory::SystemDirectories. - - // Who has not wished one could have inheritance for enumerated types? - - App_DirectoryBase = 0x00010000 - , App_PrefsDirectory30 = App_DirectoryBase + 1 - , App_PrefsDirectory40 = App_DirectoryBase + 2 - , App_PrefsDirectory50 = App_DirectoryBase + 3 + enum Type + { + // Use a big offset, so that values passed to nsIFileLocator can share the + // same range as the type nsSpecialSystemDirectory::SystemDirectories. + + // Who has not wished one could have inheritance for enumerated types? + + App_DirectoryBase = 0x00010000 + , App_PrefsDirectory30 = App_DirectoryBase + 1 + , App_PrefsDirectory40 = App_DirectoryBase + 2 + , App_PrefsDirectory50 = App_DirectoryBase + 3 - , App_ResDirectory = App_DirectoryBase + 5 + , App_ResDirectory = App_DirectoryBase + 5 - , App_UserProfileDirectory30 = App_DirectoryBase + 10 - , App_UserProfileDirectory40 = App_DirectoryBase + 11 - , App_UserProfileDirectory50 = App_DirectoryBase + 12 - , App_DefaultUserProfileRoot30 = App_DirectoryBase + 13 - , App_DefaultUserProfileRoot40 = App_DirectoryBase + 14 - , App_DefaultUserProfileRoot50 = App_DirectoryBase + 15 - , App_ProfileDefaultsFolder30 = App_DirectoryBase + 16 - , App_ProfileDefaultsFolder40 = App_DirectoryBase + 17 - , App_ProfileDefaultsFolder50 = App_DirectoryBase + 18 - , App_PrefDefaultsFolder50 = App_DirectoryBase + 19 + , App_UserProfileDirectory30 = App_DirectoryBase + 10 + , App_UserProfileDirectory40 = App_DirectoryBase + 11 + , App_UserProfileDirectory50 = App_DirectoryBase + 12 + , App_DefaultUserProfileRoot30 = App_DirectoryBase + 13 + , App_DefaultUserProfileRoot40 = App_DirectoryBase + 14 + , App_DefaultUserProfileRoot50 = App_DirectoryBase + 15 + , App_ProfileDefaultsFolder30 = App_DirectoryBase + 16 + , App_ProfileDefaultsFolder40 = App_DirectoryBase + 17 + , App_ProfileDefaultsFolder50 = App_DirectoryBase + 18 + , App_PrefDefaultsFolder50 = App_DirectoryBase + 19 - , App_DefaultsFolder50 = App_DirectoryBase + 25 + , App_DefaultsFolder50 = App_DirectoryBase + 25 - , App_ComponentsDirectory = App_DirectoryBase + 30 - , App_ChromeDirectory = App_DirectoryBase + 31 - , App_PluginsDirectory = App_DirectoryBase + 32 + , App_ComponentsDirectory = App_DirectoryBase + 30 + , App_ChromeDirectory = App_DirectoryBase + 31 + , App_PluginsDirectory = App_DirectoryBase + 32 , App_UserChromeDirectory = App_DirectoryBase + 40 - , App_FileBase = App_DirectoryBase + 1000 - , App_PreferencesFile30 = App_FileBase + 1 - , App_PreferencesFile40 = App_FileBase + 2 - , App_PreferencesFile50 = App_FileBase + 3 + , App_FileBase = App_DirectoryBase + 1000 + , App_PreferencesFile30 = App_FileBase + 1 + , App_PreferencesFile40 = App_FileBase + 2 + , App_PreferencesFile50 = App_FileBase + 3 - , App_BookmarksFile30 = App_FileBase + 10 - , App_BookmarksFile40 = App_FileBase + 11 - , App_BookmarksFile50 = App_FileBase + 12 + , App_BookmarksFile30 = App_FileBase + 10 + , App_BookmarksFile40 = App_FileBase + 11 + , App_BookmarksFile50 = App_FileBase + 12 - , App_Registry40 = App_FileBase + 20 - , App_Registry50 = App_FileBase + 21 - , App_LocalStore50 = App_FileBase + 30 - , App_History50 = App_FileBase + 40 - , App_MailDirectory50 = App_FileBase + 50 - , App_ImapMailDirectory50 = App_FileBase + 60 - , App_NewsDirectory50 = App_FileBase + 70 - , App_MessengerFolderCache50 = App_FileBase + 80 - , App_UsersPanels50 = App_FileBase + 90 - , App_SearchFile50 = App_FileBase + 100 - , App_SearchDirectory50 = App_FileBase + 101 - }; + , App_Registry40 = App_FileBase + 20 + , App_Registry50 = App_FileBase + 21 + , App_LocalStore50 = App_FileBase + 30 + , App_History50 = App_FileBase + 40 + , App_MailDirectory50 = App_FileBase + 50 + , App_ImapMailDirectory50 = App_FileBase + 60 + , App_NewsDirectory50 = App_FileBase + 70 + , App_MessengerFolderCache50 = App_FileBase + 80 + , App_UsersPanels50 = App_FileBase + 90 + , App_SearchFile50 = App_FileBase + 100 + , App_SearchDirectory50 = App_FileBase + 101 + }; //nsSpecialFileSpec(); nsSpecialFileSpec(Type aType); virtual ~nsSpecialFileSpec(); @@ -130,4 +162,5 @@ private: }; // class NS_APPSHELL nsSpecialFileSpec + #endif // _NSFILELOCATIONS_H_ diff --git a/xpfe/appshell/src/nsFileLocations.cpp b/xpfe/appshell/src/nsFileLocations.cpp index 672d4355748..58df9046ba9 100644 --- a/xpfe/appshell/src/nsFileLocations.cpp +++ b/xpfe/appshell/src/nsFileLocations.cpp @@ -60,10 +60,89 @@ static NS_DEFINE_CID(kProfileCID, NS_PROFILE_CID); // Global variable for gProfileDir static nsFileSpec* gProfileDir = nsnull; - +static PRInt32 gRegisteredWithDirService = PR_FALSE; #ifdef XP_MAC #pragma export on #endif + + +struct DirectoryTable +{ + char * directoryName; /* The formal directory name */ + PRInt32 folderEnum; /* Directory ID */ +}; + +struct DirectoryTable DirectoryTable[] = +{ +// Preferences: + + {"app.prefs.directory.3", nsSpecialFileSpec::App_PrefsDirectory30 }, + {"app.prefs.directory.4", nsSpecialFileSpec::App_PrefsDirectory40 }, + {"app.prefs.directory.5", nsSpecialFileSpec::App_PrefsDirectory50 }, + {"app.pref.default.directory.5", nsSpecialFileSpec::App_PrefDefaultsFolder50 }, + + {"app.prefs.file.3", nsSpecialFileSpec::App_PreferencesFile30 }, + {"app.prefs.file.4", nsSpecialFileSpec::App_PreferencesFile40 }, + {"app.prefs.file.5", nsSpecialFileSpec::App_PreferencesFile50 }, + +// Profile: + + {"app.profile.user.directory.3", nsSpecialFileSpec::App_UserProfileDirectory30 }, + {"app.profile.user.directory.4", nsSpecialFileSpec::App_UserProfileDirectory40 }, + {"app.profile.user.directory.5", nsSpecialFileSpec::App_UserProfileDirectory50 }, + {"app.profile.default.user.directory.3",nsSpecialFileSpec::App_DefaultUserProfileRoot30 }, + {"app.profile.default.user.directory.4",nsSpecialFileSpec::App_DefaultUserProfileRoot40 }, + {"app.profile.default.user.directory.5",nsSpecialFileSpec::App_DefaultUserProfileRoot50 }, + {"app.profile.defaults.directory.3", nsSpecialFileSpec::App_ProfileDefaultsFolder30 }, + {"app.profile.defaults.directory.4", nsSpecialFileSpec::App_ProfileDefaultsFolder40 }, + {"app.profile.defaults.directory.5", nsSpecialFileSpec::App_ProfileDefaultsFolder50 }, + + +// Application Directories: + {"app.res.directory", nsSpecialFileSpec::App_ResDirectory }, + {"app.defaults.directory", nsSpecialFileSpec::App_DefaultsFolder50 }, + {"app.chrome.directory", nsSpecialFileSpec::App_ChromeDirectory }, + {"app.chrome.user.directory", nsSpecialFileSpec::App_UserChromeDirectory }, + {"app.plugins.directory", nsSpecialFileSpec::App_PluginsDirectory }, + +// Bookmarks: + + {"app.bookmark.file.3", nsSpecialFileSpec::App_BookmarksFile30 }, + {"app.bookmark.file.4", nsSpecialFileSpec::App_BookmarksFile40 }, + {"app.bookmark.file.5", nsSpecialFileSpec::App_BookmarksFile50 }, + +// Search + {"app.search.file.5", nsSpecialFileSpec::App_SearchFile50 }, + {"app.search.directory.5", nsSpecialFileSpec::App_SearchDirectory50 }, + +// Application Files: + + {"app.registry.file.4", nsSpecialFileSpec::App_Registry40 }, + {"app.registry.file.5", nsSpecialFileSpec::App_Registry50 }, + {"app.local.store.file.5", nsSpecialFileSpec::App_LocalStore50 }, + {"app.history.file.5", nsSpecialFileSpec::App_History50 }, + {"app.user.panels.5", nsSpecialFileSpec::App_UsersPanels50 }, + +// MailNews: + + {"app.mail.directory.5", nsSpecialFileSpec::App_MailDirectory50 }, + {"app.mail.imap.directory.5", nsSpecialFileSpec::App_ImapMailDirectory50 }, + {"app.mail.news.directory.5", nsSpecialFileSpec::App_NewsDirectory50 }, + {"app.mail.messenger.cache.directory.5", nsSpecialFileSpec::App_MessengerFolderCache50 }, + + {"", 0 }, +}; + + + + + + + + + + + //======================================================================================== // Static functions that ain't nobody else's business. //======================================================================================== @@ -326,7 +405,7 @@ void nsSpecialFileSpec::operator = (Type aType) #endif } break; - case App_ChromeDirectory: + case App_ChromeDirectory: { *this = nsSpecialSystemDirectory(nsSpecialSystemDirectory::OS_CurrentProcessDirectory); #ifdef XP_MAC @@ -336,7 +415,7 @@ void nsSpecialFileSpec::operator = (Type aType) #endif } break; - case App_PluginsDirectory: + case App_PluginsDirectory: { *this = nsSpecialSystemDirectory(nsSpecialSystemDirectory::OS_CurrentProcessDirectory); #ifdef XP_MAC @@ -347,7 +426,7 @@ void nsSpecialFileSpec::operator = (Type aType) } break; - case App_UserChromeDirectory: + case App_UserChromeDirectory: { *this = nsSpecialFileSpec(App_UserProfileDirectory50); *this += "Chrome"; @@ -465,20 +544,20 @@ void nsSpecialFileSpec::operator = (Type aType) NS_NOTYETIMPLEMENTED("Write me!"); break; - case App_LocalStore50: + case App_LocalStore50: { *this = nsSpecialFileSpec(App_UserProfileDirectory50); *this += "localstore.rdf"; break; } break; - case App_History50: - { - *this = nsSpecialFileSpec(App_UserProfileDirectory50); + case App_History50: + { + *this = nsSpecialFileSpec(App_UserProfileDirectory50); *this += "history.dat"; break; } - break; + break; case App_MailDirectory50: { *this = nsSpecialFileSpec(App_UserProfileDirectory50); @@ -500,74 +579,74 @@ void nsSpecialFileSpec::operator = (Type aType) break; } break; - case App_MessengerFolderCache50: + case App_MessengerFolderCache50: { *this = nsSpecialFileSpec(App_UserProfileDirectory50); *this += "panacea.dat"; break; } break; - case App_UsersPanels50: - { - *this = nsSpecialFileSpec(App_UserProfileDirectory50); - *this += "panels.rdf"; + case App_UsersPanels50: + { + *this = nsSpecialFileSpec(App_UserProfileDirectory50); + *this += "panels.rdf"; - if (!(this->Exists())) { - // find the default panels.rdf file - // something like bin/defaults/profile/panels.rdf - nsFileSpec defaultPanelsFile; - GetProfileDefaultsFolder(defaultPanelsFile); - defaultPanelsFile += "panels.rdf"; + if (!(this->Exists())) { + // find the default panels.rdf file + // something like bin/defaults/profile/panels.rdf + nsFileSpec defaultPanelsFile; + GetProfileDefaultsFolder(defaultPanelsFile); + defaultPanelsFile += "panels.rdf"; - // get the users profile directory - *this = nsSpecialFileSpec(App_UserProfileDirectory50); - - // copy the default panels.rdf to /panels.rdf - nsresult rv = defaultPanelsFile.CopyToDir(*this); - NS_ASSERTION(NS_SUCCEEDED(rv), "failed to copy panels.rdf"); - if (NS_SUCCEEDED(rv)) { - // set this to /panels.rdf - *this += "panels.rdf"; - } - } - break; - } + // get the users profile directory + *this = nsSpecialFileSpec(App_UserProfileDirectory50); + + // copy the default panels.rdf to /panels.rdf + nsresult rv = defaultPanelsFile.CopyToDir(*this); + NS_ASSERTION(NS_SUCCEEDED(rv), "failed to copy panels.rdf"); + if (NS_SUCCEEDED(rv)) { + // set this to /panels.rdf + *this += "panels.rdf"; + } + } + break; + } break; - case App_SearchFile50: - { - *this = nsSpecialFileSpec(App_UserProfileDirectory50); - *this += "search.rdf"; + case App_SearchFile50: + { + *this = nsSpecialFileSpec(App_UserProfileDirectory50); + *this += "search.rdf"; - if (!(this->Exists())) { - // find the default search.rdf file - // something like bin/defaults/profile/search.rdf - nsFileSpec defaultPanelsFile; - GetProfileDefaultsFolder(defaultPanelsFile); - defaultPanelsFile += "search.rdf"; + if (!(this->Exists())) { + // find the default search.rdf file + // something like bin/defaults/profile/search.rdf + nsFileSpec defaultPanelsFile; + GetProfileDefaultsFolder(defaultPanelsFile); + defaultPanelsFile += "search.rdf"; - // get the users profile directory - *this = nsSpecialFileSpec(App_UserProfileDirectory50); - - // copy the default search.rdf to /search.rdf - nsresult rv = defaultPanelsFile.CopyToDir(*this); - NS_ASSERTION(NS_SUCCEEDED(rv), "failed to copy search.rdf"); - if (NS_SUCCEEDED(rv)) { - // set this to /search.rdf - *this += "search.rdf"; - } - } - break; - } + // get the users profile directory + *this = nsSpecialFileSpec(App_UserProfileDirectory50); + + // copy the default search.rdf to /search.rdf + nsresult rv = defaultPanelsFile.CopyToDir(*this); + NS_ASSERTION(NS_SUCCEEDED(rv), "failed to copy search.rdf"); + if (NS_SUCCEEDED(rv)) { + // set this to /search.rdf + *this += "search.rdf"; + } + } + break; + } break; - case App_SearchDirectory50: - { + case App_SearchDirectory50: + { *this = nsSpecialSystemDirectory(nsSpecialSystemDirectory::OS_CurrentProcessDirectory); #ifdef XP_MAC *this += "Search Plugins"; #else *this += "searchplugins"; #endif - } + } break; case App_DirectoryBase: case App_FileBase: @@ -591,8 +670,14 @@ nsFileLocator::nsFileLocator() //---------------------------------------------------------------------------------------- { NS_INIT_REFCNT(); -} + + if (gRegisteredWithDirService == 0) + { + PR_AtomicIncrement(&gRegisteredWithDirService); + new nsFileLocationProvider(); + } +} //---------------------------------------------------------------------------------------- nsFileLocator::~nsFileLocator() //---------------------------------------------------------------------------------------- @@ -625,10 +710,92 @@ NS_IMETHODIMP nsFileLocator::GetFileLocation( NS_IMETHODIMP nsFileLocator::ForgetProfileDir() //---------------------------------------------------------------------------------------- { - if (gProfileDir) { - delete gProfileDir; - gProfileDir = nsnull; - } + if (gProfileDir) { + delete gProfileDir; + gProfileDir = nsnull; + + nsresult rv; + NS_WITH_SERVICE(nsIProperties, directoryService, NS_DIRECTORY_SERVICE_PROGID, &rv); + if (NS_FAILED(rv)) return rv; + + directoryService->Undefine("app.profile.user.directory.5"); + directoryService->Undefine("app.profile.default.user.directory.5"); + directoryService->Undefine("app.profile.defaults.directory.5"); + } - return NS_OK; + return NS_OK; } + + + + +nsFileLocationProvider::nsFileLocationProvider() +{ + NS_INIT_REFCNT(); + + nsresult rv; + NS_WITH_SERVICE(nsIDirectoryService, dirService, NS_DIRECTORY_SERVICE_PROGID, &rv); + + if (dirService) + dirService->RegisterProvider( NS_STATIC_CAST(nsIDirectoryServiceProvider*, this) ); +} + +nsFileLocationProvider::~nsFileLocationProvider() +{ +} + + +NS_IMPL_THREADSAFE_ISUPPORTS1(nsFileLocationProvider, nsIDirectoryServiceProvider); + +/* MapNameToEnum + * maps name from the directory table to its enum */ +PRInt32 +static MapNameToEnum(const char* name) +{ + int i = 0; + + if ( !name ) + return -1; + + while ( DirectoryTable[i].directoryName[0] != 0 ) + { + if ( strcmp(DirectoryTable[i].directoryName, name) == 0 ) + return DirectoryTable[i].folderEnum; + i++; + } + return -1; +} +NS_IMETHODIMP +nsFileLocationProvider::GetFile(const char *prop, PRBool *persistant, nsIFile **_retval) +{ + NS_ENSURE_ARG_POINTER(_retval); + + *persistant = PR_TRUE; + nsFileSpec spec; + PRInt32 value = MapNameToEnum(prop); + if (value == -1) + return NS_ERROR_FAILURE; + + nsCOMPtr localFile; + nsresult res; + + if (value < nsSpecialFileSpec::App_DirectoryBase) + { + nsSpecialSystemDirectory ssd = (nsSpecialSystemDirectory::SystemDirectories)value; + res = NS_FileSpecToIFile(&ssd, getter_AddRefs(localFile)); + } + else + { + nsSpecialFileSpec sfs = (nsSpecialFileSpec::Type)value; + res = NS_FileSpecToIFile(&sfs, getter_AddRefs(localFile)); + } + + if (localFile && NS_SUCCEEDED(res)) + return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval); + + return NS_ERROR_FAILURE; +} + + + +