diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index f329a3fbf4..f7c33a649e 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -4181,6 +4181,16 @@ END_JUCE_NAMESPACE /*** Start of inlined file: juce_Variant.cpp ***/ BEGIN_JUCE_NAMESPACE +enum VariantStreamMarkers +{ + varMarker_Int = 1, + varMarker_BoolTrue = 2, + varMarker_BoolFalse = 3, + varMarker_Double = 4, + varMarker_String = 5, + varMarker_Int64 = 6 +}; + class var::VariantType { public: @@ -4188,6 +4198,7 @@ public: virtual ~VariantType() {} virtual int toInt (const ValueUnion&) const { return 0; } + virtual int64 toInt64 (const ValueUnion&) const { return 0; } virtual double toDouble (const ValueUnion&) const { return 0; } virtual const String toString (const ValueUnion&) const { return String::empty; } virtual bool toBool (const ValueUnion&) const { return false; } @@ -4195,6 +4206,7 @@ public: virtual bool isVoid() const throw() { return false; } virtual bool isInt() const throw() { return false; } + virtual bool isInt64() const throw() { return false; } virtual bool isBool() const throw() { return false; } virtual bool isDouble() const throw() { return false; } virtual bool isString() const throw() { return false; } @@ -4225,6 +4237,7 @@ public: static const VariantType_Int instance; int toInt (const ValueUnion& data) const { return data.intValue; }; + int64 toInt64 (const ValueUnion& data) const { return (int64) data.intValue; }; double toDouble (const ValueUnion& data) const { return (double) data.intValue; } const String toString (const ValueUnion& data) const { return String (data.intValue); } bool toBool (const ValueUnion& data) const { return data.intValue != 0; } @@ -4238,11 +4251,37 @@ public: void writeToStream (const ValueUnion& data, OutputStream& output) const { output.writeCompressedInt (5); - output.writeByte (1); + output.writeByte (varMarker_Int); output.writeInt (data.intValue); } }; +class var::VariantType_Int64 : public var::VariantType +{ +public: + VariantType_Int64() {} + static const VariantType_Int64 instance; + + int toInt (const ValueUnion& data) const { return (int) data.int64Value; }; + int64 toInt64 (const ValueUnion& data) const { return data.int64Value; }; + double toDouble (const ValueUnion& data) const { return (double) data.int64Value; } + const String toString (const ValueUnion& data) const { return String (data.int64Value); } + bool toBool (const ValueUnion& data) const { return data.int64Value != 0; } + bool isInt64() const throw() { return true; } + + bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() + { + return otherType.toInt64 (otherData) == data.int64Value; + } + + void writeToStream (const ValueUnion& data, OutputStream& output) const + { + output.writeCompressedInt (9); + output.writeByte (varMarker_Int64); + output.writeInt64 (data.int64Value); + } +}; + class var::VariantType_Double : public var::VariantType { public: @@ -4250,6 +4289,7 @@ public: static const VariantType_Double instance; int toInt (const ValueUnion& data) const { return (int) data.doubleValue; }; + int64 toInt64 (const ValueUnion& data) const { return (int64) data.doubleValue; }; double toDouble (const ValueUnion& data) const { return data.doubleValue; } const String toString (const ValueUnion& data) const { return String (data.doubleValue); } bool toBool (const ValueUnion& data) const { return data.doubleValue != 0; } @@ -4263,7 +4303,7 @@ public: void writeToStream (const ValueUnion& data, OutputStream& output) const { output.writeCompressedInt (9); - output.writeByte (4); + output.writeByte (varMarker_Double); output.writeDouble (data.doubleValue); } }; @@ -4275,6 +4315,7 @@ public: static const VariantType_Bool instance; int toInt (const ValueUnion& data) const { return data.boolValue ? 1 : 0; }; + int64 toInt64 (const ValueUnion& data) const { return data.boolValue ? 1 : 0; }; double toDouble (const ValueUnion& data) const { return data.boolValue ? 1.0 : 0.0; } const String toString (const ValueUnion& data) const { return String::charToString (data.boolValue ? '1' : '0'); } bool toBool (const ValueUnion& data) const { return data.boolValue; } @@ -4288,7 +4329,7 @@ public: void writeToStream (const ValueUnion& data, OutputStream& output) const { output.writeCompressedInt (1); - output.writeByte (data.boolValue ? 2 : 3); + output.writeByte (data.boolValue ? (char) varMarker_BoolTrue : (char) varMarker_BoolFalse); } }; @@ -4302,6 +4343,7 @@ public: void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest.stringValue = new String (*source.stringValue); } int toInt (const ValueUnion& data) const { return data.stringValue->getIntValue(); }; + int64 toInt64 (const ValueUnion& data) const { return data.stringValue->getLargeIntValue(); }; double toDouble (const ValueUnion& data) const { return data.stringValue->getDoubleValue(); } const String toString (const ValueUnion& data) const { return *data.stringValue; } bool toBool (const ValueUnion& data) const { return data.stringValue->getIntValue() != 0 @@ -4318,7 +4360,7 @@ public: { const int len = data.stringValue->getNumBytesAsUTF8() + 1; output.writeCompressedInt (len + 1); - output.writeByte (5); + output.writeByte (varMarker_String); HeapBlock temp (len); data.stringValue->copyToUTF8 (temp, len); output.write (temp, len); @@ -4375,6 +4417,7 @@ public: const var::VariantType_Void var::VariantType_Void::instance; const var::VariantType_Int var::VariantType_Int::instance; +const var::VariantType_Int64 var::VariantType_Int64::instance; const var::VariantType_Bool var::VariantType_Bool::instance; const var::VariantType_Double var::VariantType_Double::instance; const var::VariantType_String var::VariantType_String::instance; @@ -4402,6 +4445,11 @@ var::var (const int value_) throw() : type (&VariantType_Int::instance) value.intValue = value_; } +var::var (const int64 value_) throw() : type (&VariantType_Int64::instance) +{ + value.int64Value = value_; +} + var::var (const bool value_) throw() : type (&VariantType_Bool::instance) { value.boolValue = value_; @@ -4442,6 +4490,7 @@ var::var (MethodFunction method_) throw() : type (&VariantType_Method::instance bool var::isVoid() const throw() { return type->isVoid(); } bool var::isInt() const throw() { return type->isInt(); } +bool var::isInt64() const throw() { return type->isInt64(); } bool var::isBool() const throw() { return type->isBool(); } bool var::isDouble() const throw() { return type->isDouble(); } bool var::isString() const throw() { return type->isString(); } @@ -4449,6 +4498,7 @@ bool var::isObject() const throw() { return type->isObject(); } bool var::isMethod() const throw() { return type->isMethod(); } var::operator int() const { return type->toInt (value); } +var::operator int64() const { return type->toInt64 (value); } var::operator bool() const { return type->toBool (value); } var::operator float() const { return (float) type->toDouble (value); } var::operator double() const { return type->toDouble (value); } @@ -4464,6 +4514,7 @@ void var::swapWith (var& other) throw() var& var::operator= (const var& newValue) { type->cleanUp (value); type = newValue.type; type->createCopy (value, newValue.value); return *this; } var& var::operator= (int newValue) { var v (newValue); swapWith (v); return *this; } +var& var::operator= (int64 newValue) { var v (newValue); swapWith (v); return *this; } var& var::operator= (bool newValue) { var v (newValue); swapWith (v); return *this; } var& var::operator= (double newValue) { var v (newValue); swapWith (v); return *this; } var& var::operator= (const char* newValue) { var v (newValue); swapWith (v); return *this; } @@ -4500,11 +4551,12 @@ const var var::readFromStream (InputStream& input) { switch (input.readByte()) { - case 1: return var (input.readInt()); - case 2: return var (true); - case 3: return var (false); - case 4: return var (input.readDouble()); - case 5: + case varMarker_Int: return var (input.readInt()); + case varMarker_Int64: return var (input.readInt64()); + case varMarker_BoolTrue: return var (true); + case varMarker_BoolFalse: return var (false); + case varMarker_Double: return var (input.readDouble()); + case varMarker_String: { MemoryOutputStream mo; mo.writeFromInputStream (input, numBytes - 1); @@ -11434,6 +11486,21 @@ public: return dest; } + template + static const CharPointerType createFromCharPointer (const CharPointer& start, const CharPointer& end) + { + if (start.getAddress() == 0 || start.isEmpty()) + return getEmpty(); + + size_t numChars = start.lengthUpTo (end); + if (numChars == 0) + return getEmpty(); + + const CharPointerType dest (createUninitialised (numChars)); + CharPointerType (dest).writeWithCharLimit (start, (int) (numChars + 1)); + return dest; + } + static CharPointerType createFromFixedLength (const juce_wchar* const src, const size_t numChars) { CharPointerType dest (createUninitialised (numChars)); @@ -11654,6 +11721,11 @@ String::String (const CharPointer_UTF32& t, const size_t maxChars) { } +String::String (const CharPointer_UTF32& start, const CharPointer_UTF32& end) + : text (StringHolder::createFromCharPointer (start, end)) +{ +} + String::String (const CharPointer_ASCII& t) : text (StringHolder::createFromCharPointer (t)) { @@ -11676,8 +11748,9 @@ String::String (const wchar_t* const t, size_t maxChars) const String String::charToString (const juce_wchar character) { String result (Preallocation (1)); - result.text[0] = character; - result.text[1] = 0; + CharPointerType t (result.text); + t.write (character); + t.writeNull(); return result; } @@ -11866,22 +11939,22 @@ const juce_wchar String::operator[] (int index) const throw() int String::hashCode() const throw() { - const juce_wchar* t = text; + CharPointerType t (text); int result = 0; - while (*t != (juce_wchar) 0) - result = 31 * result + *t++; + while (! t.isEmpty()) + result = 31 * result + t.getAndAdvance(); return result; } int64 String::hashCode64() const throw() { - const juce_wchar* t = text; + CharPointerType t (text); int64 result = 0; - while (*t != (juce_wchar) 0) - result = 101 * result + *t++; + while (! t.isEmpty()) + result = 101 * result + t.getAndAdvance(); return result; } @@ -12027,7 +12100,6 @@ void String::append (const String& textToAppend, size_t maxCharsToTake) String& String::operator+= (const juce_wchar* const t) { appendCharPointer (CharPointer_UTF32 (t)); - return *this; } @@ -12206,16 +12278,7 @@ JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const NewLine&) int String::indexOfChar (const juce_wchar character) const throw() { - const juce_wchar* t = text; - - for (;;) - { - if (*t == character) - return (int) (t - text); - - if (*t++ == 0) - return -1; - } + return text.indexOf (character); } int String::lastIndexOfChar (const juce_wchar character) const throw() @@ -12235,21 +12298,8 @@ int String::indexOf (const String& t) const throw() int String::indexOfChar (const int startIndex, const juce_wchar character) const throw() { - if (startIndex > 0 && startIndex >= length()) - return -1; - - const juce_wchar* t = text + jmax (0, startIndex); - - for (;;) - { - if (*t == character) - return (int) (t - text); - - if (*t == 0) - return -1; - - ++t; - } + const int i = (text + startIndex).indexOf (character); + return i < 0 ? -1 : (i + startIndex); } int String::indexOfAnyOf (const String& charactersToLookFor, @@ -12380,18 +12430,7 @@ bool String::contains (const String& other) const throw() bool String::containsChar (const juce_wchar character) const throw() { - const juce_wchar* t = text; - - for (;;) - { - if (*t == 0) - return false; - - if (*t == character) - return true; - - ++t; - } + return text.indexOf (character) >= 0; } bool String::containsIgnoreCase (const String& t) const throw() @@ -12530,15 +12569,11 @@ const String String::repeatedString (const String& stringToRepeat, int numberOfT if (numberOfTimesToRepeat <= 0) return String::empty; - const int len = stringToRepeat.length(); - String result (Preallocation (len * numberOfTimesToRepeat + 1)); + String result (Preallocation (stringToRepeat.length() * numberOfTimesToRepeat + 1)); CharPointerType n (result.text); while (--numberOfTimesToRepeat >= 0) - { - StringHolder::copyChars (n, stringToRepeat.text, len); - n += len; - } + n.writeAll (stringToRepeat.text); return result; } @@ -12917,57 +12952,63 @@ const String String::quoted (const juce_wchar quoteCharacter) const return t; } -const String String::trim() const +static String::CharPointerType findTrimmedEnd (const String::CharPointerType& start, String::CharPointerType end) { - if (isEmpty()) - return empty; - - int start = 0; - - while ((text + start).isWhitespace()) - ++start; + while (end > start) + { + if (! (--end).isWhitespace()) + { + ++end; + break; + } + } - const int len = length(); - int end = len - 1; + return end; +} - while ((end >= start) && (text + end).isWhitespace()) - --end; +const String String::trim() const +{ + if (isNotEmpty()) + { + CharPointerType start (text.findEndOfWhitespace()); - ++end; + const CharPointerType end (start.findTerminatingNull()); + CharPointerType trimmedEnd (findTrimmedEnd (start, end)); - if (end <= start) - return empty; - else if (start > 0 || end < len) - return String (text + start, end - start); + if (trimmedEnd <= start) + return empty; + else if (text < start || trimmedEnd < end) + return String (start, trimmedEnd); + } return *this; } const String String::trimStart() const { - if (isEmpty()) - return empty; - - CharPointerType t (text.findEndOfWhitespace()); + if (isNotEmpty()) + { + const CharPointerType t (text.findEndOfWhitespace()); - if (t == text) - return *this; + if (t != text) + return String (t); + } - return String (t); + return *this; } const String String::trimEnd() const { - if (isEmpty()) - return empty; - - CharPointerType endT (text); - endT = endT.findTerminatingNull() - 1; + if (isNotEmpty()) + { + const CharPointerType end (text.findTerminatingNull()); + CharPointerType trimmedEnd (findTrimmedEnd (text, end)); - while ((endT.getAddress() >= text) && endT.isWhitespace()) - --endT; + if (trimmedEnd < end) + return String (text, trimmedEnd); + } - return String (text, 1 + (int) (endT.getAddress() - text)); + return *this; } const String String::trimCharactersAtStart (const String& charactersToTrim) const @@ -12982,20 +13023,25 @@ const String String::trimCharactersAtStart (const String& charactersToTrim) cons const String String::trimCharactersAtEnd (const String& charactersToTrim) const { - if (isEmpty()) - return empty; + if (isNotEmpty()) + { + const CharPointerType end (text.findTerminatingNull()); + CharPointerType trimmedEnd (end); - const int len = length(); - const juce_wchar* endT = text + (len - 1); - int numToRemove = 0; + while (trimmedEnd > text) + { + if (! charactersToTrim.containsChar (*--trimmedEnd)) + { + ++trimmedEnd; + break; + } + } - while (numToRemove < len && charactersToTrim.containsChar (*endT)) - { - ++numToRemove; - --endT; + if (trimmedEnd < end) + return String (text, trimmedEnd); } - return numToRemove > 0 ? String (text, len - numToRemove) : *this; + return *this; } const String String::retainCharacters (const String& charactersToRetain) const @@ -13048,33 +13094,32 @@ const String String::removeCharacters (const String& charactersToRemove) const const String String::initialSectionContainingOnly (const String& permittedCharacters) const { - int i = 0; + CharPointerType t (text); - for (;;) + while (! t.isEmpty()) { - if (! permittedCharacters.containsChar (text[i])) - break; + if (! permittedCharacters.containsChar (*t)) + return String (text, t); - ++i; + ++t; } - return substring (0, i); + return *this; } const String String::initialSectionNotContaining (const String& charactersToStopAt) const { - const juce_wchar* const t = text; - int i = 0; + CharPointerType t (text); - while (t[i] != 0) + while (! t.isEmpty()) { - if (charactersToStopAt.containsChar (t[i])) - return String (text, i); + if (charactersToStopAt.containsChar (*t)) + return String (text, t); - ++i; + ++t; } - return empty; + return *this; } bool String::containsOnly (const String& chars) const throw() @@ -13090,10 +13135,10 @@ bool String::containsOnly (const String& chars) const throw() bool String::containsAnyOf (const String& chars) const throw() { - const juce_wchar* t = text; + CharPointerType t (text); - while (*t != 0) - if (chars.containsChar (*t++)) + while (! t.isEmpty()) + if (chars.containsChar (t.getAndAdvance())) return true; return false; @@ -13205,40 +13250,50 @@ double String::getDoubleValue() const throw() static const char* const hexDigits = "0123456789abcdef"; -const String String::toHexString (const int number) +template +struct HexConverter { - juce_wchar buffer[32]; - juce_wchar* const end = buffer + 32; - juce_wchar* t = end; - *--t = 0; - unsigned int v = (unsigned int) number; - - do + static const String hexToString (Type v) { - *--t = (juce_wchar) hexDigits [v & 15]; - v >>= 4; + juce_wchar buffer[32]; + juce_wchar* const end = buffer + 32; + juce_wchar* t = end; + *--t = 0; - } while (v != 0); + do + { + *--t = (juce_wchar) hexDigits [(int) (v & 15)]; + v >>= 4; - return String (t, (int) (((char*) end) - (char*) t) - 1); -} + } while (v != 0); -const String String::toHexString (const int64 number) -{ - juce_wchar buffer[32]; - juce_wchar* const end = buffer + 32; - juce_wchar* t = end; - *--t = 0; - uint64 v = (uint64) number; + return String (t, (int) (end - t) - 1); + } - do + static Type stringToHex (String::CharPointerType t) throw() { - *--t = (juce_wchar) hexDigits [(int) (v & 15)]; - v >>= 4; + Type result = 0; - } while (v != 0); + while (! t.isEmpty()) + { + const int hexValue = CharacterFunctions::getHexDigitValue (t.getAndAdvance()); + + if (hexValue >= 0) + result = (result << 4) | hexValue; + } + + return result; + } +}; + +const String String::toHexString (const int number) +{ + return HexConverter ::hexToString ((unsigned int) number); +} - return String (t, (int) (((char*) end) - (char*) t)); +const String String::toHexString (const int64 number) +{ + return HexConverter ::hexToString ((uint64) number); } const String String::toHexString (const short number) @@ -13275,34 +13330,12 @@ const String String::toHexString (const unsigned char* data, const int size, con int String::getHexValue32() const throw() { - int result = 0; - CharPointerType t (text); - - while (! t.isEmpty()) - { - const int hexValue = CharacterFunctions::getHexDigitValue (t.getAndAdvance()); - - if (hexValue >= 0) - result = (result << 4) | hexValue; - } - - return result; + return HexConverter ::stringToHex (text); } int64 String::getHexValue64() const throw() { - int64 result = 0; - CharPointerType t (text); - - while (! t.isEmpty()) - { - const int hexValue = CharacterFunctions::getHexDigitValue (t.getAndAdvance()); - - if (hexValue >= 0) - result = (result << 4) | hexValue; - } - - return result; + return HexConverter ::stringToHex (text); } const String String::createStringFromData (const void* const data_, const int size) @@ -13317,8 +13350,10 @@ const String String::createStringFromData (const void* const data_, const int si { return charToString ((char) data[0]); } - else if ((data[0] == (uint8) CharPointer_UTF16::byteOrderMarkBE1 && data[1] == (uint8) CharPointer_UTF16::byteOrderMarkBE2) - || (data[0] == (uint8) CharPointer_UTF16::byteOrderMarkLE1 && data[1] == (uint8) CharPointer_UTF16::byteOrderMarkLE1)) + else if ((data[0] == (uint8) CharPointer_UTF16::byteOrderMarkBE1 + && data[1] == (uint8) CharPointer_UTF16::byteOrderMarkBE2) + || (data[0] == (uint8) CharPointer_UTF16::byteOrderMarkLE1 + && data[1] == (uint8) CharPointer_UTF16::byteOrderMarkLE1)) { const bool bigEndian = (data[0] == (uint8) CharPointer_UTF16::byteOrderMarkBE1); const int numChars = size / 2 - 1; @@ -13756,7 +13791,9 @@ public: expect (s5.removeCharacters ("1wordxya") == " 2 3"); expectEquals (s5.removeCharacters (String::empty), s5); expect (s5.initialSectionContainingOnly ("word") == L"word"); + expect (String ("word").initialSectionContainingOnly ("word") == L"word"); expectEquals (s5.initialSectionNotContaining (String ("xyz ")), String ("word")); + expectEquals (s5.initialSectionNotContaining (String (";[:'/")), s5); expect (! s5.isQuotedString()); expect (s5.quoted().isQuotedString()); expect (! s5.quoted().unquoted().isQuotedString()); @@ -19453,7 +19490,6 @@ bool FileBasedDocument::loadFrom (const File& newFile, return false; } -#endif bool FileBasedDocument::loadFromUserSpecifiedFile (const bool showMessageOnFailure) { @@ -19476,7 +19512,6 @@ FileBasedDocument::SaveResult FileBasedDocument::save (const bool askUserForFile showMessageOnFailure); } -#if JUCE_MODAL_LOOPS_PERMITTED FileBasedDocument::SaveResult FileBasedDocument::saveAs (const File& newFile, const bool warnAboutOverwritingExistingFiles, const bool askUserForFileIfNotSpecified, @@ -26766,12 +26801,15 @@ public: void runTest() { - beginTest ("Round-trip conversion"); - + beginTest ("Round-trip conversion: Int8"); Test1 ::test (*this); + beginTest ("Round-trip conversion: Int16"); Test1 ::test (*this); + beginTest ("Round-trip conversion: Int24"); Test1 ::test (*this); + beginTest ("Round-trip conversion: Int32"); Test1 ::test (*this); + beginTest ("Round-trip conversion: Float32"); Test1 ::test (*this); } }; @@ -30856,56 +30894,38 @@ void PluginListComponent::deleteKeyPressed (int lastRowSelected) list.removeType (lastRowSelected); } -void PluginListComponent::buttonClicked (Button* button) +void PluginListComponent::optionsMenuCallback (int result) { - if (button == &optionsButton) + switch (result) { - PopupMenu menu; - menu.addItem (1, TRANS("Clear list")); - menu.addItem (5, TRANS("Remove selected plugin from list"), listBox.getNumSelectedRows() > 0); - menu.addItem (6, TRANS("Show folder containing selected plugin"), listBox.getNumSelectedRows() > 0); - menu.addItem (7, TRANS("Remove any plugins whose files no longer exist")); - menu.addSeparator(); - menu.addItem (2, TRANS("Sort alphabetically")); - menu.addItem (3, TRANS("Sort by category")); - menu.addItem (4, TRANS("Sort by manufacturer")); - menu.addSeparator(); - - for (int i = 0; i < AudioPluginFormatManager::getInstance()->getNumFormats(); ++i) - { - AudioPluginFormat* const format = AudioPluginFormatManager::getInstance()->getFormat (i); - - if (format->getDefaultLocationsToSearch().getNumPaths() > 0) - menu.addItem (10 + i, "Scan for new or updated " + format->getName() + " plugins..."); - } - - const int r = menu.showMenu (PopupMenu::Options().withTargetComponent (&optionsButton)); - - if (r == 1) - { + case 1: list.clear(); - } - else if (r == 2) - { + break; + + case 2: list.sort (KnownPluginList::sortAlphabetically); - } - else if (r == 3) - { + break; + + case 3: list.sort (KnownPluginList::sortByCategory); - } - else if (r == 4) - { + break; + + case 4: list.sort (KnownPluginList::sortByManufacturer); - } - else if (r == 5) + break; + + case 5: { const SparseSet selected (listBox.getSelectedRows()); for (int i = list.getNumTypes(); --i >= 0;) if (selected.contains (i)) list.removeType (i); + + break; } - else if (r == 6) + + case 6: { const PluginDescription* const desc = list.getType (listBox.getSelectedRow()); @@ -30914,22 +30934,59 @@ void PluginListComponent::buttonClicked (Button* button) if (File (desc->fileOrIdentifier).existsAsFile()) File (desc->fileOrIdentifier).getParentDirectory().startAsProcess(); } + + break; } - else if (r == 7) - { + + case 7: for (int i = list.getNumTypes(); --i >= 0;) - { if (! AudioPluginFormatManager::getInstance()->doesPluginStillExist (*list.getType (i))) - { list.removeType (i); - } + + break; + + default: + if (result != 0) + { + typeToScan = result - 10; + startTimer (1); } - } - else if (r != 0) + + break; + } +} + +void PluginListComponent::optionsMenuStaticCallback (int result, PluginListComponent* pluginList) +{ + if (pluginList != 0) + pluginList->optionsMenuCallback (result); +} + +void PluginListComponent::buttonClicked (Button* button) +{ + if (button == &optionsButton) + { + PopupMenu menu; + menu.addItem (1, TRANS("Clear list")); + menu.addItem (5, TRANS("Remove selected plugin from list"), listBox.getNumSelectedRows() > 0); + menu.addItem (6, TRANS("Show folder containing selected plugin"), listBox.getNumSelectedRows() > 0); + menu.addItem (7, TRANS("Remove any plugins whose files no longer exist")); + menu.addSeparator(); + menu.addItem (2, TRANS("Sort alphabetically")); + menu.addItem (3, TRANS("Sort by category")); + menu.addItem (4, TRANS("Sort by manufacturer")); + menu.addSeparator(); + + for (int i = 0; i < AudioPluginFormatManager::getInstance()->getNumFormats(); ++i) { - typeToScan = r - 10; - startTimer (1); + AudioPluginFormat* const format = AudioPluginFormatManager::getInstance()->getFormat (i); + + if (format->getDefaultLocationsToSearch().getNumPaths() > 0) + menu.addItem (10 + i, "Scan for new or updated " + format->getName() + " plugins..."); } + + menu.showMenuAsync (PopupMenu::Options().withTargetComponent (&optionsButton), + ModalCallbackFunction::forComponent (optionsMenuStaticCallback, this)); } } @@ -30950,9 +31007,9 @@ void PluginListComponent::filesDropped (const StringArray& files, int, int) list.scanAndAddDragAndDroppedFiles (files, typesFound); } -#if JUCE_MODAL_LOOPS_PERMITTED void PluginListComponent::scanFor (AudioPluginFormat* format) { +#if JUCE_MODAL_LOOPS_PERMITTED if (format == 0) return; @@ -31025,8 +31082,10 @@ void PluginListComponent::scanFor (AudioPluginFormat* format) TRANS("Note that the following files appeared to be plugin files, but failed to load correctly:\n\n") + shortNames.joinIntoString (", ")); } -} +#else + jassertfalse; // this method needs refactoring to work without modal loops.. #endif +} END_JUCE_NAMESPACE /*** End of inlined file: juce_PluginListComponent.cpp ***/ @@ -58288,6 +58347,7 @@ FileChooser::~FileChooser() { } +#if JUCE_MODAL_LOOPS_PERMITTED bool FileChooser::browseForFileToOpen (FilePreviewComponent* previewComponent) { return showDialog (false, true, false, false, false, previewComponent); @@ -58313,21 +58373,6 @@ bool FileChooser::browseForDirectory() return showDialog (true, false, false, false, false, 0); } -const File FileChooser::getResult() const -{ - // if you've used a multiple-file select, you should use the getResults() method - // to retrieve all the files that were chosen. - jassert (results.size() <= 1); - - return results.getFirst(); -} - -const Array& FileChooser::getResults() const -{ - return results; -} - -#if JUCE_MODAL_LOOPS_PERMITTED bool FileChooser::showDialog (const bool selectsDirectories, const bool selectsFiles, const bool isSave, @@ -58401,6 +58446,20 @@ bool FileChooser::showDialog (const bool selectsDirectories, } #endif +const File FileChooser::getResult() const +{ + // if you've used a multiple-file select, you should use the getResults() method + // to retrieve all the files that were chosen. + jassert (results.size() <= 1); + + return results.getFirst(); +} + +const Array& FileChooser::getResults() const +{ + return results; +} + FilePreviewComponent::FilePreviewComponent() { } @@ -58507,6 +58566,7 @@ FileChooserDialogBox::~FileChooserDialogBox() content->chooserComponent.removeListener (this); } +#if JUCE_MODAL_LOOPS_PERMITTED bool FileChooserDialogBox::show (int w, int h) { return showAt (-1, -1, w, h); @@ -58536,6 +58596,7 @@ bool FileChooserDialogBox::showAt (int x, int y, int w, int h) setVisible (false); return ok; } +#endif void FileChooserDialogBox::centreWithDefaultSize (Component* componentToCentreAround) { @@ -58991,6 +59052,7 @@ void FilenameComponent::setDefaultBrowseTarget (const File& newDefaultDirectory) void FilenameComponent::buttonClicked (Button*) { + #if JUCE_MODAL_LOOPS_PERMITTED FileChooser fc (TRANS("Choose a new file"), getCurrentFile() == File::nonexistent ? defaultBrowseFile : getCurrentFile(), @@ -59002,6 +59064,9 @@ void FilenameComponent::buttonClicked (Button*) { setCurrentFile (fc.getResult(), true); } + #else + jassertfalse; // needs rewriting to deal with non-modal environments + #endif } void FilenameComponent::comboBoxChanged (ComboBox*) @@ -59256,6 +59321,7 @@ void FileSearchPathListComponent::deleteKeyPressed (int row) void FileSearchPathListComponent::returnKeyPressed (int row) { + #if JUCE_MODAL_LOOPS_PERMITTED FileChooser chooser (TRANS("Change folder..."), path [row], "*"); if (chooser.browseForDirectory()) @@ -59264,6 +59330,7 @@ void FileSearchPathListComponent::returnKeyPressed (int row) path.add (chooser.getResult(), row); changed(); } + #endif } void FileSearchPathListComponent::listBoxItemDoubleClicked (int row, const MouseEvent&) @@ -59337,12 +59404,14 @@ void FileSearchPathListComponent::buttonClicked (Button* button) if (start == File::nonexistent) start = File::getCurrentWorkingDirectory(); + #if JUCE_MODAL_LOOPS_PERMITTED FileChooser chooser (TRANS("Add a folder..."), start, "*"); if (chooser.browseForDirectory()) - { path.add (chooser.getResult(), currentRow); - } + #else + jassertfalse; // needs rewriting to deal with non-modal environments + #endif } else if (button == &changeButton) { @@ -66530,12 +66599,10 @@ void LookAndFeel::drawTooltip (Graphics& g, const String& text, int width, int h { g.fillAll (findColour (TooltipWindow::backgroundColourId)); - const Colour textCol (findColour (TooltipWindow::textColourId)); - -#if ! JUCE_MAC // The mac windows already have a non-optional 1 pix outline, so don't double it here.. + #if ! JUCE_MAC // The mac windows already have a non-optional 1 pix outline, so don't double it here.. g.setColour (findColour (TooltipWindow::outlineColourId)); g.drawRect (0, 0, width, height, 1); -#endif + #endif const TextLayout tl (LookAndFeelHelpers::layoutTooltipText (text)); @@ -70323,7 +70390,12 @@ int PopupMenu::showWithOptionalCallback (const Options& options, ModalComponentM window->toFront (false); // need to do this after making it modal, or it could // be stuck behind other comps that are already modal.. + #if JUCE_MODAL_LOOPS_PERMITTED return (userCallback == 0 && canBeModal) ? window->runModalLoop() : 0; + #else + jassert (userCallback != 0 && canBeModal); + return 0; + #endif } #if JUCE_MODAL_LOOPS_PERMITTED @@ -70342,6 +70414,7 @@ void PopupMenu::showMenuAsync (const Options& options, ModalComponentManager::Ca showWithOptionalCallback (options, userCallback, false); } +#if JUCE_MODAL_LOOPS_PERMITTED int PopupMenu::show (const int itemIdThatMustBeVisible, const int minimumWidth, const int maximumNumColumns, const int standardItemHeight, @@ -70384,6 +70457,7 @@ int PopupMenu::showAt (Component* componentToAttachTo, return showWithOptionalCallback (options, callback, true); } +#endif bool JUCE_CALLTYPE PopupMenu::dismissAllActiveMenus() { @@ -74259,26 +74333,39 @@ public: m.addSeparator(); m.addItem (2, TRANS("Set this swatch to the current colour")); - const int r = m.showAt (this); + m.showMenuAsync (PopupMenu::Options().withTargetComponent (this), + ModalCallbackFunction::forComponent (menuStaticCallback, this)); + } + +private: + ColourSelector& owner; + const int index; - if (r == 1) + static void menuStaticCallback (int result, SwatchComponent* comp) + { + if (comp != 0) { - owner.setCurrentColour (owner.getSwatchColour (index)); + if (result == 1) + comp->setColourFromSwatch(); + else if (result == 2) + comp->setSwatchFromColour(); } - else if (r == 2) + } + + void setColourFromSwatch() + { + owner.setCurrentColour (owner.getSwatchColour (index)); + } + + void setSwatchFromColour() + { + if (owner.getSwatchColour (index) != owner.getCurrentColour()) { - if (owner.getSwatchColour (index) != owner.getCurrentColour()) - { - owner.setSwatchColour (index, owner.getCurrentColour()); - repaint(); - } + owner.setSwatchColour (index, owner.getCurrentColour()); + repaint(); } } -private: - ColourSelector& owner; - const int index; - JUCE_DECLARE_NON_COPYABLE (SwatchComponent); }; @@ -262634,10 +262721,7 @@ const String PlatformUtilities::convertToPrecomposedUnicode (const String& s) bytesNeeded, &bytesRead, &outputBufferSize, tempOut) == noErr) { - result.preallocateStorage (bytesRead / sizeof (UniChar) + 2); - - CharPointer_UTF32 dest (result.getCharPointer()); - dest.writeAll (CharPointer_UTF16 ((CharPointer_UTF16::CharType*) tempOut.getData())); + result = String (CharPointer_UTF16 ((CharPointer_UTF16::CharType*) tempOut.getData())); } DisposeUnicodeToTextInfo (&conversionInfo); diff --git a/juce_amalgamated.h b/juce_amalgamated.h index e58f5a4f12..8facbed33a 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 31 +#define JUCE_BUILDNUMBER 32 /** Current Juce version number. @@ -1324,7 +1324,7 @@ inline int64 abs64 (const int64 n) throw() template inline Type juce_negate (Type n) throw() { - return sizeof (Type) == 1 ? (Type) -(char) n + return sizeof (Type) == 1 ? (Type) -(signed char) n : (sizeof (Type) == 2 ? (Type) -(short) n : (sizeof (Type) == 4 ? (Type) -(int) n : ((Type) -(int64) n))); @@ -1884,12 +1884,22 @@ public: static int ftime (juce_wchar* dest, int maxChars, const juce_wchar* format, const struct tm* tm) throw(); template - static size_t lengthUpTo (const CharPointerType& text, const size_t maxCharsToCount) throw() + static size_t lengthUpTo (CharPointerType text, const size_t maxCharsToCount) throw() { size_t len = 0; - CharPointerType t (text); - while (len < maxCharsToCount && t.getAndAdvance() != 0) + while (len < maxCharsToCount && text.getAndAdvance() != 0) + ++len; + + return len; + } + + template + static size_t lengthUpTo (CharPointerType start, const CharPointerType& end) throw() + { + size_t len = 0; + + while (start < end && start.getAndAdvance() != 0) ++len; return len; @@ -2498,16 +2508,12 @@ public: } /** This is a pointer comparison, it doesn't compare the actual text. */ - inline bool operator== (const CharPointer_UTF8& other) const throw() - { - return data == other.data; - } - - /** This is a pointer comparison, it doesn't compare the actual text. */ - inline bool operator!= (const CharPointer_UTF8& other) const throw() - { - return data == other.data; - } + inline bool operator== (const CharPointer_UTF8& other) const throw() { return data == other.data; } + inline bool operator!= (const CharPointer_UTF8& other) const throw() { return data != other.data; } + inline bool operator<= (const CharPointer_UTF8& other) const throw() { return data <= other.data; } + inline bool operator< (const CharPointer_UTF8& other) const throw() { return data < other.data; } + inline bool operator>= (const CharPointer_UTF8& other) const throw() { return data >= other.data; } + inline bool operator> (const CharPointer_UTF8& other) const throw() { return data > other.data; } /** Returns the address that this pointer is pointing to. */ inline CharType* getAddress() const throw() { return data; } @@ -2521,7 +2527,7 @@ public: /** Returns the unicode character that this pointer is pointing to. */ juce_wchar operator*() const throw() { - const char byte = *data; + const signed char byte = (signed char) *data; if (byte >= 0) return byte; @@ -2557,7 +2563,7 @@ public: /** Moves this pointer along to the next character in the string. */ CharPointer_UTF8& operator++() throw() { - const char n = *data++; + const signed char n = (signed char) *data++; if (n < 0) { @@ -2577,7 +2583,7 @@ public: advances the pointer to point to the next character. */ juce_wchar getAndAdvance() throw() { - const char byte = *data++; + const signed char byte = (signed char) *data++; if (byte >= 0) return byte; @@ -2681,6 +2687,12 @@ public: return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); } + /** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */ + size_t lengthUpTo (const CharPointer_UTF8& end) const throw() + { + return CharacterFunctions::lengthUpTo (*this, end); + } + /** Returns the number of bytes that are used to represent this string. This includes the terminating null character. */ @@ -2922,7 +2934,7 @@ public: { while (--maxBytesToRead >= 0 && *dataToTest != 0) { - const char byte = *dataToTest; + const signed char byte = (signed char) *dataToTest; if (byte < 0) { @@ -3013,16 +3025,12 @@ public: } /** This is a pointer comparison, it doesn't compare the actual text. */ - inline bool operator== (const CharPointer_UTF16& other) const throw() - { - return data == other.data; - } - - /** This is a pointer comparison, it doesn't compare the actual text. */ - inline bool operator!= (const CharPointer_UTF16& other) const throw() - { - return data == other.data; - } + inline bool operator== (const CharPointer_UTF16& other) const throw() { return data == other.data; } + inline bool operator!= (const CharPointer_UTF16& other) const throw() { return data != other.data; } + inline bool operator<= (const CharPointer_UTF16& other) const throw() { return data <= other.data; } + inline bool operator< (const CharPointer_UTF16& other) const throw() { return data < other.data; } + inline bool operator>= (const CharPointer_UTF16& other) const throw() { return data >= other.data; } + inline bool operator> (const CharPointer_UTF16& other) const throw() { return data > other.data; } /** Returns the address that this pointer is pointing to. */ inline CharType* getAddress() const throw() { return data; } @@ -3151,6 +3159,12 @@ public: return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); } + /** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */ + size_t lengthUpTo (const CharPointer_UTF16& end) const throw() + { + return CharacterFunctions::lengthUpTo (*this, end); + } + /** Returns the number of bytes that are used to represent this string. This includes the terminating null character. */ @@ -3444,16 +3458,12 @@ public: } /** This is a pointer comparison, it doesn't compare the actual text. */ - inline bool operator== (const CharPointer_UTF32& other) const throw() - { - return data == other.data; - } - - /** This is a pointer comparison, it doesn't compare the actual text. */ - inline bool operator!= (const CharPointer_UTF32& other) const throw() - { - return data == other.data; - } + inline bool operator== (const CharPointer_UTF32& other) const throw() { return data == other.data; } + inline bool operator!= (const CharPointer_UTF32& other) const throw() { return data != other.data; } + inline bool operator<= (const CharPointer_UTF32& other) const throw() { return data <= other.data; } + inline bool operator< (const CharPointer_UTF32& other) const throw() { return data < other.data; } + inline bool operator>= (const CharPointer_UTF32& other) const throw() { return data >= other.data; } + inline bool operator> (const CharPointer_UTF32& other) const throw() { return data > other.data; } /** Returns the address that this pointer is pointing to. */ inline CharType* getAddress() const throw() { return data; } @@ -3558,6 +3568,12 @@ public: return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); } + /** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */ + size_t lengthUpTo (const CharPointer_UTF32& end) const throw() + { + return CharacterFunctions::lengthUpTo (*this, end); + } + /** Returns the number of bytes that are used to represent this string. This includes the terminating null character. */ @@ -3796,16 +3812,12 @@ public: } /** This is a pointer comparison, it doesn't compare the actual text. */ - inline bool operator== (const CharPointer_ASCII& other) const throw() - { - return data == other.data; - } - - /** This is a pointer comparison, it doesn't compare the actual text. */ - inline bool operator!= (const CharPointer_ASCII& other) const throw() - { - return data == other.data; - } + inline bool operator== (const CharPointer_ASCII& other) const throw() { return data == other.data; } + inline bool operator!= (const CharPointer_ASCII& other) const throw() { return data != other.data; } + inline bool operator<= (const CharPointer_ASCII& other) const throw() { return data <= other.data; } + inline bool operator< (const CharPointer_ASCII& other) const throw() { return data < other.data; } + inline bool operator>= (const CharPointer_ASCII& other) const throw() { return data >= other.data; } + inline bool operator> (const CharPointer_ASCII& other) const throw() { return data > other.data; } /** Returns the address that this pointer is pointing to. */ inline CharType* getAddress() const throw() { return data; } @@ -3903,6 +3915,12 @@ public: return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); } + /** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */ + size_t lengthUpTo (const CharPointer_ASCII& end) const throw() + { + return CharacterFunctions::lengthUpTo (*this, end); + } + /** Returns the number of bytes that are used to represent this string. This includes the terminating null character. */ @@ -4097,7 +4115,7 @@ public: { while (--maxBytesToRead >= 0) { - if (*dataToTest <= 0) + if (((signed char) *dataToTest) <= 0) return *dataToTest == 0; ++dataToTest; @@ -4195,6 +4213,9 @@ public: /** Creates a string from a UTF-32 character string */ String (const CharPointer_UTF32& text, size_t maxChars); + /** Creates a string from a UTF-32 character string */ + String (const CharPointer_UTF32& start, const CharPointer_UTF32& end); + /** Creates a string from an ASCII character string */ String (const CharPointer_ASCII& text); @@ -4832,7 +4853,8 @@ public: /** Returns a section from the start of the string that only contains a certain set of characters. This returns the leftmost section of the string, up to (and not including) the - first character that occurs in the string passed in. + first character that occurs in the string passed in. (If none of the specified + characters are found in the string, the return value will just be the original string). */ const String initialSectionNotContaining (const String& charactersToStopAt) const; @@ -5435,7 +5457,7 @@ public: { if (--(getCounter().numObjects) < 0) { - DBG ("*** Dangling pointer deletion! Class: " << String (typeid (OwnerClass).name())); + DBG ("*** Dangling pointer deletion! Class: " << OwnerClass::getLeakedObjectClassName()); /** If you hit this, then you've managed to delete more instances of this class than you've created.. That indicates that you're deleting some dangling pointers. @@ -5463,7 +5485,7 @@ private: { if (numObjects.value > 0) { - DBG ("*** Leaked objects detected: " << numObjects.value << " instance(s) of class " << String (typeid (OwnerClass).name())); + DBG ("*** Leaked objects detected: " << numObjects.value << " instance(s) of class " << OwnerClass::getLeakedObjectClassName()); /** If you hit this, then you've leaked one or more objects of the type specified by the 'OwnerClass' template parameter - the name should have been printed by the line above. @@ -5506,7 +5528,10 @@ private: @see JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR, LeakedObjectDetector */ - #define JUCE_LEAK_DETECTOR(OwnerClass) JUCE_NAMESPACE::LeakedObjectDetector JUCE_JOIN_MACRO (leakDetector, __LINE__); + #define JUCE_LEAK_DETECTOR(OwnerClass) \ + friend class JUCE_NAMESPACE::LeakedObjectDetector; \ + static const char* getLeakedObjectClassName() throw() { return #OwnerClass; } \ + JUCE_NAMESPACE::LeakedObjectDetector JUCE_JOIN_MACRO (leakDetector, __LINE__); #else #define JUCE_LEAK_DETECTOR(OwnerClass) #endif @@ -8271,6 +8296,7 @@ public: var (const var& valueToCopy); var (int value) throw(); + var (int64 value) throw(); var (bool value) throw(); var (double value) throw(); var (const char* value); @@ -8281,6 +8307,7 @@ public: var& operator= (const var& valueToCopy); var& operator= (int value); + var& operator= (int64 value); var& operator= (bool value); var& operator= (double value); var& operator= (const char* value); @@ -8292,6 +8319,7 @@ public: void swapWith (var& other) throw(); operator int() const; + operator int64() const; operator bool() const; operator float() const; operator double() const; @@ -8301,6 +8329,7 @@ public: bool isVoid() const throw(); bool isInt() const throw(); + bool isInt64() const throw(); bool isBool() const throw(); bool isDouble() const throw(); bool isString() const throw(); @@ -8355,6 +8384,8 @@ private: friend class VariantType_Void; class VariantType_Int; friend class VariantType_Int; + class VariantType_Int64; + friend class VariantType_Int64; class VariantType_Double; friend class VariantType_Double; class VariantType_Float; @@ -8371,6 +8402,7 @@ private: union ValueUnion { int intValue; + int64 int64Value; bool boolValue; double doubleValue; String* stringValue; @@ -46106,6 +46138,8 @@ private: int typeToScan; void scanFor (AudioPluginFormat* format); + static void optionsMenuStaticCallback (int result, PluginListComponent*); + void optionsMenuCallback (int result); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginListComponent); }; @@ -56483,6 +56517,7 @@ public: /** Destructor. */ ~FileChooserDialogBox(); + #if JUCE_MODAL_LOOPS_PERMITTED /** Displays and runs the dialog box modally. This will show the box with the specified size, returning true if the user @@ -56500,6 +56535,7 @@ public: Leave the width or height as 0 to use the default size. */ bool showAt (int x, int y, int width, int height); + #endif /** Sets the size of this dialog box to its default and positions it either in the centre of the screen, or centred around a component that is provided. diff --git a/src/containers/juce_Variant.cpp b/src/containers/juce_Variant.cpp index ce5753ada2..be0d13a97f 100644 --- a/src/containers/juce_Variant.cpp +++ b/src/containers/juce_Variant.cpp @@ -185,7 +185,7 @@ public: void writeToStream (const ValueUnion& data, OutputStream& output) const { output.writeCompressedInt (1); - output.writeByte (data.boolValue ? varMarker_BoolTrue : varMarker_BoolFalse); + output.writeByte (data.boolValue ? (char) varMarker_BoolTrue : (char) varMarker_BoolFalse); } }; @@ -310,7 +310,7 @@ var::var (const int value_) throw() : type (&VariantType_Int::instance) var::var (const int64 value_) throw() : type (&VariantType_Int64::instance) { - value.intValue = value_; + value.int64Value = value_; } var::var (const bool value_) throw() : type (&VariantType_Bool::instance)