| @@ -1284,6 +1284,11 @@ protected: | |||||
| link->createNewChildElement ("EnableCOMDATFolding")->addTextElement ("true"); | link->createNewChildElement ("EnableCOMDATFolding")->addTextElement ("true"); | ||||
| } | } | ||||
| String extraLinkerOptions (getExtraLinkerFlags().toString()); | |||||
| if (extraLinkerOptions.isNotEmpty()) | |||||
| link->createNewChildElement ("AdditionalOptions")->addTextElement (replacePreprocessorTokens (config, extraLinkerOptions).trim() | |||||
| + " %(AdditionalOptions)"); | |||||
| XmlElement* bsc = group->createNewChildElement ("Bscmake"); | XmlElement* bsc = group->createNewChildElement ("Bscmake"); | ||||
| bsc->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); | bsc->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); | ||||
| bsc->createNewChildElement ("OutputFile")->addTextElement (FileHelpers::windowsStylePath (intermediatesPath + "/" + binaryName + ".bsc")); | bsc->createNewChildElement ("OutputFile")->addTextElement (FileHelpers::windowsStylePath (intermediatesPath + "/" + binaryName + ".bsc")); | ||||
| @@ -135,21 +135,11 @@ private: | |||||
| JuceDemoPluginAudioProcessor::JuceDemoPluginAudioProcessor() | JuceDemoPluginAudioProcessor::JuceDemoPluginAudioProcessor() | ||||
| : delayBuffer (2, 12000) | : delayBuffer (2, 12000) | ||||
| { | { | ||||
| // Set up parameters and default values.. | |||||
| AudioProcessorParameter* gainParam = new AudioProcessorParameter ("gain"); | |||||
| gainParam->resetWithDefault (1.0); | |||||
| parameters.add (gainParam); | |||||
| // Set up some default values.. | |||||
| gain = 1.0f; | |||||
| delay = 0.5f; | |||||
| AudioProcessorParameter* delayParam = new AudioProcessorParameter ("delay"); | |||||
| delayParam->resetWithDefault (0.5); | |||||
| parameters.add (delayParam); | |||||
| AudioProcessorParameter* cutOffParam = new AudioProcessorParameter ("cutoff", AudioProcessorParameter::hertz); | |||||
| cutOffParam->setRange (Range<double> (20.0, 20000.0)); | |||||
| cutOffParam->resetWithDefault (10000.0); | |||||
| parameters.add (cutOffParam); | |||||
| lastUIWidth = 600; | |||||
| lastUIWidth = 400; | |||||
| lastUIHeight = 200; | lastUIHeight = 200; | ||||
| lastPosInfo.resetToDefault(); | lastPosInfo.resetToDefault(); | ||||
| @@ -160,8 +150,6 @@ JuceDemoPluginAudioProcessor::JuceDemoPluginAudioProcessor() | |||||
| synth.addVoice (new SineWaveVoice()); // These voices will play our custom sine-wave sounds.. | synth.addVoice (new SineWaveVoice()); // These voices will play our custom sine-wave sounds.. | ||||
| synth.addSound (new SineWaveSound()); | synth.addSound (new SineWaveSound()); | ||||
| zeromem (lastSample, sizeof (lastSample)); | |||||
| } | } | ||||
| JuceDemoPluginAudioProcessor::~JuceDemoPluginAudioProcessor() | JuceDemoPluginAudioProcessor::~JuceDemoPluginAudioProcessor() | ||||
| @@ -171,7 +159,7 @@ JuceDemoPluginAudioProcessor::~JuceDemoPluginAudioProcessor() | |||||
| //============================================================================== | //============================================================================== | ||||
| int JuceDemoPluginAudioProcessor::getNumParameters() | int JuceDemoPluginAudioProcessor::getNumParameters() | ||||
| { | { | ||||
| return parameters.size(); | |||||
| return totalNumParams; | |||||
| } | } | ||||
| float JuceDemoPluginAudioProcessor::getParameter (int index) | float JuceDemoPluginAudioProcessor::getParameter (int index) | ||||
| @@ -179,8 +167,12 @@ float JuceDemoPluginAudioProcessor::getParameter (int index) | |||||
| // This method will be called by the host, probably on the audio thread, so | // This method will be called by the host, probably on the audio thread, so | ||||
| // it's absolutely time-critical. Don't use critical sections or anything | // it's absolutely time-critical. Don't use critical sections or anything | ||||
| // UI-related, or anything at all that may block in any way! | // UI-related, or anything at all that may block in any way! | ||||
| jassert (parameters [index] != 0); | |||||
| parameters.getUnchecked (index)->getValue(); | |||||
| switch (index) | |||||
| { | |||||
| case gainParam: return gain; | |||||
| case delayParam: return delay; | |||||
| default: return 0.0f; | |||||
| } | |||||
| } | } | ||||
| void JuceDemoPluginAudioProcessor::setParameter (int index, float newValue) | void JuceDemoPluginAudioProcessor::setParameter (int index, float newValue) | ||||
| @@ -188,14 +180,24 @@ void JuceDemoPluginAudioProcessor::setParameter (int index, float newValue) | |||||
| // This method will be called by the host, probably on the audio thread, so | // This method will be called by the host, probably on the audio thread, so | ||||
| // it's absolutely time-critical. Don't use critical sections or anything | // it's absolutely time-critical. Don't use critical sections or anything | ||||
| // UI-related, or anything at all that may block in any way! | // UI-related, or anything at all that may block in any way! | ||||
| jassert (parameters [index] != 0); | |||||
| parameters.getUnchecked (index)->setValue (newValue); | |||||
| switch (index) | |||||
| { | |||||
| case gainParam: gain = newValue; break; | |||||
| case delayParam: delay = newValue; break; | |||||
| default: break; | |||||
| } | |||||
| } | } | ||||
| const String JuceDemoPluginAudioProcessor::getParameterName (int index) | const String JuceDemoPluginAudioProcessor::getParameterName (int index) | ||||
| { | { | ||||
| jassert (parameters [index] != 0); | |||||
| return parameters.getUnchecked (index)->getName(); | |||||
| switch (index) | |||||
| { | |||||
| case gainParam: return "gain"; | |||||
| case delayParam: return "delay"; | |||||
| default: break; | |||||
| } | |||||
| return String::empty; | |||||
| } | } | ||||
| const String JuceDemoPluginAudioProcessor::getParameterText (int index) | const String JuceDemoPluginAudioProcessor::getParameterText (int index) | ||||
| @@ -203,26 +205,6 @@ const String JuceDemoPluginAudioProcessor::getParameterText (int index) | |||||
| return String (getParameter (index), 2); | return String (getParameter (index), 2); | ||||
| } | } | ||||
| int JuceDemoPluginAudioProcessor::indexOfParameter (const String& parameterName) const | |||||
| { | |||||
| for (int i = parameters.size(); --i >= 0;) | |||||
| if (parameters.getUnchecked(i)->getName() == name) | |||||
| return i; | |||||
| return -1; | |||||
| } | |||||
| AudioProcessorParameter* JuceDemoPluginAudioProcessor::getParameterObject (int index) const | |||||
| { | |||||
| return parameters [index]; | |||||
| } | |||||
| AudioProcessorParameter* JuceDemoPluginAudioProcessor::getParameterWithName (const String& parameterName) const | |||||
| { | |||||
| return parameters [indexOfParameter (parameterName)]; | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| void JuceDemoPluginAudioProcessor::prepareToPlay (double sampleRate, int /*samplesPerBlock*/) | void JuceDemoPluginAudioProcessor::prepareToPlay (double sampleRate, int /*samplesPerBlock*/) | ||||
| { | { | ||||
| @@ -251,12 +233,6 @@ void JuceDemoPluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, Midi | |||||
| { | { | ||||
| const int numSamples = buffer.getNumSamples(); | const int numSamples = buffer.getNumSamples(); | ||||
| int channel, dp = 0; | int channel, dp = 0; | ||||
| float gain = getParameter (0); | |||||
| float delay = getParameter (1); | |||||
| float cutOff = getParameter (2); | |||||
| // Get one-pole filter coefficient | |||||
| const float filterCoeff = (float_Pi * cutOff / getSampleRate()); | |||||
| // Go through the incoming data, and apply our gain to it... | // Go through the incoming data, and apply our gain to it... | ||||
| for (channel = 0; channel < getNumInputChannels(); ++channel) | for (channel = 0; channel < getNumInputChannels(); ++channel) | ||||
| @@ -279,12 +255,7 @@ void JuceDemoPluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, Midi | |||||
| for (int i = 0; i < numSamples; ++i) | for (int i = 0; i < numSamples; ++i) | ||||
| { | { | ||||
| const float in = channelData[i]; | const float in = channelData[i]; | ||||
| // filter delay data | |||||
| lastSample [channel] += filterCoeff * (delayData[dp] - lastSample [channel]); | |||||
| // add to output buffers | |||||
| channelData[i] += lastSample [channel]; | |||||
| channelData[i] += delayData[dp]; | |||||
| delayData[dp] = (delayData[dp] + in) * delay; | delayData[dp] = (delayData[dp] + in) * delay; | ||||
| if (++dp > delayBuffer.getNumSamples()) | if (++dp > delayBuffer.getNumSamples()) | ||||
| dp = 0; | dp = 0; | ||||
| @@ -332,12 +303,8 @@ void JuceDemoPluginAudioProcessor::getStateInformation (MemoryBlock& destData) | |||||
| // add some attributes to it.. | // add some attributes to it.. | ||||
| xml.setAttribute ("uiWidth", lastUIWidth); | xml.setAttribute ("uiWidth", lastUIWidth); | ||||
| xml.setAttribute ("uiHeight", lastUIHeight); | xml.setAttribute ("uiHeight", lastUIHeight); | ||||
| for (int i = 0; i < parameters.size(); ++i) | |||||
| { | |||||
| const AudioProcessorParameter* const p = parameters.getUnchecked(i); | |||||
| xml.setAttribute (p->getName(), p->getValue()); | |||||
| } | |||||
| xml.setAttribute ("gain", gain); | |||||
| xml.setAttribute ("delay", delay); | |||||
| // then use this helper function to stuff it into the binary blob and return it.. | // then use this helper function to stuff it into the binary blob and return it.. | ||||
| copyXmlToBinary (xml, destData); | copyXmlToBinary (xml, destData); | ||||
| @@ -356,16 +323,12 @@ void JuceDemoPluginAudioProcessor::setStateInformation (const void* data, int si | |||||
| // make sure that it's actually our type of XML object.. | // make sure that it's actually our type of XML object.. | ||||
| if (xmlState->hasTagName ("MYPLUGINSETTINGS")) | if (xmlState->hasTagName ("MYPLUGINSETTINGS")) | ||||
| { | { | ||||
| // ok, now pull out our plugin-specific attributes.. | |||||
| // ok, now pull out our parameters.. | |||||
| lastUIWidth = xmlState->getIntAttribute ("uiWidth", lastUIWidth); | lastUIWidth = xmlState->getIntAttribute ("uiWidth", lastUIWidth); | ||||
| lastUIHeight = xmlState->getIntAttribute ("uiHeight", lastUIHeight); | lastUIHeight = xmlState->getIntAttribute ("uiHeight", lastUIHeight); | ||||
| // and all the parameters. | |||||
| for (int i = 0; i < parameters.size(); ++i) | |||||
| { | |||||
| const AudioProcessorParameter* const p = parameters.getUnchecked(i); | |||||
| p->setValue (xmlState->getDoubleAttribute (p->getName(), p->getDefault())); | |||||
| } | |||||
| gain = (float) xmlState->getDoubleAttribute ("gain", gain); | |||||
| delay = (float) xmlState->getDoubleAttribute ("delay", delay); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -13484,6 +13484,11 @@ CharPointer_UTF32 String::toUTF32() const | |||||
| return StringEncodingConverter <CharPointerType, CharPointer_UTF32>::convert (*this); | return StringEncodingConverter <CharPointerType, CharPointer_UTF32>::convert (*this); | ||||
| } | } | ||||
| const wchar_t* String::toWideCharPointer() const | |||||
| { | |||||
| return (const wchar_t*) StringEncodingConverter <CharPointerType, CharPointer_wchar_t>::convert (*this).getAddress(); | |||||
| } | |||||
| template <class CharPointerType_Src, class CharPointerType_Dest> | template <class CharPointerType_Src, class CharPointerType_Dest> | ||||
| struct StringCopier | struct StringCopier | ||||
| { | { | ||||
| @@ -64770,6 +64775,7 @@ Viewport::Viewport (const String& componentName) | |||||
| singleStepY (16), | singleStepY (16), | ||||
| showHScrollbar (true), | showHScrollbar (true), | ||||
| showVScrollbar (true), | showVScrollbar (true), | ||||
| deleteContent (true), | |||||
| verticalScrollBar (true), | verticalScrollBar (true), | ||||
| horizontalScrollBar (false) | horizontalScrollBar (false) | ||||
| { | { | ||||
| @@ -64798,18 +64804,26 @@ void Viewport::visibleAreaChanged (const Rectangle<int>&) | |||||
| void Viewport::deleteContentComp() | void Viewport::deleteContentComp() | ||||
| { | { | ||||
| // This sets the content comp to a null pointer before deleting the old one, in case | |||||
| // anything tries to use the old one while it's in mid-deletion.. | |||||
| ScopedPointer<Component> oldCompDeleter (contentComp); | |||||
| contentComp = 0; | |||||
| if (deleteContent) | |||||
| { | |||||
| // This sets the content comp to a null pointer before deleting the old one, in case | |||||
| // anything tries to use the old one while it's in mid-deletion.. | |||||
| ScopedPointer<Component> oldCompDeleter (contentComp); | |||||
| contentComp = 0; | |||||
| } | |||||
| else | |||||
| { | |||||
| contentComp = 0; | |||||
| } | |||||
| } | } | ||||
| void Viewport::setViewedComponent (Component* const newViewedComponent) | |||||
| void Viewport::setViewedComponent (Component* const newViewedComponent, const bool deleteComponentWhenNoLongerNeeded) | |||||
| { | { | ||||
| if (contentComp.get() != newViewedComponent) | if (contentComp.get() != newViewedComponent) | ||||
| { | { | ||||
| deleteContentComp(); | deleteContentComp(); | ||||
| contentComp = newViewedComponent; | contentComp = newViewedComponent; | ||||
| deleteContent = deleteComponentWhenNoLongerNeeded; | |||||
| if (contentComp != 0) | if (contentComp != 0) | ||||
| { | { | ||||
| @@ -261960,25 +261974,19 @@ class LinuxComponentPeer : public ComponentPeer | |||||
| { | { | ||||
| public: | public: | ||||
| LinuxComponentPeer (Component* const component, const int windowStyleFlags) | |||||
| LinuxComponentPeer (Component* const component, const int windowStyleFlags, Window parentToAddTo)) | |||||
| : ComponentPeer (component, windowStyleFlags), | : ComponentPeer (component, windowStyleFlags), | ||||
| windowH (0), | |||||
| parentWindow (0), | |||||
| wx (0), | |||||
| wy (0), | |||||
| ww (0), | |||||
| wh (0), | |||||
| fullScreen (false), | |||||
| mapped (false), | |||||
| visual (0), | |||||
| depth (0) | |||||
| windowH (0), parentWindow (0), | |||||
| wx (0), wy (0), ww (0), wh (0), | |||||
| fullScreen (false), mapped (false), | |||||
| visual (0), depth (0) | |||||
| { | { | ||||
| // it's dangerous to create a window on a thread other than the message thread.. | // it's dangerous to create a window on a thread other than the message thread.. | ||||
| jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | ||||
| repainter = new LinuxRepaintManager (this); | repainter = new LinuxRepaintManager (this); | ||||
| createWindow(); | |||||
| createWindow (parentToAddTo); | |||||
| setTitle (component->getName()); | setTitle (component->getName()); | ||||
| } | } | ||||
| @@ -263337,7 +263345,7 @@ private: | |||||
| (unsigned char*) &netHints, numHints); | (unsigned char*) &netHints, numHints); | ||||
| } | } | ||||
| void createWindow() | |||||
| void createWindow (Window parentToAddTo) | |||||
| { | { | ||||
| ScopedXLock xlock; | ScopedXLock xlock; | ||||
| Atoms::initialiseAtoms(); | Atoms::initialiseAtoms(); | ||||
| @@ -263367,7 +263375,7 @@ private: | |||||
| swa.colormap = colormap; | swa.colormap = colormap; | ||||
| swa.event_mask = getAllEventsMask(); | swa.event_mask = getAllEventsMask(); | ||||
| windowH = XCreateWindow (display, root, | |||||
| windowH = XCreateWindow (display, parentToAddTo != 0 ? parentToAddTo : root, | |||||
| 0, 0, 1, 1, | 0, 0, 1, 1, | ||||
| 0, depth, InputOutput, visual, | 0, depth, InputOutput, visual, | ||||
| CWBorderPixel | CWColormap | CWBackPixmap | CWEventMask, | CWBorderPixel | CWColormap | CWBackPixmap | CWEventMask, | ||||
| @@ -263862,9 +263870,9 @@ void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable | |||||
| kioskModeComponent->setBounds (Desktop::getInstance().getMainMonitorArea (false)); | kioskModeComponent->setBounds (Desktop::getInstance().getMainMonitorArea (false)); | ||||
| } | } | ||||
| ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/) | |||||
| ComponentPeer* Component::createNewPeer (int styleFlags, void* nativeWindowToAttachTo) | |||||
| { | { | ||||
| return new LinuxComponentPeer (this, styleFlags); | |||||
| return new LinuxComponentPeer (this, styleFlags, (Window) nativeWindowToAttachTo); | |||||
| } | } | ||||
| // (this callback is hooked up in the messaging code) | // (this callback is hooked up in the messaging code) | ||||
| @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 53 | #define JUCE_MINOR_VERSION 53 | ||||
| #define JUCE_BUILDNUMBER 43 | |||||
| #define JUCE_BUILDNUMBER 44 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -4462,17 +4462,13 @@ public: | |||||
| // Comparison methods.. | // Comparison methods.. | ||||
| /** Returns true if the string contains no characters. | /** Returns true if the string contains no characters. | ||||
| Note that there's also an isNotEmpty() method to help write readable code. | Note that there's also an isNotEmpty() method to help write readable code. | ||||
| @see containsNonWhitespaceChars() | @see containsNonWhitespaceChars() | ||||
| */ | */ | ||||
| inline bool isEmpty() const throw() { return text[0] == 0; } | inline bool isEmpty() const throw() { return text[0] == 0; } | ||||
| /** Returns true if the string contains at least one character. | /** Returns true if the string contains at least one character. | ||||
| Note that there's also an isEmpty() method to help write readable code. | Note that there's also an isEmpty() method to help write readable code. | ||||
| @see containsNonWhitespaceChars() | @see containsNonWhitespaceChars() | ||||
| */ | */ | ||||
| inline bool isNotEmpty() const throw() { return text[0] != 0; } | inline bool isNotEmpty() const throw() { return text[0] != 0; } | ||||
| @@ -4487,30 +4483,26 @@ public: | |||||
| bool equalsIgnoreCase (const char* other) const throw(); | bool equalsIgnoreCase (const char* other) const throw(); | ||||
| /** Case-sensitive comparison with another string. | /** Case-sensitive comparison with another string. | ||||
| @returns 0 if the two strings are identical; negative if this string | |||||
| comes before the other one alphabetically, or positive if it | |||||
| comes after it. | |||||
| @returns 0 if the two strings are identical; negative if this string comes before | |||||
| the other one alphabetically, or positive if it comes after it. | |||||
| */ | */ | ||||
| int compare (const String& other) const throw(); | int compare (const String& other) const throw(); | ||||
| /** Case-sensitive comparison with another string. | /** Case-sensitive comparison with another string. | ||||
| @returns 0 if the two strings are identical; negative if this string | |||||
| comes before the other one alphabetically, or positive if it | |||||
| comes after it. | |||||
| @returns 0 if the two strings are identical; negative if this string comes before | |||||
| the other one alphabetically, or positive if it comes after it. | |||||
| */ | */ | ||||
| int compare (const char* other) const throw(); | int compare (const char* other) const throw(); | ||||
| /** Case-sensitive comparison with another string. | /** Case-sensitive comparison with another string. | ||||
| @returns 0 if the two strings are identical; negative if this string | |||||
| comes before the other one alphabetically, or positive if it | |||||
| comes after it. | |||||
| @returns 0 if the two strings are identical; negative if this string comes before | |||||
| the other one alphabetically, or positive if it comes after it. | |||||
| */ | */ | ||||
| int compare (const wchar_t* other) const throw(); | int compare (const wchar_t* other) const throw(); | ||||
| /** Case-insensitive comparison with another string. | /** Case-insensitive comparison with another string. | ||||
| @returns 0 if the two strings are identical; negative if this string | |||||
| comes before the other one alphabetically, or positive if it | |||||
| comes after it. | |||||
| @returns 0 if the two strings are identical; negative if this string comes before | |||||
| the other one alphabetically, or positive if it comes after it. | |||||
| */ | */ | ||||
| int compareIgnoreCase (const String& other) const throw(); | int compareIgnoreCase (const String& other) const throw(); | ||||
| @@ -4519,9 +4511,8 @@ public: | |||||
| The comparison used here is case-insensitive and ignores leading non-alphanumeric | The comparison used here is case-insensitive and ignores leading non-alphanumeric | ||||
| characters, making it good for sorting human-readable strings. | characters, making it good for sorting human-readable strings. | ||||
| @returns 0 if the two strings are identical; negative if this string | |||||
| comes before the other one alphabetically, or positive if it | |||||
| comes after it. | |||||
| @returns 0 if the two strings are identical; negative if this string comes before | |||||
| the other one alphabetically, or positive if it comes after it. | |||||
| */ | */ | ||||
| int compareLexicographically (const String& other) const throw(); | int compareLexicographically (const String& other) const throw(); | ||||
| @@ -4612,7 +4603,6 @@ public: | |||||
| int indexOfWholeWordIgnoreCase (const String& wordToLookFor) const throw(); | int indexOfWholeWordIgnoreCase (const String& wordToLookFor) const throw(); | ||||
| /** Looks for any of a set of characters in the string. | /** Looks for any of a set of characters in the string. | ||||
| Uses a case-sensitive comparison. | Uses a case-sensitive comparison. | ||||
| @returns true if the string contains any of the characters from | @returns true if the string contains any of the characters from | ||||
| @@ -4621,7 +4611,6 @@ public: | |||||
| bool containsAnyOf (const String& charactersItMightContain) const throw(); | bool containsAnyOf (const String& charactersItMightContain) const throw(); | ||||
| /** Looks for a set of characters in the string. | /** Looks for a set of characters in the string. | ||||
| Uses a case-sensitive comparison. | Uses a case-sensitive comparison. | ||||
| @returns Returns false if any of the characters in this string do not occur in | @returns Returns false if any of the characters in this string do not occur in | ||||
| @@ -4765,7 +4754,6 @@ public: | |||||
| const juce_wchar operator[] (int index) const throw(); | const juce_wchar operator[] (int index) const throw(); | ||||
| /** Returns the final character of the string. | /** Returns the final character of the string. | ||||
| If the string is empty this will return 0. | If the string is empty this will return 0. | ||||
| */ | */ | ||||
| juce_wchar getLastCharacter() const throw(); | juce_wchar getLastCharacter() const throw(); | ||||
| @@ -4873,8 +4861,10 @@ public: | |||||
| /** Returns a copy of this string with any whitespace characters removed from the start and end. */ | /** Returns a copy of this string with any whitespace characters removed from the start and end. */ | ||||
| const String trim() const; | const String trim() const; | ||||
| /** Returns a copy of this string with any whitespace characters removed from the start. */ | /** Returns a copy of this string with any whitespace characters removed from the start. */ | ||||
| const String trimStart() const; | const String trimStart() const; | ||||
| /** Returns a copy of this string with any whitespace characters removed from the end. */ | /** Returns a copy of this string with any whitespace characters removed from the end. */ | ||||
| const String trimEnd() const; | const String trimEnd() const; | ||||
| @@ -5052,7 +5042,9 @@ public: | |||||
| here because of the popular unrest that was stirred-up when I tried to remove it... | here because of the popular unrest that was stirred-up when I tried to remove it... | ||||
| If you're really determined to use it, at least make sure that you never, ever, | If you're really determined to use it, at least make sure that you never, ever, | ||||
| pass any String objects to it as parameters. | |||||
| pass any String objects to it as parameters. And bear in mind that internally, depending | |||||
| on the platform, it may be using wchar_t or char character types, so that even string | |||||
| literals can't be safely used as parameters if you're writing portable code. | |||||
| */ | */ | ||||
| static const String formatted (const String& formatString, ... ); | static const String formatted (const String& formatString, ... ); | ||||
| @@ -5243,6 +5235,20 @@ public: | |||||
| */ | */ | ||||
| CharPointer_UTF32 toUTF32() const; | CharPointer_UTF32 toUTF32() const; | ||||
| /** Returns a pointer to a wchar_t version of this string. | |||||
| Because it returns a reference to the string's internal data, the pointer | |||||
| that is returned must not be stored anywhere, as it can be deleted whenever the | |||||
| string changes. | |||||
| Bear in mind that the wchar_t type is different on different platforms, so on | |||||
| Windows, this will be equivalent to calling toUTF16(), on unix it'll be the same | |||||
| as calling toUTF32(), etc. | |||||
| @see getCharPointer, toUTF8, toUTF16, toUTF32 | |||||
| */ | |||||
| const wchar_t* toWideCharPointer() const; | |||||
| /** Creates a String from a UTF-8 encoded buffer. | /** Creates a String from a UTF-8 encoded buffer. | ||||
| If the size is < 0, it'll keep reading until it hits a zero. | If the size is < 0, it'll keep reading until it hits a zero. | ||||
| */ | */ | ||||
| @@ -6828,14 +6834,10 @@ public: | |||||
| const ElementType* e = data.elements.getData(); | const ElementType* e = data.elements.getData(); | ||||
| const ElementType* const end = e + numUsed; | const ElementType* const end = e + numUsed; | ||||
| while (e != end) | |||||
| { | |||||
| for (; e != end; ++e) | |||||
| if (elementToLookFor == *e) | if (elementToLookFor == *e) | ||||
| return static_cast <int> (e - data.elements.getData()); | return static_cast <int> (e - data.elements.getData()); | ||||
| ++e; | |||||
| } | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| @@ -6850,14 +6852,10 @@ public: | |||||
| const ElementType* e = data.elements.getData(); | const ElementType* e = data.elements.getData(); | ||||
| const ElementType* const end = e + numUsed; | const ElementType* const end = e + numUsed; | ||||
| while (e != end) | |||||
| { | |||||
| for (; e != end; ++e) | |||||
| if (elementToLookFor == *e) | if (elementToLookFor == *e) | ||||
| return true; | return true; | ||||
| ++e; | |||||
| } | |||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -7239,17 +7237,15 @@ public: | |||||
| void removeValue (ParameterType valueToRemove) | void removeValue (ParameterType valueToRemove) | ||||
| { | { | ||||
| const ScopedLockType lock (getLock()); | const ScopedLockType lock (getLock()); | ||||
| ElementType* e = data.elements; | |||||
| ElementType* const e = data.elements; | |||||
| for (int i = numUsed; --i >= 0;) | |||||
| for (int i = 0; i < numUsed; ++i) | |||||
| { | { | ||||
| if (valueToRemove == *e) | |||||
| if (valueToRemove == e[i]) | |||||
| { | { | ||||
| remove (static_cast <int> (e - data.elements.getData())); | |||||
| remove (i); | |||||
| break; | break; | ||||
| } | } | ||||
| ++e; | |||||
| } | } | ||||
| } | } | ||||
| @@ -9467,14 +9463,10 @@ public: | |||||
| ObjectClass* const* e = data.elements.getData(); | ObjectClass* const* e = data.elements.getData(); | ||||
| ObjectClass* const* const end = e + numUsed; | ObjectClass* const* const end = e + numUsed; | ||||
| while (e != end) | |||||
| { | |||||
| for (; e != end; ++e) | |||||
| if (objectToLookFor == *e) | if (objectToLookFor == *e) | ||||
| return static_cast <int> (e - data.elements.getData()); | return static_cast <int> (e - data.elements.getData()); | ||||
| ++e; | |||||
| } | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| @@ -9489,14 +9481,10 @@ public: | |||||
| ObjectClass* const* e = data.elements.getData(); | ObjectClass* const* e = data.elements.getData(); | ||||
| ObjectClass* const* const end = e + numUsed; | ObjectClass* const* const end = e + numUsed; | ||||
| while (e != end) | |||||
| { | |||||
| for (; e != end; ++e) | |||||
| if (objectToLookFor == *e) | if (objectToLookFor == *e) | ||||
| return true; | return true; | ||||
| ++e; | |||||
| } | |||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -9859,17 +9847,15 @@ public: | |||||
| const bool deleteObject = true) | const bool deleteObject = true) | ||||
| { | { | ||||
| const ScopedLockType lock (getLock()); | const ScopedLockType lock (getLock()); | ||||
| ObjectClass** e = data.elements.getData(); | |||||
| ObjectClass** const e = data.elements.getData(); | |||||
| for (int i = numUsed; --i >= 0;) | |||||
| for (int i = 0; i < numUsed; ++i) | |||||
| { | { | ||||
| if (objectToRemove == *e) | |||||
| if (objectToRemove == e[i]) | |||||
| { | { | ||||
| remove (static_cast <int> (e - data.elements.getData()), deleteObject); | |||||
| remove (i, deleteObject); | |||||
| break; | break; | ||||
| } | } | ||||
| ++e; | |||||
| } | } | ||||
| } | } | ||||
| @@ -12139,7 +12125,7 @@ private: | |||||
| */ | */ | ||||
| #define forEachXmlChildElement(parentXmlElement, childElementVariableName) \ | #define forEachXmlChildElement(parentXmlElement, childElementVariableName) \ | ||||
| \ | \ | ||||
| for (XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \ | |||||
| for (JUCE_NAMESPACE::XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \ | |||||
| childElementVariableName != 0; \ | childElementVariableName != 0; \ | ||||
| childElementVariableName = childElementVariableName->getNextElement()) | childElementVariableName = childElementVariableName->getNextElement()) | ||||
| @@ -12168,7 +12154,7 @@ private: | |||||
| */ | */ | ||||
| #define forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \ | #define forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \ | ||||
| \ | \ | ||||
| for (XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \ | |||||
| for (JUCE_NAMESPACE::XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \ | |||||
| childElementVariableName != 0; \ | childElementVariableName != 0; \ | ||||
| childElementVariableName = childElementVariableName->getNextElementWithTagName (requiredTagName)) | childElementVariableName = childElementVariableName->getNextElementWithTagName (requiredTagName)) | ||||
| @@ -40661,18 +40647,21 @@ public: | |||||
| /** Sets the component that this viewport will contain and scroll around. | /** Sets the component that this viewport will contain and scroll around. | ||||
| This will add the given component to this Viewport and position it at | |||||
| (0, 0). | |||||
| This will add the given component to this Viewport and position it at (0, 0). | |||||
| (Don't add or remove any child components directly using the normal | (Don't add or remove any child components directly using the normal | ||||
| Component::addChildComponent() methods). | Component::addChildComponent() methods). | ||||
| @param newViewedComponent the component to add to this viewport (this pointer | |||||
| may be null). The component passed in will be deleted | |||||
| by the Viewport when it's no longer needed | |||||
| @param newViewedComponent the component to add to this viewport, or null to remove | |||||
| the current component. | |||||
| @param deleteComponentWhenNoLongerNeeded if true, the component will be deleted | |||||
| automatically when the viewport is deleted or when a different | |||||
| component is added. If false, the caller must manage the lifetime | |||||
| of the component | |||||
| @see getViewedComponent | @see getViewedComponent | ||||
| */ | */ | ||||
| void setViewedComponent (Component* newViewedComponent); | |||||
| void setViewedComponent (Component* newViewedComponent, | |||||
| bool deleteComponentWhenNoLongerNeeded = true); | |||||
| /** Returns the component that's currently being used inside the Viewport. | /** Returns the component that's currently being used inside the Viewport. | ||||
| @@ -40851,7 +40840,7 @@ private: | |||||
| Rectangle<int> lastVisibleArea; | Rectangle<int> lastVisibleArea; | ||||
| int scrollBarThickness; | int scrollBarThickness; | ||||
| int singleStepX, singleStepY; | int singleStepX, singleStepY; | ||||
| bool showHScrollbar, showVScrollbar; | |||||
| bool showHScrollbar, showVScrollbar, deleteContent; | |||||
| Component contentHolder; | Component contentHolder; | ||||
| ScrollBar verticalScrollBar; | ScrollBar verticalScrollBar; | ||||
| ScrollBar horizontalScrollBar; | ScrollBar horizontalScrollBar; | ||||
| @@ -43210,7 +43199,7 @@ public: | |||||
| static Type gainToDecibels (const Type gain, | static Type gainToDecibels (const Type gain, | ||||
| const Type minusInfinityDb = (Type) defaultMinusInfinitydB) | const Type minusInfinityDb = (Type) defaultMinusInfinitydB) | ||||
| { | { | ||||
| return gain > Type() ? jmax (minusInfinityDb, (Type) std::log (gain) * (Type) 20.0) | |||||
| return gain > Type() ? jmax (minusInfinityDb, (Type) std::log10 (gain) * (Type) 20.0) | |||||
| : minusInfinityDb; | : minusInfinityDb; | ||||
| } | } | ||||
| @@ -57,7 +57,7 @@ public: | |||||
| static Type gainToDecibels (const Type gain, | static Type gainToDecibels (const Type gain, | ||||
| const Type minusInfinityDb = (Type) defaultMinusInfinitydB) | const Type minusInfinityDb = (Type) defaultMinusInfinitydB) | ||||
| { | { | ||||
| return gain > Type() ? jmax (minusInfinityDb, (Type) std::log (gain) * (Type) 20.0) | |||||
| return gain > Type() ? jmax (minusInfinityDb, (Type) std::log10 (gain) * (Type) 20.0) | |||||
| : minusInfinityDb; | : minusInfinityDb; | ||||
| } | } | ||||
| @@ -303,14 +303,10 @@ public: | |||||
| const ElementType* e = data.elements.getData(); | const ElementType* e = data.elements.getData(); | ||||
| const ElementType* const end = e + numUsed; | const ElementType* const end = e + numUsed; | ||||
| while (e != end) | |||||
| { | |||||
| for (; e != end; ++e) | |||||
| if (elementToLookFor == *e) | if (elementToLookFor == *e) | ||||
| return static_cast <int> (e - data.elements.getData()); | return static_cast <int> (e - data.elements.getData()); | ||||
| ++e; | |||||
| } | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| @@ -325,14 +321,10 @@ public: | |||||
| const ElementType* e = data.elements.getData(); | const ElementType* e = data.elements.getData(); | ||||
| const ElementType* const end = e + numUsed; | const ElementType* const end = e + numUsed; | ||||
| while (e != end) | |||||
| { | |||||
| for (; e != end; ++e) | |||||
| if (elementToLookFor == *e) | if (elementToLookFor == *e) | ||||
| return true; | return true; | ||||
| ++e; | |||||
| } | |||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -716,17 +708,15 @@ public: | |||||
| void removeValue (ParameterType valueToRemove) | void removeValue (ParameterType valueToRemove) | ||||
| { | { | ||||
| const ScopedLockType lock (getLock()); | const ScopedLockType lock (getLock()); | ||||
| ElementType* e = data.elements; | |||||
| ElementType* const e = data.elements; | |||||
| for (int i = numUsed; --i >= 0;) | |||||
| for (int i = 0; i < numUsed; ++i) | |||||
| { | { | ||||
| if (valueToRemove == *e) | |||||
| if (valueToRemove == e[i]) | |||||
| { | { | ||||
| remove (static_cast <int> (e - data.elements.getData())); | |||||
| remove (i); | |||||
| break; | break; | ||||
| } | } | ||||
| ++e; | |||||
| } | } | ||||
| } | } | ||||
| @@ -170,14 +170,10 @@ public: | |||||
| ObjectClass* const* e = data.elements.getData(); | ObjectClass* const* e = data.elements.getData(); | ||||
| ObjectClass* const* const end = e + numUsed; | ObjectClass* const* const end = e + numUsed; | ||||
| while (e != end) | |||||
| { | |||||
| for (; e != end; ++e) | |||||
| if (objectToLookFor == *e) | if (objectToLookFor == *e) | ||||
| return static_cast <int> (e - data.elements.getData()); | return static_cast <int> (e - data.elements.getData()); | ||||
| ++e; | |||||
| } | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| @@ -192,14 +188,10 @@ public: | |||||
| ObjectClass* const* e = data.elements.getData(); | ObjectClass* const* e = data.elements.getData(); | ||||
| ObjectClass* const* const end = e + numUsed; | ObjectClass* const* const end = e + numUsed; | ||||
| while (e != end) | |||||
| { | |||||
| for (; e != end; ++e) | |||||
| if (objectToLookFor == *e) | if (objectToLookFor == *e) | ||||
| return true; | return true; | ||||
| ++e; | |||||
| } | |||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -564,17 +556,15 @@ public: | |||||
| const bool deleteObject = true) | const bool deleteObject = true) | ||||
| { | { | ||||
| const ScopedLockType lock (getLock()); | const ScopedLockType lock (getLock()); | ||||
| ObjectClass** e = data.elements.getData(); | |||||
| ObjectClass** const e = data.elements.getData(); | |||||
| for (int i = numUsed; --i >= 0;) | |||||
| for (int i = 0; i < numUsed; ++i) | |||||
| { | { | ||||
| if (objectToRemove == *e) | |||||
| if (objectToRemove == e[i]) | |||||
| { | { | ||||
| remove (static_cast <int> (e - data.elements.getData()), deleteObject); | |||||
| remove (i, deleteObject); | |||||
| break; | break; | ||||
| } | } | ||||
| ++e; | |||||
| } | } | ||||
| } | } | ||||
| @@ -33,7 +33,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 53 | #define JUCE_MINOR_VERSION 53 | ||||
| #define JUCE_BUILDNUMBER 43 | |||||
| #define JUCE_BUILDNUMBER 44 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -39,6 +39,7 @@ Viewport::Viewport (const String& componentName) | |||||
| singleStepY (16), | singleStepY (16), | ||||
| showHScrollbar (true), | showHScrollbar (true), | ||||
| showVScrollbar (true), | showVScrollbar (true), | ||||
| deleteContent (true), | |||||
| verticalScrollBar (true), | verticalScrollBar (true), | ||||
| horizontalScrollBar (false) | horizontalScrollBar (false) | ||||
| { | { | ||||
| @@ -69,18 +70,26 @@ void Viewport::visibleAreaChanged (const Rectangle<int>&) | |||||
| //============================================================================== | //============================================================================== | ||||
| void Viewport::deleteContentComp() | void Viewport::deleteContentComp() | ||||
| { | { | ||||
| // This sets the content comp to a null pointer before deleting the old one, in case | |||||
| // anything tries to use the old one while it's in mid-deletion.. | |||||
| ScopedPointer<Component> oldCompDeleter (contentComp); | |||||
| contentComp = 0; | |||||
| if (deleteContent) | |||||
| { | |||||
| // This sets the content comp to a null pointer before deleting the old one, in case | |||||
| // anything tries to use the old one while it's in mid-deletion.. | |||||
| ScopedPointer<Component> oldCompDeleter (contentComp); | |||||
| contentComp = 0; | |||||
| } | |||||
| else | |||||
| { | |||||
| contentComp = 0; | |||||
| } | |||||
| } | } | ||||
| void Viewport::setViewedComponent (Component* const newViewedComponent) | |||||
| void Viewport::setViewedComponent (Component* const newViewedComponent, const bool deleteComponentWhenNoLongerNeeded) | |||||
| { | { | ||||
| if (contentComp.get() != newViewedComponent) | if (contentComp.get() != newViewedComponent) | ||||
| { | { | ||||
| deleteContentComp(); | deleteContentComp(); | ||||
| contentComp = newViewedComponent; | contentComp = newViewedComponent; | ||||
| deleteContent = deleteComponentWhenNoLongerNeeded; | |||||
| if (contentComp != 0) | if (contentComp != 0) | ||||
| { | { | ||||
| @@ -61,18 +61,21 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Sets the component that this viewport will contain and scroll around. | /** Sets the component that this viewport will contain and scroll around. | ||||
| This will add the given component to this Viewport and position it at | |||||
| (0, 0). | |||||
| This will add the given component to this Viewport and position it at (0, 0). | |||||
| (Don't add or remove any child components directly using the normal | (Don't add or remove any child components directly using the normal | ||||
| Component::addChildComponent() methods). | Component::addChildComponent() methods). | ||||
| @param newViewedComponent the component to add to this viewport (this pointer | |||||
| may be null). The component passed in will be deleted | |||||
| by the Viewport when it's no longer needed | |||||
| @param newViewedComponent the component to add to this viewport, or null to remove | |||||
| the current component. | |||||
| @param deleteComponentWhenNoLongerNeeded if true, the component will be deleted | |||||
| automatically when the viewport is deleted or when a different | |||||
| component is added. If false, the caller must manage the lifetime | |||||
| of the component | |||||
| @see getViewedComponent | @see getViewedComponent | ||||
| */ | */ | ||||
| void setViewedComponent (Component* newViewedComponent); | |||||
| void setViewedComponent (Component* newViewedComponent, | |||||
| bool deleteComponentWhenNoLongerNeeded = true); | |||||
| /** Returns the component that's currently being used inside the Viewport. | /** Returns the component that's currently being used inside the Viewport. | ||||
| @@ -256,7 +259,7 @@ private: | |||||
| Rectangle<int> lastVisibleArea; | Rectangle<int> lastVisibleArea; | ||||
| int scrollBarThickness; | int scrollBarThickness; | ||||
| int singleStepX, singleStepY; | int singleStepX, singleStepY; | ||||
| bool showHScrollbar, showVScrollbar; | |||||
| bool showHScrollbar, showVScrollbar, deleteContent; | |||||
| Component contentHolder; | Component contentHolder; | ||||
| ScrollBar verticalScrollBar; | ScrollBar verticalScrollBar; | ||||
| ScrollBar horizontalScrollBar; | ScrollBar horizontalScrollBar; | ||||
| @@ -747,25 +747,19 @@ class LinuxComponentPeer : public ComponentPeer | |||||
| { | { | ||||
| public: | public: | ||||
| //============================================================================== | //============================================================================== | ||||
| LinuxComponentPeer (Component* const component, const int windowStyleFlags) | |||||
| LinuxComponentPeer (Component* const component, const int windowStyleFlags, Window parentToAddTo)) | |||||
| : ComponentPeer (component, windowStyleFlags), | : ComponentPeer (component, windowStyleFlags), | ||||
| windowH (0), | |||||
| parentWindow (0), | |||||
| wx (0), | |||||
| wy (0), | |||||
| ww (0), | |||||
| wh (0), | |||||
| fullScreen (false), | |||||
| mapped (false), | |||||
| visual (0), | |||||
| depth (0) | |||||
| windowH (0), parentWindow (0), | |||||
| wx (0), wy (0), ww (0), wh (0), | |||||
| fullScreen (false), mapped (false), | |||||
| visual (0), depth (0) | |||||
| { | { | ||||
| // it's dangerous to create a window on a thread other than the message thread.. | // it's dangerous to create a window on a thread other than the message thread.. | ||||
| jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | ||||
| repainter = new LinuxRepaintManager (this); | repainter = new LinuxRepaintManager (this); | ||||
| createWindow(); | |||||
| createWindow (parentToAddTo); | |||||
| setTitle (component->getName()); | setTitle (component->getName()); | ||||
| } | } | ||||
| @@ -2130,7 +2124,7 @@ private: | |||||
| (unsigned char*) &netHints, numHints); | (unsigned char*) &netHints, numHints); | ||||
| } | } | ||||
| void createWindow() | |||||
| void createWindow (Window parentToAddTo) | |||||
| { | { | ||||
| ScopedXLock xlock; | ScopedXLock xlock; | ||||
| Atoms::initialiseAtoms(); | Atoms::initialiseAtoms(); | ||||
| @@ -2160,7 +2154,7 @@ private: | |||||
| swa.colormap = colormap; | swa.colormap = colormap; | ||||
| swa.event_mask = getAllEventsMask(); | swa.event_mask = getAllEventsMask(); | ||||
| windowH = XCreateWindow (display, root, | |||||
| windowH = XCreateWindow (display, parentToAddTo != 0 ? parentToAddTo : root, | |||||
| 0, 0, 1, 1, | 0, 0, 1, 1, | ||||
| 0, depth, InputOutput, visual, | 0, depth, InputOutput, visual, | ||||
| CWBorderPixel | CWColormap | CWBackPixmap | CWEventMask, | CWBorderPixel | CWColormap | CWBackPixmap | CWEventMask, | ||||
| @@ -2661,9 +2655,9 @@ void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/) | |||||
| ComponentPeer* Component::createNewPeer (int styleFlags, void* nativeWindowToAttachTo) | |||||
| { | { | ||||
| return new LinuxComponentPeer (this, styleFlags); | |||||
| return new LinuxComponentPeer (this, styleFlags, (Window) nativeWindowToAttachTo); | |||||
| } | } | ||||
| @@ -2118,6 +2118,11 @@ CharPointer_UTF32 String::toUTF32() const | |||||
| return StringEncodingConverter <CharPointerType, CharPointer_UTF32>::convert (*this); | return StringEncodingConverter <CharPointerType, CharPointer_UTF32>::convert (*this); | ||||
| } | } | ||||
| const wchar_t* String::toWideCharPointer() const | |||||
| { | |||||
| return (const wchar_t*) StringEncodingConverter <CharPointerType, CharPointer_wchar_t>::convert (*this).getAddress(); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| template <class CharPointerType_Src, class CharPointerType_Dest> | template <class CharPointerType_Src, class CharPointerType_Dest> | ||||
| struct StringCopier | struct StringCopier | ||||
| @@ -283,17 +283,13 @@ public: | |||||
| // Comparison methods.. | // Comparison methods.. | ||||
| /** Returns true if the string contains no characters. | /** Returns true if the string contains no characters. | ||||
| Note that there's also an isNotEmpty() method to help write readable code. | Note that there's also an isNotEmpty() method to help write readable code. | ||||
| @see containsNonWhitespaceChars() | @see containsNonWhitespaceChars() | ||||
| */ | */ | ||||
| inline bool isEmpty() const throw() { return text[0] == 0; } | inline bool isEmpty() const throw() { return text[0] == 0; } | ||||
| /** Returns true if the string contains at least one character. | /** Returns true if the string contains at least one character. | ||||
| Note that there's also an isEmpty() method to help write readable code. | Note that there's also an isEmpty() method to help write readable code. | ||||
| @see containsNonWhitespaceChars() | @see containsNonWhitespaceChars() | ||||
| */ | */ | ||||
| inline bool isNotEmpty() const throw() { return text[0] != 0; } | inline bool isNotEmpty() const throw() { return text[0] != 0; } | ||||
| @@ -308,30 +304,26 @@ public: | |||||
| bool equalsIgnoreCase (const char* other) const throw(); | bool equalsIgnoreCase (const char* other) const throw(); | ||||
| /** Case-sensitive comparison with another string. | /** Case-sensitive comparison with another string. | ||||
| @returns 0 if the two strings are identical; negative if this string | |||||
| comes before the other one alphabetically, or positive if it | |||||
| comes after it. | |||||
| @returns 0 if the two strings are identical; negative if this string comes before | |||||
| the other one alphabetically, or positive if it comes after it. | |||||
| */ | */ | ||||
| int compare (const String& other) const throw(); | int compare (const String& other) const throw(); | ||||
| /** Case-sensitive comparison with another string. | /** Case-sensitive comparison with another string. | ||||
| @returns 0 if the two strings are identical; negative if this string | |||||
| comes before the other one alphabetically, or positive if it | |||||
| comes after it. | |||||
| @returns 0 if the two strings are identical; negative if this string comes before | |||||
| the other one alphabetically, or positive if it comes after it. | |||||
| */ | */ | ||||
| int compare (const char* other) const throw(); | int compare (const char* other) const throw(); | ||||
| /** Case-sensitive comparison with another string. | /** Case-sensitive comparison with another string. | ||||
| @returns 0 if the two strings are identical; negative if this string | |||||
| comes before the other one alphabetically, or positive if it | |||||
| comes after it. | |||||
| @returns 0 if the two strings are identical; negative if this string comes before | |||||
| the other one alphabetically, or positive if it comes after it. | |||||
| */ | */ | ||||
| int compare (const wchar_t* other) const throw(); | int compare (const wchar_t* other) const throw(); | ||||
| /** Case-insensitive comparison with another string. | /** Case-insensitive comparison with another string. | ||||
| @returns 0 if the two strings are identical; negative if this string | |||||
| comes before the other one alphabetically, or positive if it | |||||
| comes after it. | |||||
| @returns 0 if the two strings are identical; negative if this string comes before | |||||
| the other one alphabetically, or positive if it comes after it. | |||||
| */ | */ | ||||
| int compareIgnoreCase (const String& other) const throw(); | int compareIgnoreCase (const String& other) const throw(); | ||||
| @@ -340,9 +332,8 @@ public: | |||||
| The comparison used here is case-insensitive and ignores leading non-alphanumeric | The comparison used here is case-insensitive and ignores leading non-alphanumeric | ||||
| characters, making it good for sorting human-readable strings. | characters, making it good for sorting human-readable strings. | ||||
| @returns 0 if the two strings are identical; negative if this string | |||||
| comes before the other one alphabetically, or positive if it | |||||
| comes after it. | |||||
| @returns 0 if the two strings are identical; negative if this string comes before | |||||
| the other one alphabetically, or positive if it comes after it. | |||||
| */ | */ | ||||
| int compareLexicographically (const String& other) const throw(); | int compareLexicographically (const String& other) const throw(); | ||||
| @@ -433,7 +424,6 @@ public: | |||||
| int indexOfWholeWordIgnoreCase (const String& wordToLookFor) const throw(); | int indexOfWholeWordIgnoreCase (const String& wordToLookFor) const throw(); | ||||
| /** Looks for any of a set of characters in the string. | /** Looks for any of a set of characters in the string. | ||||
| Uses a case-sensitive comparison. | Uses a case-sensitive comparison. | ||||
| @returns true if the string contains any of the characters from | @returns true if the string contains any of the characters from | ||||
| @@ -442,7 +432,6 @@ public: | |||||
| bool containsAnyOf (const String& charactersItMightContain) const throw(); | bool containsAnyOf (const String& charactersItMightContain) const throw(); | ||||
| /** Looks for a set of characters in the string. | /** Looks for a set of characters in the string. | ||||
| Uses a case-sensitive comparison. | Uses a case-sensitive comparison. | ||||
| @returns Returns false if any of the characters in this string do not occur in | @returns Returns false if any of the characters in this string do not occur in | ||||
| @@ -589,7 +578,6 @@ public: | |||||
| const juce_wchar operator[] (int index) const throw(); | const juce_wchar operator[] (int index) const throw(); | ||||
| /** Returns the final character of the string. | /** Returns the final character of the string. | ||||
| If the string is empty this will return 0. | If the string is empty this will return 0. | ||||
| */ | */ | ||||
| juce_wchar getLastCharacter() const throw(); | juce_wchar getLastCharacter() const throw(); | ||||
| @@ -700,8 +688,10 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns a copy of this string with any whitespace characters removed from the start and end. */ | /** Returns a copy of this string with any whitespace characters removed from the start and end. */ | ||||
| const String trim() const; | const String trim() const; | ||||
| /** Returns a copy of this string with any whitespace characters removed from the start. */ | /** Returns a copy of this string with any whitespace characters removed from the start. */ | ||||
| const String trimStart() const; | const String trimStart() const; | ||||
| /** Returns a copy of this string with any whitespace characters removed from the end. */ | /** Returns a copy of this string with any whitespace characters removed from the end. */ | ||||
| const String trimEnd() const; | const String trimEnd() const; | ||||
| @@ -884,7 +874,9 @@ public: | |||||
| here because of the popular unrest that was stirred-up when I tried to remove it... | here because of the popular unrest that was stirred-up when I tried to remove it... | ||||
| If you're really determined to use it, at least make sure that you never, ever, | If you're really determined to use it, at least make sure that you never, ever, | ||||
| pass any String objects to it as parameters. | |||||
| pass any String objects to it as parameters. And bear in mind that internally, depending | |||||
| on the platform, it may be using wchar_t or char character types, so that even string | |||||
| literals can't be safely used as parameters if you're writing portable code. | |||||
| */ | */ | ||||
| static const String formatted (const String& formatString, ... ); | static const String formatted (const String& formatString, ... ); | ||||
| @@ -1077,6 +1069,20 @@ public: | |||||
| */ | */ | ||||
| CharPointer_UTF32 toUTF32() const; | CharPointer_UTF32 toUTF32() const; | ||||
| /** Returns a pointer to a wchar_t version of this string. | |||||
| Because it returns a reference to the string's internal data, the pointer | |||||
| that is returned must not be stored anywhere, as it can be deleted whenever the | |||||
| string changes. | |||||
| Bear in mind that the wchar_t type is different on different platforms, so on | |||||
| Windows, this will be equivalent to calling toUTF16(), on unix it'll be the same | |||||
| as calling toUTF32(), etc. | |||||
| @see getCharPointer, toUTF8, toUTF16, toUTF32 | |||||
| */ | |||||
| const wchar_t* toWideCharPointer() const; | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Creates a String from a UTF-8 encoded buffer. | /** Creates a String from a UTF-8 encoded buffer. | ||||
| If the size is < 0, it'll keep reading until it hits a zero. | If the size is < 0, it'll keep reading until it hits a zero. | ||||
| @@ -53,7 +53,7 @@ | |||||
| */ | */ | ||||
| #define forEachXmlChildElement(parentXmlElement, childElementVariableName) \ | #define forEachXmlChildElement(parentXmlElement, childElementVariableName) \ | ||||
| \ | \ | ||||
| for (XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \ | |||||
| for (JUCE_NAMESPACE::XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \ | |||||
| childElementVariableName != 0; \ | childElementVariableName != 0; \ | ||||
| childElementVariableName = childElementVariableName->getNextElement()) | childElementVariableName = childElementVariableName->getNextElement()) | ||||
| @@ -82,7 +82,7 @@ | |||||
| */ | */ | ||||
| #define forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \ | #define forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \ | ||||
| \ | \ | ||||
| for (XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \ | |||||
| for (JUCE_NAMESPACE::XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \ | |||||
| childElementVariableName != 0; \ | childElementVariableName != 0; \ | ||||
| childElementVariableName = childElementVariableName->getNextElementWithTagName (requiredTagName)) | childElementVariableName = childElementVariableName->getNextElementWithTagName (requiredTagName)) | ||||