| @@ -279,6 +279,27 @@ DynamicObject* var::getObject() const throw() | |||||
| return type == objectType ? value.objectValue : 0; | return type == objectType ? value.objectValue : 0; | ||||
| } | } | ||||
| bool var::operator== (const var& other) const throw() | |||||
| { | |||||
| switch (type) | |||||
| { | |||||
| case voidType: return other.isVoid(); | |||||
| case intType: return value.intValue == (int) other; | |||||
| case boolType: return value.boolValue == (bool) other; | |||||
| case doubleType: return value.doubleValue == (double) other; | |||||
| case stringType: return (*(value.stringValue)) == other.toString(); | |||||
| case objectType: return value.objectValue == other.getObject(); | |||||
| default: jassertfalse; break; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| bool var::operator!= (const var& other) const throw() | |||||
| { | |||||
| return ! operator== (other); | |||||
| } | |||||
| const var var::operator[] (const var::identifier& propertyName) const throw() | const var var::operator[] (const var::identifier& propertyName) const throw() | ||||
| { | { | ||||
| if (type == objectType && value.objectValue != 0) | if (type == objectType && value.objectValue != 0) | ||||
| @@ -91,6 +91,9 @@ public: | |||||
| bool isObject() const throw() { return type == objectType; } | bool isObject() const throw() { return type == objectType; } | ||||
| bool isMethod() const throw() { return type == methodType; } | bool isMethod() const throw() { return type == methodType; } | ||||
| bool operator== (const var& other) const throw(); | |||||
| bool operator!= (const var& other) const throw(); | |||||
| //============================================================================== | //============================================================================== | ||||
| class JUCE_API identifier | class JUCE_API identifier | ||||
| { | { | ||||
| @@ -46,14 +46,14 @@ namespace CppTokeniser | |||||
| static bool isIdentifierStart (const tchar c) throw() | static bool isIdentifierStart (const tchar c) throw() | ||||
| { | { | ||||
| return CharacterFunctions::isLetter (c) | return CharacterFunctions::isLetter (c) | ||||
| || c == T('_'); | |||||
| || c == T('_') || c == T('@'); | |||||
| } | } | ||||
| static bool isIdentifierBody (const tchar c) throw() | static bool isIdentifierBody (const tchar c) throw() | ||||
| { | { | ||||
| return CharacterFunctions::isLetter (c) | return CharacterFunctions::isLetter (c) | ||||
| || CharacterFunctions::isDigit (c) | || CharacterFunctions::isDigit (c) | ||||
| || c == T('_'); | |||||
| || c == T('_') || c == T('@'); | |||||
| } | } | ||||
| static int parseIdentifier (CodeDocument::Iterator& source) throw() | static int parseIdentifier (CodeDocument::Iterator& source) throw() | ||||
| @@ -80,7 +80,9 @@ static int parseIdentifier (CodeDocument::Iterator& source) throw() | |||||
| static const tchar* keywordsOther[] = | static const tchar* keywordsOther[] = | ||||
| { T("const_cast"), T("continue"), T("default"), T("explicit"), T("mutable"), T("namespace"), | { T("const_cast"), T("continue"), T("default"), T("explicit"), T("mutable"), T("namespace"), | ||||
| T("operator"), T("private"), T("protected"), T("register"), T("reinterpret_cast"), T("static_cast"), | T("operator"), T("private"), T("protected"), T("register"), T("reinterpret_cast"), T("static_cast"), | ||||
| T("template"), T("typedef"), T("typename"), T("unsigned"), T("virtual"), T("volatile"), 0 }; | |||||
| T("template"), T("typedef"), T("typename"), T("unsigned"), T("virtual"), T("volatile"), | |||||
| T("@implementation"), T("@interface"), T("@end"), T("@synthesize"), T("@dynamic"), T("@public"), | |||||
| T("@private"), T("@property"), T("@protected"), T("@class"), 0 }; | |||||
| int tokenLength = 0; | int tokenLength = 0; | ||||
| tchar possibleIdentifier [19]; | tchar possibleIdentifier [19]; | ||||
| @@ -58,22 +58,27 @@ FileChooser::~FileChooser() | |||||
| bool FileChooser::browseForFileToOpen (FilePreviewComponent* previewComponent) | bool FileChooser::browseForFileToOpen (FilePreviewComponent* previewComponent) | ||||
| { | { | ||||
| return showDialog (false, false, false, false, previewComponent); | |||||
| return showDialog (false, true, false, false, false, previewComponent); | |||||
| } | } | ||||
| bool FileChooser::browseForMultipleFilesToOpen (FilePreviewComponent* previewComponent) | bool FileChooser::browseForMultipleFilesToOpen (FilePreviewComponent* previewComponent) | ||||
| { | { | ||||
| return showDialog (false, false, false, true, previewComponent); | |||||
| return showDialog (false, true, false, false, true, previewComponent); | |||||
| } | |||||
| bool FileChooser::browseForMultipleFilesOrDirectories (FilePreviewComponent* previewComponent) | |||||
| { | |||||
| return showDialog (true, true, false, false, true, previewComponent); | |||||
| } | } | ||||
| bool FileChooser::browseForFileToSave (const bool warnAboutOverwritingExistingFiles) | bool FileChooser::browseForFileToSave (const bool warnAboutOverwritingExistingFiles) | ||||
| { | { | ||||
| return showDialog (false, true, warnAboutOverwritingExistingFiles, false, 0); | |||||
| return showDialog (false, true, true, warnAboutOverwritingExistingFiles, false, 0); | |||||
| } | } | ||||
| bool FileChooser::browseForDirectory() | bool FileChooser::browseForDirectory() | ||||
| { | { | ||||
| return showDialog (true, false, false, false, 0); | |||||
| return showDialog (true, false, false, false, false, 0); | |||||
| } | } | ||||
| const File FileChooser::getResult() const | const File FileChooser::getResult() const | ||||
| @@ -95,7 +100,8 @@ const OwnedArray <File>& FileChooser::getResults() const | |||||
| return results; | return results; | ||||
| } | } | ||||
| bool FileChooser::showDialog (const bool isDirectory, | |||||
| bool FileChooser::showDialog (const bool selectsDirectories, | |||||
| const bool selectsFiles, | |||||
| const bool isSave, | const bool isSave, | ||||
| const bool warnAboutOverwritingExistingFiles, | const bool warnAboutOverwritingExistingFiles, | ||||
| const bool selectMultipleFiles, | const bool selectMultipleFiles, | ||||
| @@ -120,7 +126,7 @@ bool FileChooser::showDialog (const bool isDirectory, | |||||
| #endif | #endif | ||||
| { | { | ||||
| showPlatformDialog (results, title, startingFile, filters, | showPlatformDialog (results, title, startingFile, filters, | ||||
| isDirectory, isSave, | |||||
| selectsDirectories, selectsFiles, isSave, | |||||
| warnAboutOverwritingExistingFiles, | warnAboutOverwritingExistingFiles, | ||||
| selectMultipleFiles, | selectMultipleFiles, | ||||
| previewComponent); | previewComponent); | ||||
| @@ -131,9 +137,9 @@ bool FileChooser::showDialog (const bool isDirectory, | |||||
| WildcardFileFilter wildcard (filters, String::empty); | WildcardFileFilter wildcard (filters, String::empty); | ||||
| FileBrowserComponent browserComponent (isDirectory ? FileBrowserComponent::chooseDirectoryMode | |||||
| : (isSave ? FileBrowserComponent::saveFileMode | |||||
| : FileBrowserComponent::loadFileMode), | |||||
| FileBrowserComponent browserComponent (selectsDirectories ? FileBrowserComponent::chooseDirectoryMode | |||||
| : (isSave ? FileBrowserComponent::saveFileMode | |||||
| : FileBrowserComponent::loadFileMode), | |||||
| startingFile, &wildcard, previewComponent); | startingFile, &wildcard, previewComponent); | ||||
| FileChooserDialogBox box (title, String::empty, | FileChooserDialogBox box (title, String::empty, | ||||
| @@ -136,6 +136,13 @@ public: | |||||
| */ | */ | ||||
| bool browseForDirectory(); | bool browseForDirectory(); | ||||
| /** Same as browseForFileToOpen, but allows the user to select multiple files and directories. | |||||
| The files that are returned can be obtained by calling getResults(). See | |||||
| browseForFileToOpen() for more info about the behaviour of this method. | |||||
| */ | |||||
| bool browseForMultipleFilesOrDirectories (FilePreviewComponent* previewComponent = 0); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns the last file that was chosen by one of the browseFor methods. | /** Returns the last file that was chosen by one of the browseFor methods. | ||||
| @@ -171,7 +178,8 @@ private: | |||||
| OwnedArray <File> results; | OwnedArray <File> results; | ||||
| bool useNativeDialogBox; | bool useNativeDialogBox; | ||||
| bool showDialog (const bool isDirectory, | |||||
| bool showDialog (const bool selectsDirectories, | |||||
| const bool selectsFiles, | |||||
| const bool isSave, | const bool isSave, | ||||
| const bool warnAboutOverwritingExistingFiles, | const bool warnAboutOverwritingExistingFiles, | ||||
| const bool selectMultipleFiles, | const bool selectMultipleFiles, | ||||
| @@ -181,7 +189,8 @@ private: | |||||
| const String& title, | const String& title, | ||||
| const File& file, | const File& file, | ||||
| const String& filters, | const String& filters, | ||||
| bool isDirectory, | |||||
| bool selectsDirectories, | |||||
| bool selectsFiles, | |||||
| bool isSave, | bool isSave, | ||||
| bool warnAboutOverwritingExistingFiles, | bool warnAboutOverwritingExistingFiles, | ||||
| bool selectMultipleFiles, | bool selectMultipleFiles, | ||||
| @@ -729,9 +729,16 @@ public: | |||||
| default viewer application. | default viewer application. | ||||
| - if it's a folder, it will be opened in Explorer, Finder, or equivalent. | - if it's a folder, it will be opened in Explorer, Finder, or equivalent. | ||||
| @see revealToUser | |||||
| */ | */ | ||||
| bool startAsProcess (const String& parameters = String::empty) const throw(); | bool startAsProcess (const String& parameters = String::empty) const throw(); | ||||
| /** Opens Finder, Explorer, or whatever the OS uses, to show the user this file's location. | |||||
| @see startAsProcess | |||||
| */ | |||||
| void revealToUser() const throw(); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** A set of types of location that can be passed to the getSpecialLocation() method. | /** A set of types of location that can be passed to the getSpecialLocation() method. | ||||
| */ | */ | ||||
| @@ -25,7 +25,7 @@ | |||||
| // (This file gets included by juce_linux_NativeCode.cpp, rather than being | // (This file gets included by juce_linux_NativeCode.cpp, rather than being | ||||
| // compiled on its own). | // compiled on its own). | ||||
| #if JUCE_INCLUDED_FILE | |||||
| #if JUCE_INCLUDED_FILE && JUCE_USE_CDREADER | |||||
| //============================================================================== | //============================================================================== | ||||
| @@ -33,6 +33,7 @@ void FileChooser::showPlatformDialog (OwnedArray<File>& results, | |||||
| const File& file, | const File& file, | ||||
| const String& filters, | const String& filters, | ||||
| bool isDirectory, | bool isDirectory, | ||||
| bool selectsFiles, | |||||
| bool isSave, | bool isSave, | ||||
| bool warnAboutOverwritingExistingFiles, | bool warnAboutOverwritingExistingFiles, | ||||
| bool selectMultipleFiles, | bool selectMultipleFiles, | ||||
| @@ -417,10 +417,11 @@ bool juce_launchFile (const String& fileName, | |||||
| cmdString << " " << parameters; | cmdString << " " << parameters; | ||||
| if (URL::isProbablyAWebsiteURL (fileName) | if (URL::isProbablyAWebsiteURL (fileName) | ||||
| || cmdString.startsWithIgnoreCase (T("file:")) | |||||
| || URL::isProbablyAnEmailAddress (fileName)) | || URL::isProbablyAnEmailAddress (fileName)) | ||||
| { | { | ||||
| // create a command that tries to launch a bunch of likely browsers | // create a command that tries to launch a bunch of likely browsers | ||||
| const char* const browserNames[] = { "/etc/alternatives/x-www-browser", "firefox", "mozilla", "konqueror", "opera" }; | |||||
| const char* const browserNames[] = { "xdg-open", "/etc/alternatives/x-www-browser", "firefox", "mozilla", "konqueror", "opera" }; | |||||
| StringArray cmdLines; | StringArray cmdLines; | ||||
| @@ -430,9 +431,6 @@ bool juce_launchFile (const String& fileName, | |||||
| cmdString = cmdLines.joinIntoString (T(" || ")); | cmdString = cmdLines.joinIntoString (T(" || ")); | ||||
| } | } | ||||
| if (cmdString.startsWithIgnoreCase (T("file:"))) | |||||
| cmdString = cmdString.substring (5); | |||||
| const char* const argv[4] = { "/bin/sh", "-c", (const char*) cmdString.toUTF8(), 0 }; | const char* const argv[4] = { "/bin/sh", "-c", (const char*) cmdString.toUTF8(), 0 }; | ||||
| const int cpid = fork(); | const int cpid = fork(); | ||||
| @@ -449,4 +447,13 @@ bool juce_launchFile (const String& fileName, | |||||
| return cpid >= 0; | return cpid >= 0; | ||||
| } | } | ||||
| void File::revealToUser() const throw() | |||||
| { | |||||
| if (isDirectory()) | |||||
| startAsProcess(); | |||||
| else if (getParentDirectory().exists()) | |||||
| getParentDirectory().startAsProcess(); | |||||
| } | |||||
| #endif | #endif | ||||
| @@ -172,18 +172,27 @@ public: | |||||
| bool clipToRectangleList (const RectangleList& clipRegion) | bool clipToRectangleList (const RectangleList& clipRegion) | ||||
| { | { | ||||
| const int numRects = clipRegion.getNumRectangles(); | |||||
| CGRect* const rects = new CGRect [numRects]; | |||||
| for (int i = 0; i < numRects; ++i) | |||||
| if (clipRegion.isEmpty()) | |||||
| { | { | ||||
| const Rectangle& r = clipRegion.getRectangle(i); | |||||
| rects[i] = CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()); | |||||
| CGContextClipToRect (context, CGRectMake (0, 0, 0, 0)); | |||||
| return false; | |||||
| } | } | ||||
| else | |||||
| { | |||||
| const int numRects = clipRegion.getNumRectangles(); | |||||
| CGContextClipToRects (context, rects, numRects); | |||||
| delete[] rects; | |||||
| CGRect* const rects = new CGRect [numRects]; | |||||
| for (int i = 0; i < numRects; ++i) | |||||
| { | |||||
| const Rectangle& r = clipRegion.getRectangle(i); | |||||
| rects[i] = CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()); | |||||
| } | |||||
| return ! isClipEmpty(); | |||||
| CGContextClipToRects (context, rects, numRects); | |||||
| delete[] rects; | |||||
| return ! isClipEmpty(); | |||||
| } | |||||
| } | } | ||||
| void excludeClipRectangle (const Rectangle& r) | void excludeClipRectangle (const Rectangle& r) | ||||
| @@ -84,6 +84,7 @@ void FileChooser::showPlatformDialog (OwnedArray<File>& results, | |||||
| const File& currentFileOrDirectory, | const File& currentFileOrDirectory, | ||||
| const String& filter, | const String& filter, | ||||
| bool selectsDirectory, | bool selectsDirectory, | ||||
| bool selectsFiles, | |||||
| bool isSaveDialogue, | bool isSaveDialogue, | ||||
| bool warnAboutOverwritingExistingFiles, | bool warnAboutOverwritingExistingFiles, | ||||
| bool selectMultipleFiles, | bool selectMultipleFiles, | ||||
| @@ -108,7 +109,7 @@ void FileChooser::showPlatformDialog (OwnedArray<File>& results, | |||||
| { | { | ||||
| NSOpenPanel* openPanel = (NSOpenPanel*) panel; | NSOpenPanel* openPanel = (NSOpenPanel*) panel; | ||||
| [openPanel setCanChooseDirectories: selectsDirectory]; | [openPanel setCanChooseDirectories: selectsDirectory]; | ||||
| [openPanel setCanChooseFiles: ! selectsDirectory]; | |||||
| [openPanel setCanChooseFiles: selectsFiles]; | |||||
| [openPanel setAllowsMultipleSelection: selectMultipleFiles]; | [openPanel setAllowsMultipleSelection: selectMultipleFiles]; | ||||
| } | } | ||||
| @@ -157,6 +158,7 @@ void FileChooser::showPlatformDialog (OwnedArray<File>& results, | |||||
| const File& currentFileOrDirectory, | const File& currentFileOrDirectory, | ||||
| const String& filter, | const String& filter, | ||||
| bool selectsDirectory, | bool selectsDirectory, | ||||
| bool selectsFiles, | |||||
| bool isSaveDialogue, | bool isSaveDialogue, | ||||
| bool warnAboutOverwritingExistingFiles, | bool warnAboutOverwritingExistingFiles, | ||||
| bool selectMultipleFiles, | bool selectMultipleFiles, | ||||
| @@ -497,6 +497,16 @@ bool juce_launchFile (const String& fileName, | |||||
| #endif | #endif | ||||
| } | } | ||||
| void File::revealToUser() const throw() | |||||
| { | |||||
| #if ! JUCE_IPHONE | |||||
| if (exists()) | |||||
| [[NSWorkspace sharedWorkspace] selectFile: juceStringToNS (getFullPathName()) inFileViewerRootedAtPath: @""]; | |||||
| else if (getParentDirectory().exists()) | |||||
| getParentDirectory().revealToUser(); | |||||
| #endif | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| #if ! JUCE_IPHONE | #if ! JUCE_IPHONE | ||||
| bool PlatformUtilities::makeFSRefFromPath (FSRef* destFSRef, const String& path) | bool PlatformUtilities::makeFSRefFromPath (FSRef* destFSRef, const String& path) | ||||
| @@ -148,6 +148,7 @@ void FileChooser::showPlatformDialog (OwnedArray<File>& results, | |||||
| const File& currentFileOrDirectory, | const File& currentFileOrDirectory, | ||||
| const String& filter, | const String& filter, | ||||
| bool selectsDirectory, | bool selectsDirectory, | ||||
| bool selectsFiles, | |||||
| bool isSaveDialogue, | bool isSaveDialogue, | ||||
| bool warnAboutOverwritingExistingFiles, | bool warnAboutOverwritingExistingFiles, | ||||
| bool selectMultipleFiles, | bool selectMultipleFiles, | ||||
| @@ -677,6 +677,14 @@ bool juce_launchFile (const String& fileName, | |||||
| return hInstance > (HINSTANCE) 32; | return hInstance > (HINSTANCE) 32; | ||||
| } | } | ||||
| void File::revealToUser() const throw() | |||||
| { | |||||
| if (isDirectory()) | |||||
| startAsProcess(); | |||||
| else if (getParentDirectory().exists()) | |||||
| getParentDirectory().startAsProcess(); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| struct NamedPipeInternal | struct NamedPipeInternal | ||||
| { | { | ||||
| @@ -1110,7 +1110,7 @@ const String XmlElement::getText() const throw() | |||||
| { | { | ||||
| jassert (isTextElement()); // you're trying to get the text from an element that | jassert (isTextElement()); // you're trying to get the text from an element that | ||||
| // isn't actually a text element.. If this contains text sub-nodes, you | // isn't actually a text element.. If this contains text sub-nodes, you | ||||
| // can use getAllSubText instead to | |||||
| // probably want to use getAllSubText instead. | |||||
| return getStringAttribute (juce_xmltextContentAttributeName); | return getStringAttribute (juce_xmltextContentAttributeName); | ||||
| } | } | ||||