2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #ifndef __JUCE_PROPERTIESFILE_JUCEHEADER__
27 #define __JUCE_PROPERTIESFILE_JUCEHEADER__
29 #include "../io/files/juce_File.h"
30 #include "../containers/juce_PropertySet.h"
31 #include "../events/juce_Timer.h"
32 #include "../events/juce_ChangeBroadcaster.h"
33 #include "../threads/juce_InterProcessLock.h"
36 //==============================================================================
37 /** Wrapper on a file that stores a list of key/value data pairs.
39 Useful for storing application settings, etc. See the PropertySet class for
40 the interfaces that read and write values.
42 Not designed for very large amounts of data, as it keeps all the values in
43 memory and writes them out to disk lazily when they are changed.
45 Because this class derives from ChangeBroadcaster, ChangeListeners can be registered
46 with it, and these will be signalled when a value changes.
50 class JUCE_API PropertiesFile
: public PropertySet
,
51 public ChangeBroadcaster
,
55 //==============================================================================
59 storeAsCompressedBinary
,
63 //==============================================================================
66 /** Creates an empty Options structure.
67 You'll need to fill-in the data memebers appropriately before using this structure.
71 /** The name of your application - this is used to help generate the path and filename
72 at which the properties file will be stored. */
73 String applicationName
;
75 /** The suffix to use for your properties file.
76 It doesn't really matter what this is - you may want to use ".settings" or
77 ".properties" or something.
79 String filenameSuffix
;
81 /** The name of a subfolder in which you'd like your properties file to live.
82 See the getDefaultFile() method for more details about how this is used.
86 /** If you're using properties files on a Mac, you must set this value - failure to
87 do so will cause a runtime assertion.
89 The PropertiesFile class always used to put its settings files in "Library/Preferences", but Apple
90 have changed their advice, and now stipulate that settings should go in "Library/Application Support".
92 Because older apps would be broken by a silent change in this class's behaviour, you must now
93 explicitly set the osxLibrarySubFolder value to indicate which path you want to use.
95 In newer apps, you should always set this to "Application Support".
97 If your app needs to load settings files that were created by older versions of juce and
98 you want to maintain backwards-compatibility, then you can set this to "Preferences".
99 But.. for better Apple-compliance, the recommended approach would be to write some code that
100 finds your old settings files in ~/Library/Preferences, moves them to ~/Library/Application Support,
101 and then uses the new path.
103 String osxLibrarySubFolder
;
105 /** If true, the file will be created in a location that's shared between users.
106 The default constructor initialises this value to false.
108 bool commonToAllUsers
;
110 /** If true, this means that property names are matched in a case-insensitive manner.
111 See the PropertySet constructor for more info.
112 The default constructor initialises this value to false.
114 bool ignoreCaseOfKeyNames
;
116 /** If this is zero or greater, then after a value is changed, the object will wait
117 for this amount of time and then save the file. If this zero, the file will be
118 written to disk immediately on being changed (which might be slow, as it'll re-write
119 synchronously each time a value-change method is called). If it is less than zero,
120 the file won't be saved until save() or saveIfNeeded() are explicitly called.
121 The default constructor sets this to a reasonable value of a few seconds, so you
122 only need to change it if you need a special case.
124 int millisecondsBeforeSaving
;
126 /** Specifies whether the file should be written as XML, binary, etc.
127 The default constructor sets this to storeAsXML, so you only need to set it explicitly
128 if you want to use a different format.
130 StorageFormat storageFormat
;
132 /** An optional InterprocessLock object that will be used to prevent multiple threads or
133 processes from writing to the file at the same time. The PropertiesFile will keep a
134 pointer to this object but will not take ownership of it - the caller is responsible for
135 making sure that the lock doesn't get deleted before the PropertiesFile has been deleted.
136 The default constructor initialises this value to nullptr, so you don't need to touch it
137 unless you want to use a lock.
139 InterProcessLock
* processLock
;
141 /** This can be called to suggest a file that should be used, based on the values
144 So on a Mac, this will return a file called:
145 ~/Library/[osxLibrarySubFolder]/[folderName]/[applicationName].[filenameSuffix]
147 On Windows it'll return something like:
148 C:\\Documents and Settings\\username\\Application Data\\[folderName]\\[applicationName].[filenameSuffix]
150 On Linux it'll return
151 ~/.[folderName]/[applicationName].[filenameSuffix]
153 If the folderName variable is empty, it'll use the app name for this (or omit the
154 folder name on the Mac).
156 The paths will also vary depending on whether commonToAllUsers is true.
158 File
getDefaultFile() const;
161 //==============================================================================
162 /** Creates a PropertiesFile object.
163 The file used will be chosen by calling PropertiesFile::Options::getDefaultFile()
164 for the options provided. To set the file explicitly, use the other constructor.
166 explicit PropertiesFile (const Options
& options
);
168 /** Creates a PropertiesFile object.
169 Unlike the other constructor, this one allows you to explicitly set the file that you
170 want to be used, rather than using the default one.
172 PropertiesFile (const File
& file
,
173 const Options
& options
);
176 When deleted, the file will first call saveIfNeeded() to flush any changes to disk.
180 //==============================================================================
181 /** Returns true if this file was created from a valid (or non-existent) file.
182 If the file failed to load correctly because it was corrupt or had insufficient
183 access, this will be false.
185 bool isValidFile() const noexcept
{ return loadedOk
; }
187 //==============================================================================
188 /** This will flush all the values to disk if they've changed since the last
189 time they were saved.
191 Returns false if it fails to write to the file for some reason (maybe because
192 it's read-only or the directory doesn't exist or something).
198 /** This will force a write-to-disk of the current values, regardless of whether
199 anything has changed since the last save.
201 Returns false if it fails to write to the file for some reason (maybe because
202 it's read-only or the directory doesn't exist or something).
208 /** Returns true if the properties have been altered since the last time they were saved.
209 The file is flagged as needing to be saved when you change a value, but you can
210 explicitly set this flag with setNeedsToBeSaved().
212 bool needsToBeSaved() const;
214 /** Explicitly sets the flag to indicate whether the file needs saving or not.
217 void setNeedsToBeSaved (bool needsToBeSaved
);
219 //==============================================================================
220 /** Returns the file that's being used. */
221 File
getFile() const { return file
; }
226 virtual void propertyChanged();
229 //==============================================================================
232 bool loadedOk
, needsWriting
;
234 typedef const ScopedPointer
<InterProcessLock::ScopedLockType
> ProcessScopedLock
;
235 InterProcessLock::ScopedLockType
* createProcessLock() const;
237 void timerCallback();
240 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertiesFile
);
243 #endif // __JUCE_PROPERTIESFILE_JUCEHEADER__