1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-02-04 03:40:07 +00:00

Refactored the PropertiesFile construction, introducing a PropertiesFile::Options structure to hold all the settings that previously were just passed as parameters. Also added a mandatory option for setting the OSX preferences path to be used - see the PropertiesFile::Options::osxLibrarySubFolder value for details.

Also on OSX, changed the location used for interprocess lock files to /var/tmp - this may affect applications which try to share locks with older builds of the same app.
This commit is contained in:
Julian Storer 2011-06-15 16:16:33 +01:00
parent b94782d388
commit 74469aaa83
15 changed files with 568 additions and 433 deletions

View file

@ -54,27 +54,99 @@ namespace PropertyFileConstants
}
//==============================================================================
PropertiesFile::PropertiesFile (const File& f, const int millisecondsBeforeSaving,
const int options_, InterProcessLock* const processLock_)
: PropertySet (ignoreCaseOfKeyNames),
file (f),
timerInterval (millisecondsBeforeSaving),
options (options_),
loadedOk (false),
needsWriting (false),
processLock (processLock_)
PropertiesFile::Options::Options()
: commonToAllUsers (false),
ignoreCaseOfKeyNames (false),
millisecondsBeforeSaving (3000),
storageFormat (PropertiesFile::storeAsXML),
processLock (nullptr)
{
}
File PropertiesFile::Options::getDefaultFile() const
{
// mustn't have illegal characters in this name..
jassert (applicationName == File::createLegalFileName (applicationName));
#if JUCE_MAC || JUCE_IOS
File dir (commonToAllUsers ? "/Library/"
: "~/Library/");
if (osxLibrarySubFolder != "Preferences" && osxLibrarySubFolder != "Application Support")
{
/* The PropertiesFile class always used to put its settings files in "Library/Preferences", but Apple
have changed their advice, and now stipulate that settings should go in "Library/Application Support".
Because older apps would be broken by a silent change in this class's behaviour, you must now
explicitly set the osxLibrarySubFolder value to indicate which path you want to use.
In newer apps, you should always set this to "Application Support".
If your app needs to load settings files that were created by older versions of juce and
you want to maintain backwards-compatibility, then you can set this to "Preferences".
But.. for better Apple-compliance, the recommended approach would be to write some code that
finds your old settings files in ~/Library/Preferences, moves them to ~/Library/Application Support,
and then uses the new path.
*/
jassertfalse;
dir = dir.getChildFile ("Application Support");
}
else
{
dir = dir.getChildFile (osxLibrarySubFolder);
}
if (folderName.isNotEmpty())
dir = dir.getChildFile (folderName);
#elif JUCE_LINUX || JUCE_ANDROID
const File dir ((commonToAllUsers ? "/var/" : "~/")
+ (folderName.isNotEmpty() ? folderName
: ("." + applicationName)));
#elif JUCE_WINDOWS
File dir (File::getSpecialLocation (commonToAllUsers ? File::commonApplicationDataDirectory
: File::userApplicationDataDirectory));
if (dir == File::nonexistent)
return File::nonexistent;
dir = dir.getChildFile (folderName.isNotEmpty() ? folderName
: applicationName);
#endif
return dir.getChildFile (applicationName)
.withFileExtension (filenameSuffix);
}
//==============================================================================
PropertiesFile::PropertiesFile (const File& file_, const Options& options_)
: PropertySet (options.ignoreCaseOfKeyNames),
file (file_), options (options_),
loadedOk (false), needsWriting (false)
{
initialise();
}
PropertiesFile::PropertiesFile (const Options& options_)
: PropertySet (options.ignoreCaseOfKeyNames),
file (options_.getDefaultFile()), options (options_),
loadedOk (false), needsWriting (false)
{
initialise();
}
void PropertiesFile::initialise()
{
// You need to correctly specify just one storage format for the file
jassert ((options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsBinary
|| (options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsCompressedBinary
|| (options_ & (storeAsBinary | storeAsCompressedBinary | storeAsXML)) == storeAsXML);
ProcessScopedLock pl (createProcessLock());
if (pl != nullptr && ! pl->isLocked())
return; // locking failure..
ScopedPointer<InputStream> fileStream (f.createInputStream());
ScopedPointer<InputStream> fileStream (file.createInputStream());
if (fileStream != nullptr)
{
@ -108,7 +180,7 @@ PropertiesFile::PropertiesFile (const File& f, const int millisecondsBeforeSavin
// Not a binary props file - let's see if it's XML..
fileStream = nullptr;
XmlDocument parser (f);
XmlDocument parser (file);
ScopedPointer<XmlElement> doc (parser.getDocumentElement (true));
if (doc != nullptr && doc->hasTagName (PropertyFileConstants::fileTag))
@ -144,7 +216,7 @@ PropertiesFile::PropertiesFile (const File& f, const int millisecondsBeforeSavin
}
else
{
loadedOk = ! f.exists();
loadedOk = ! file.exists();
}
}
@ -156,7 +228,7 @@ PropertiesFile::~PropertiesFile()
InterProcessLock::ScopedLockType* PropertiesFile::createProcessLock() const
{
return processLock != nullptr ? new InterProcessLock::ScopedLockType (*processLock) : nullptr;
return options.processLock != nullptr ? new InterProcessLock::ScopedLockType (*options.processLock) : nullptr;
}
bool PropertiesFile::saveIfNeeded()
@ -188,7 +260,7 @@ bool PropertiesFile::save()
|| ! file.getParentDirectory().createDirectory())
return false;
if ((options & storeAsXML) != 0)
if (options.storageFormat == storeAsXML)
{
XmlElement doc (PropertyFileConstants::fileTag);
@ -230,7 +302,7 @@ bool PropertiesFile::save()
if (out != nullptr)
{
if ((options & storeAsCompressedBinary) != 0)
if (options.storageFormat == storeAsCompressedBinary)
{
out->writeInt (PropertyFileConstants::magicNumberCompressed);
out->flush();
@ -240,7 +312,7 @@ bool PropertiesFile::save()
else
{
// have you set up the storage option flags correctly?
jassert ((options & storeAsBinary) != 0);
jassert (options.storageFormat == storeAsBinary);
out->writeInt (PropertyFileConstants::magicNumber);
}
@ -279,66 +351,11 @@ void PropertiesFile::propertyChanged()
needsWriting = true;
if (timerInterval > 0)
startTimer (timerInterval);
else if (timerInterval == 0)
if (options.millisecondsBeforeSaving > 0)
startTimer (options.millisecondsBeforeSaving);
else if (options.millisecondsBeforeSaving == 0)
saveIfNeeded();
}
//==============================================================================
File PropertiesFile::getDefaultAppSettingsFile (const String& applicationName,
const String& fileNameSuffix,
const String& folderName,
const bool commonToAllUsers)
{
// mustn't have illegal characters in this name..
jassert (applicationName == File::createLegalFileName (applicationName));
#if JUCE_MAC || JUCE_IOS
File dir (commonToAllUsers ? "/Library/Preferences"
: "~/Library/Preferences");
if (folderName.isNotEmpty())
dir = dir.getChildFile (folderName);
#elif JUCE_LINUX || JUCE_ANDROID
const File dir ((commonToAllUsers ? "/var/" : "~/")
+ (folderName.isNotEmpty() ? folderName
: ("." + applicationName)));
#elif JUCE_WINDOWS
File dir (File::getSpecialLocation (commonToAllUsers ? File::commonApplicationDataDirectory
: File::userApplicationDataDirectory));
if (dir == File::nonexistent)
return File::nonexistent;
dir = dir.getChildFile (folderName.isNotEmpty() ? folderName
: applicationName);
#endif
return dir.getChildFile (applicationName)
.withFileExtension (fileNameSuffix);
}
PropertiesFile* PropertiesFile::createDefaultAppPropertiesFile (const String& applicationName,
const String& fileNameSuffix,
const String& folderName,
const bool commonToAllUsers,
const int millisecondsBeforeSaving,
const int propertiesFileOptions,
InterProcessLock* processLock_)
{
const File file (getDefaultAppSettingsFile (applicationName,
fileNameSuffix,
folderName,
commonToAllUsers));
jassert (file != File::nonexistent);
if (file == File::nonexistent)
return nullptr;
return new PropertiesFile (file, millisecondsBeforeSaving, propertiesFileOptions,processLock_);
}
END_JUCE_NAMESPACE