Browse Source

tags/2021-05-28
jules 18 years ago
parent
commit
08cde09921
9 changed files with 164 additions and 99 deletions
  1. +2
    -0
      docs/JUCE changelist.txt
  2. +39
    -52
      src/juce_appframework/application/juce_ApplicationProperties.cpp
  3. +20
    -6
      src/juce_appframework/application/juce_ApplicationProperties.h
  4. +14
    -2
      src/juce_appframework/application/juce_PropertiesFile.cpp
  5. +5
    -0
      src/juce_appframework/application/juce_PropertiesFile.h
  6. +5
    -1
      src/juce_appframework/gui/components/buttons/juce_Button.h
  7. +17
    -32
      src/juce_appframework/gui/components/windows/juce_AlertWindow.cpp
  8. +21
    -5
      src/juce_core/containers/juce_PropertySet.cpp
  9. +41
    -1
      src/juce_core/containers/juce_PropertySet.h

+ 2
- 0
docs/JUCE changelist.txt View File

@@ -20,6 +20,8 @@ Changelist for version 1.44
- added MultiDocumentPanel::createNewDocumentWindow() method to allow creation of custom document windows in a MultiDocumentPanel
- added a Thread::getCurrentThread() method
- added an option to MessageManagerLock that can check for thread termination, to avoid deadlocks.
- new method: PropertySet::setFallbackPropertySet()
- some simplifications to ApplicationProperties, because of problems it was causing when there were read-only common property files.

==============================================================================
Changelist for version 1.43


+ 39
- 52
src/juce_appframework/application/juce_ApplicationProperties.cpp View File

@@ -47,7 +47,8 @@ ApplicationProperties::ApplicationProperties() throw()
: userProps (0),
commonProps (0),
msBeforeSaving (3000),
options (PropertiesFile::storeAsBinary)
options (PropertiesFile::storeAsBinary),
commonSettingsAreReadOnly (0)
{
}
@@ -75,9 +76,8 @@ bool ApplicationProperties::testWriteAccess (const bool testUserSettings,
const bool testCommonSettings,
const bool showWarningDialogOnFailure)
{
const bool userOk = (! testUserSettings) || getUserSettings()->save();
const bool commonOk = (! testCommonSettings)
|| (userProps != getCommonSettings() && getCommonSettings()->save());
const bool userOk = (! testUserSettings) || getUserSettings()->save();
const bool commonOk = (! testCommonSettings) || getCommonSettings (false)->save();
if (! (userOk && commonOk))
{
@@ -85,26 +85,16 @@ bool ApplicationProperties::testWriteAccess (const bool testUserSettings,
{
String filenames;
if (! userOk)
filenames << "\n" << getUserSettings()->getFile().getFullPathName();
if (userProps != 0 && ! userOk)
filenames << '\n' << userProps->getFile().getFullPathName();
if (! commonOk)
{
PropertiesFile* const realCommonProps
= PropertiesFile::createDefaultAppPropertiesFile (appName, fileSuffix, folderName,
true, msBeforeSaving, options);
if (realCommonProps != 0)
{
filenames << "\n" << realCommonProps->getFile().getFullPathName();
delete realCommonProps;
}
}
if (commonProps != 0 && ! commonOk)
filenames << '\n' << commonProps->getFile().getFullPathName();
AlertWindow::showMessageBox (AlertWindow::WarningIcon,
appName + TRANS(" - Unable to save settings"),
TRANS("An error occurred when trying to save the application's settings file...\n\nIn order to save and restore its settings, ")
+ appName + TRANS(" needs to be able to write to the following files:\n")
+ appName + TRANS(" needs to be able to write to the following files:\n")
+ filenames
+ TRANS("\n\nMake sure that these files aren't read-only, and that the disk isn't full."));
}
@@ -116,45 +106,46 @@ bool ApplicationProperties::testWriteAccess (const bool testUserSettings,
}
//==============================================================================
PropertiesFile* ApplicationProperties::getUserSettings() throw()
void ApplicationProperties::openFiles() throw()
{
if (userProps == 0)
{
// You need to call setStorageParameters() before trying to get hold of the
// properties!
jassert (appName.isNotEmpty());
// You need to call setStorageParameters() before trying to get hold of the
// properties!
jassert (appName.isNotEmpty());
if (appName.isNotEmpty())
if (appName.isNotEmpty())
{
if (userProps == 0)
userProps = PropertiesFile::createDefaultAppPropertiesFile (appName, fileSuffix, folderName,
false, msBeforeSaving, options);
if (userProps == 0)
{
// create an emergency properties object to avoid returning a null pointer..
userProps = new PropertiesFile (File::nonexistent, msBeforeSaving, options);
}
if (commonProps == 0)
commonProps = PropertiesFile::createDefaultAppPropertiesFile (appName, fileSuffix, folderName,
true, msBeforeSaving, options);
userProps->setFallbackPropertySet (commonProps);
}
}
PropertiesFile* ApplicationProperties::getUserSettings() throw()
{
if (userProps == 0)
openFiles();
return userProps;
}
PropertiesFile* ApplicationProperties::getCommonSettings() throw()
PropertiesFile* ApplicationProperties::getCommonSettings (const bool returnUserPropsIfReadOnly) throw()
{
if (commonProps == 0)
{
// You need to call setStorageParameters() before trying to get hold of the
// properties!
jassert (appName.isNotEmpty());
openFiles();
if (appName.isNotEmpty())
commonProps = PropertiesFile::createDefaultAppPropertiesFile (appName, fileSuffix, folderName,
true, msBeforeSaving, options);
if (commonProps == 0 || ! commonProps->save())
{
delete commonProps;
commonProps = getUserSettings();
}
if (returnUserPropsIfReadOnly)
{
if (commonSettingsAreReadOnly == 0)
commonSettingsAreReadOnly = commonProps->save() ? -1 : 1;
if (commonSettingsAreReadOnly > 0)
return userProps;
}
return commonProps;
@@ -163,17 +154,13 @@ PropertiesFile* ApplicationProperties::getCommonSettings() throw()
bool ApplicationProperties::saveIfNeeded()
{
return (userProps == 0 || userProps->saveIfNeeded())
&& (commonProps == 0 || commonProps == userProps || commonProps->saveIfNeeded());
&& (commonProps == 0 || commonProps->saveIfNeeded());
}
void ApplicationProperties::closeFiles()
{
delete userProps;
if (commonProps != userProps)
delete commonProps;
userProps = commonProps = 0;
deleteAndZero (userProps);
deleteAndZero (commonProps);
}


+ 20
- 6
src/juce_appframework/application/juce_ApplicationProperties.h View File

@@ -106,7 +106,12 @@ public:
//==============================================================================
/** Returns the user settings file.
The first time this is called, it will create and load the file.
The first time this is called, it will create and load the properties file.
Note that when you search the user PropertiesFile for a value that it doesn't contain,
the common settings are used as a second-chance place to look. This is done via the
PropertySet::setFallbackPropertySet() method - by default the common settings are set
to the fallback for the user settings.
@see getCommonSettings
*/
@@ -114,14 +119,19 @@ public:
/** Returns the common settings file.
The first time this is called, it will create and load the file.
If the common settings file doesn't have write access but the user one does,
then this may return the same PropertiesFile object as getUserSettings().
The first time this is called, it will create and load the properties file.
@param returnUserPropsIfReadOnly if this is true, and the common properties file is
read-only (e.g. because the user doesn't have permission to write
to shared files), then this will return the user settings instead,
(like getUserSettings() would do). This is handy if you'd like to
write a value to the common settings, but if that's no possible,
then you'd rather write to the user settings than none at all.
If returnUserPropsIfReadOnly is false, this method will always return
the common settings, even if any changes to them can't be saved.
@see getUserSettings
*/
PropertiesFile* getCommonSettings() throw();
PropertiesFile* getCommonSettings (const bool returnUserPropsIfReadOnly) throw();
//==============================================================================
/** Saves both files if they need to be saved.
@@ -138,6 +148,7 @@ public:
*/
void closeFiles();
//==============================================================================
juce_UseDebuggingNewOperator
@@ -148,9 +159,12 @@ private:
String appName, fileSuffix, folderName;
int msBeforeSaving, options;
int commonSettingsAreReadOnly;
ApplicationProperties (const ApplicationProperties&);
const ApplicationProperties& operator= (const ApplicationProperties&);
void openFiles() throw();
};


+ 14
- 2
src/juce_appframework/application/juce_PropertiesFile.cpp View File

@@ -144,13 +144,23 @@ bool PropertiesFile::saveIfNeeded()
return (! needsWriting) || save();
}
bool PropertiesFile::needsToBeSaved() const throw()
{
const ScopedLock sl (getLock());
return needsWriting;
}
bool PropertiesFile::save()
{
const ScopedLock sl (getLock());
stopTimer();
if (file == File::nonexistent || file.isDirectory())
if (file == File::nonexistent
|| file.isDirectory()
|| ! file.getParentDirectory().createDirectory())
return false;
if ((options & storeAsXML) != 0)
@@ -292,7 +302,9 @@ PropertiesFile* PropertiesFile::createDefaultAppPropertiesFile (const String& ap
folderName,
commonToAllUsers));
if (file == File::nonexistent || ! file.getParentDirectory().createDirectory())
jassert (file != File::nonexistent);
if (file == File::nonexistent)
return 0;
return new PropertiesFile (file, millisecondsBeforeSaving, propertiesFileOptions);


+ 5
- 0
src/juce_appframework/application/juce_PropertiesFile.h View File

@@ -114,6 +114,11 @@ public:
*/
bool save();
/** Returns true if the properties have been altered since the last time they were
saved.
*/
bool needsToBeSaved() const throw();
//==============================================================================
/** Returns the file that's being used. */
const File getFile() const throw();


+ 5
- 1
src/juce_appframework/gui/components/buttons/juce_Button.h View File

@@ -225,12 +225,16 @@ public:
If generateTooltip is true, then the button's tooltip will be automatically
generated based on the name of this command and its current shortcut key.
@see addShortcut
@see addShortcut, getCommandID
*/
void setCommandToTrigger (ApplicationCommandManager* commandManagerToUse,
const int commandID,
const bool generateTooltip);
/** Returns the command ID that was set by setCommandToTrigger().
*/
int getCommandID() const throw() { return commandID; }
//==============================================================================
/** Assigns a shortcut key to trigger the button.


+ 17
- 32
src/juce_appframework/gui/components/windows/juce_AlertWindow.cpp View File

@@ -45,24 +45,6 @@ static const int titleH = 24;
static const int iconWidth = 80;
//==============================================================================
class AlertWindowTextButton : public TextButton
{
public:
AlertWindowTextButton (const String& text)
: TextButton (text, String::empty)
{
setWantsKeyboardFocus (true);
setMouseClickGrabsKeyboardFocus (false);
}
int returnValue;
private:
AlertWindowTextButton (const AlertWindowTextButton&);
const AlertWindowTextButton& operator= (const AlertWindowTextButton&);
};
//==============================================================================
class AlertWindowTextEditor : public TextEditor
{
@@ -89,13 +71,13 @@ public:
void returnPressed()
{
// pass these up the component hierarchy to be trigger the buttons
Component::keyPressed (KeyPress (KeyPress::returnKey, 0, T('\n')));
getParentComponent()->keyPressed (KeyPress (KeyPress::returnKey, 0, T('\n')));
}
void escapePressed()
{
// pass these up the component hierarchy to be trigger the buttons
Component::keyPressed (KeyPress (KeyPress::escapeKey, 0, 0));
getParentComponent()->keyPressed (KeyPress (KeyPress::escapeKey, 0, 0));
}
private:
@@ -134,8 +116,6 @@ AlertWindow::AlertWindow (const String& title,
lookAndFeelChanged();
constrainer.setMinimumOnscreenAmounts (0x10000, 0x10000, 0x10000, 0x10000);
setWantsKeyboardFocus (getNumChildComponents() == 0);
}
AlertWindow::~AlertWindow()
@@ -172,12 +152,12 @@ void AlertWindow::buttonClicked (Button* button)
{
for (int i = 0; i < buttons.size(); i++)
{
AlertWindowTextButton* const c = (AlertWindowTextButton*) buttons[i];
TextButton* const c = (TextButton*) buttons[i];
if (button->getName() == c->getName())
{
if (c->getParentComponent() != 0)
c->getParentComponent()->exitModalState (c->returnValue);
c->getParentComponent()->exitModalState (c->getCommandID());
break;
}
@@ -190,9 +170,11 @@ void AlertWindow::addButton (const String& name,
const KeyPress& shortcutKey1,
const KeyPress& shortcutKey2)
{
AlertWindowTextButton* const b = new AlertWindowTextButton (name);
TextButton* const b = new TextButton (name, String::empty);
b->returnValue = returnValue;
b->setWantsKeyboardFocus (true);
b->setMouseClickGrabsKeyboardFocus (false);
b->setCommandToTrigger (0, returnValue, false);
b->addShortcut (shortcutKey1);
b->addShortcut (shortcutKey2);
b->addButtonListener (this);
@@ -286,6 +268,7 @@ public:
setCaretVisible (false);
setScrollbarsShown (true);
lookAndFeelChanged();
setWantsKeyboardFocus (false);
setFont (font);
setText (message, false);
@@ -441,14 +424,14 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize)
int buttonW = 40;
int i;
for (i = 0; i < buttons.size(); ++i)
buttonW += 16 + ((const AlertWindowTextButton*) buttons[i])->getWidth();
buttonW += 16 + ((const TextButton*) buttons[i])->getWidth();
w = jmax (buttonW, w);
h += (textBoxes.size() + comboBoxes.size() + progressBars.size()) * 50;
if (buttons.size() > 0)
h += 20 + ((AlertWindowTextButton*) buttons[0])->getHeight();
h += 20 + ((TextButton*) buttons[0])->getHeight();
for (i = customComps.size(); --i >= 0;)
{
@@ -499,14 +482,14 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize)
int totalWidth = -spacer;
for (i = buttons.size(); --i >= 0;)
totalWidth += ((AlertWindowTextButton*) buttons[i])->getWidth() + spacer;
totalWidth += ((TextButton*) buttons[i])->getWidth() + spacer;
int x = (w - totalWidth) / 2;
int y = (int) (getHeight() * 0.95f);
for (i = 0; i < buttons.size(); ++i)
{
AlertWindowTextButton* const c = (AlertWindowTextButton*) buttons[i];
TextButton* const c = (TextButton*) buttons[i];
int ny = proportionOfHeight (0.95f) - c->getHeight();
c->setTopLeftPosition (x, ny);
if (ny < y)
@@ -544,6 +527,8 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize)
y += h + 10;
}
}
setWantsKeyboardFocus (getNumChildComponents() == 0);
}
bool AlertWindow::containsAnyExtraComponents() const
@@ -569,7 +554,7 @@ bool AlertWindow::keyPressed (const KeyPress& key)
{
for (int i = buttons.size(); --i >= 0;)
{
AlertWindowTextButton* const b = (AlertWindowTextButton*) buttons[i];
TextButton* const b = (TextButton*) buttons[i];
if (b->isRegisteredForShortcut (key))
{
@@ -585,7 +570,7 @@ bool AlertWindow::keyPressed (const KeyPress& key)
}
else if (key.isKeyCode (KeyPress::returnKey) && buttons.size() == 1)
{
((AlertWindowTextButton*) buttons.getFirst())->triggerClick();
((TextButton*) buttons.getFirst())->triggerClick();
return true;
}


+ 21
- 5
src/juce_core/containers/juce_PropertySet.cpp View File

@@ -42,6 +42,7 @@ BEGIN_JUCE_NAMESPACE
//==============================================================================
PropertySet::PropertySet (const bool ignoreCaseOfKeyNames) throw()
: properties (ignoreCaseOfKeyNames),
fallbackProperties (0),
ignoreCaseOfKeys (ignoreCaseOfKeyNames)
{
}
@@ -51,11 +52,17 @@ PropertySet::~PropertySet()
}
const String PropertySet::getValue (const String& keyName,
const String& defaultReturnValue) const throw()
const String& defaultValue) const throw()
{
const ScopedLock sl (lock);
return properties.getValue (keyName, defaultReturnValue);
const int index = properties.getAllKeys().indexOf (keyName, ignoreCaseOfKeys);
if (index >= 0)
return properties.getAllValues() [index];
return fallbackProperties != 0 ? fallbackProperties->getValue (keyName, defaultValue)
: defaultValue;
}
int PropertySet::getIntValue (const String& keyName,
@@ -67,7 +74,8 @@ int PropertySet::getIntValue (const String& keyName,
if (index >= 0)
return properties.getAllValues() [index].getIntValue();
return defaultValue;
return fallbackProperties != 0 ? fallbackProperties->getIntValue (keyName, defaultValue)
: defaultValue;
}
double PropertySet::getDoubleValue (const String& keyName,
@@ -79,7 +87,8 @@ double PropertySet::getDoubleValue (const String& keyName,
if (index >= 0)
return properties.getAllValues()[index].getDoubleValue();
return defaultValue;
return fallbackProperties != 0 ? fallbackProperties->getDoubleValue (keyName, defaultValue)
: defaultValue;
}
bool PropertySet::getBoolValue (const String& keyName,
@@ -91,7 +100,8 @@ bool PropertySet::getBoolValue (const String& keyName,
if (index >= 0)
return properties.getAllValues() [index].getIntValue() != 0;
return defaultValue;
return fallbackProperties != 0 ? fallbackProperties->getBoolValue (keyName, defaultValue)
: defaultValue;
}
XmlElement* PropertySet::getXmlValue (const String& keyName) const
@@ -162,6 +172,12 @@ bool PropertySet::containsKey (const String& keyName) const throw()
return properties.getAllKeys().contains (keyName, ignoreCaseOfKeys);
}
void PropertySet::setFallbackPropertySet (PropertySet* fallbackProperties_) throw()
{
const ScopedLock sl (lock);
fallbackProperties = fallbackProperties_;
}
void PropertySet::propertyChanged()
{
}


+ 41
- 1
src/juce_core/containers/juce_PropertySet.h View File

@@ -63,6 +63,10 @@ public:
//==============================================================================
/** Returns one of the properties as a string.
If the value isn't found in this set, then this will look for it in a fallback
property set (if you've specified one with the setFallbackPropertySet() method),
and if it can't find one there, it'll return the default value passed-in.
@param keyName the name of the property to retrieve
@param defaultReturnValue a value to return if the named property doesn't actually exist
*/
@@ -71,6 +75,10 @@ public:
/** Returns one of the properties as an integer.
If the value isn't found in this set, then this will look for it in a fallback
property set (if you've specified one with the setFallbackPropertySet() method),
and if it can't find one there, it'll return the default value passed-in.
@param keyName the name of the property to retrieve
@param defaultReturnValue a value to return if the named property doesn't actually exist
*/
@@ -79,6 +87,10 @@ public:
/** Returns one of the properties as an double.
If the value isn't found in this set, then this will look for it in a fallback
property set (if you've specified one with the setFallbackPropertySet() method),
and if it can't find one there, it'll return the default value passed-in.
@param keyName the name of the property to retrieve
@param defaultReturnValue a value to return if the named property doesn't actually exist
*/
@@ -90,6 +102,10 @@ public:
The result will be true if the string found for this key name can be parsed as a non-zero
integer.
If the value isn't found in this set, then this will look for it in a fallback
property set (if you've specified one with the setFallbackPropertySet() method),
and if it can't find one there, it'll return the default value passed-in.
@param keyName the name of the property to retrieve
@param defaultReturnValue a value to return if the named property doesn't actually exist
*/
@@ -101,6 +117,10 @@ public:
The result will a new XMLElement object that the caller must delete. If may return 0 if the
key isn't found, or if the entry contains an string that isn't valid XML.
If the value isn't found in this set, then this will look for it in a fallback
property set (if you've specified one with the setFallbackPropertySet() method),
and if it can't find one there, it'll return the default value passed-in.
@param keyName the name of the property to retrieve
*/
XmlElement* getXmlValue (const String& keyName) const;
@@ -167,6 +187,25 @@ public:
/** Returns the lock used when reading or writing to this set */
const CriticalSection& getLock() const throw() { return lock; }
//==============================================================================
/** Sets up a second PopertySet that will be used to look up any values that aren't
set in this one.
If you set this up to be a pointer to a second property set, then whenever one
of the getValue() methods fails to find an entry in this set, it will look up that
value in the fallback set, and if it finds it, it will return that.
Make sure that you don't delete the fallback set while it's still being used by
another set! To remove the fallback set, just call this method with a null pointer.
@see getFallbackPropertySet
*/
void setFallbackPropertySet (PropertySet* fallbackProperties) throw();
/** Returns the fallback property set.
@see setFallbackPropertySet
*/
PropertySet* getFallbackPropertySet() const throw() { return fallbackProperties; }
//==============================================================================
juce_UseDebuggingNewOperator
@@ -182,8 +221,9 @@ protected:
private:
//==============================================================================
StringPairArray properties;
bool ignoreCaseOfKeys;
PropertySet* fallbackProperties;
CriticalSection lock;
bool ignoreCaseOfKeys;
PropertySet (const PropertySet&);
const PropertySet& operator= (const PropertySet&);


Loading…
Cancel
Save