| @@ -279,6 +279,27 @@ DynamicObject* var::getObject() const throw() | |||
| 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() | |||
| { | |||
| if (type == objectType && value.objectValue != 0) | |||
| @@ -91,6 +91,9 @@ public: | |||
| bool isObject() const throw() { return type == objectType; } | |||
| 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 | |||
| { | |||
| @@ -46,14 +46,14 @@ namespace CppTokeniser | |||
| static bool isIdentifierStart (const tchar c) throw() | |||
| { | |||
| return CharacterFunctions::isLetter (c) | |||
| || c == T('_'); | |||
| || c == T('_') || c == T('@'); | |||
| } | |||
| static bool isIdentifierBody (const tchar c) throw() | |||
| { | |||
| return CharacterFunctions::isLetter (c) | |||
| || CharacterFunctions::isDigit (c) | |||
| || c == T('_'); | |||
| || c == T('_') || c == T('@'); | |||
| } | |||
| static int parseIdentifier (CodeDocument::Iterator& source) throw() | |||
| @@ -80,7 +80,9 @@ static int parseIdentifier (CodeDocument::Iterator& source) throw() | |||
| static const tchar* keywordsOther[] = | |||
| { 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("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; | |||
| tchar possibleIdentifier [19]; | |||
| @@ -58,22 +58,27 @@ FileChooser::~FileChooser() | |||
| 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) | |||
| { | |||
| 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) | |||
| { | |||
| return showDialog (false, true, warnAboutOverwritingExistingFiles, false, 0); | |||
| return showDialog (false, true, true, warnAboutOverwritingExistingFiles, false, 0); | |||
| } | |||
| bool FileChooser::browseForDirectory() | |||
| { | |||
| return showDialog (true, false, false, false, 0); | |||
| return showDialog (true, false, false, false, false, 0); | |||
| } | |||
| const File FileChooser::getResult() const | |||
| @@ -95,7 +100,8 @@ const OwnedArray <File>& FileChooser::getResults() const | |||
| return results; | |||
| } | |||
| bool FileChooser::showDialog (const bool isDirectory, | |||
| bool FileChooser::showDialog (const bool selectsDirectories, | |||
| const bool selectsFiles, | |||
| const bool isSave, | |||
| const bool warnAboutOverwritingExistingFiles, | |||
| const bool selectMultipleFiles, | |||
| @@ -120,7 +126,7 @@ bool FileChooser::showDialog (const bool isDirectory, | |||
| #endif | |||
| { | |||
| showPlatformDialog (results, title, startingFile, filters, | |||
| isDirectory, isSave, | |||
| selectsDirectories, selectsFiles, isSave, | |||
| warnAboutOverwritingExistingFiles, | |||
| selectMultipleFiles, | |||
| previewComponent); | |||
| @@ -131,9 +137,9 @@ bool FileChooser::showDialog (const bool isDirectory, | |||
| 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); | |||
| FileChooserDialogBox box (title, String::empty, | |||
| @@ -136,6 +136,13 @@ public: | |||
| */ | |||
| 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. | |||
| @@ -171,7 +178,8 @@ private: | |||
| OwnedArray <File> results; | |||
| bool useNativeDialogBox; | |||
| bool showDialog (const bool isDirectory, | |||
| bool showDialog (const bool selectsDirectories, | |||
| const bool selectsFiles, | |||
| const bool isSave, | |||
| const bool warnAboutOverwritingExistingFiles, | |||
| const bool selectMultipleFiles, | |||
| @@ -181,7 +189,8 @@ private: | |||
| const String& title, | |||
| const File& file, | |||
| const String& filters, | |||
| bool isDirectory, | |||
| bool selectsDirectories, | |||
| bool selectsFiles, | |||
| bool isSave, | |||
| bool warnAboutOverwritingExistingFiles, | |||
| bool selectMultipleFiles, | |||
| @@ -729,9 +729,16 @@ public: | |||
| default viewer application. | |||
| - 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(); | |||
| /** 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. | |||
| */ | |||
| @@ -25,7 +25,7 @@ | |||
| // (This file gets included by juce_linux_NativeCode.cpp, rather than being | |||
| // 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 String& filters, | |||
| bool isDirectory, | |||
| bool selectsFiles, | |||
| bool isSave, | |||
| bool warnAboutOverwritingExistingFiles, | |||
| bool selectMultipleFiles, | |||
| @@ -417,10 +417,11 @@ bool juce_launchFile (const String& fileName, | |||
| cmdString << " " << parameters; | |||
| if (URL::isProbablyAWebsiteURL (fileName) | |||
| || cmdString.startsWithIgnoreCase (T("file:")) | |||
| || URL::isProbablyAnEmailAddress (fileName)) | |||
| { | |||
| // 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; | |||
| @@ -430,9 +431,6 @@ bool juce_launchFile (const String& fileName, | |||
| 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 int cpid = fork(); | |||
| @@ -449,4 +447,13 @@ bool juce_launchFile (const String& fileName, | |||
| return cpid >= 0; | |||
| } | |||
| void File::revealToUser() const throw() | |||
| { | |||
| if (isDirectory()) | |||
| startAsProcess(); | |||
| else if (getParentDirectory().exists()) | |||
| getParentDirectory().startAsProcess(); | |||
| } | |||
| #endif | |||
| @@ -172,18 +172,27 @@ public: | |||
| 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) | |||
| @@ -84,6 +84,7 @@ void FileChooser::showPlatformDialog (OwnedArray<File>& results, | |||
| const File& currentFileOrDirectory, | |||
| const String& filter, | |||
| bool selectsDirectory, | |||
| bool selectsFiles, | |||
| bool isSaveDialogue, | |||
| bool warnAboutOverwritingExistingFiles, | |||
| bool selectMultipleFiles, | |||
| @@ -108,7 +109,7 @@ void FileChooser::showPlatformDialog (OwnedArray<File>& results, | |||
| { | |||
| NSOpenPanel* openPanel = (NSOpenPanel*) panel; | |||
| [openPanel setCanChooseDirectories: selectsDirectory]; | |||
| [openPanel setCanChooseFiles: ! selectsDirectory]; | |||
| [openPanel setCanChooseFiles: selectsFiles]; | |||
| [openPanel setAllowsMultipleSelection: selectMultipleFiles]; | |||
| } | |||
| @@ -157,6 +158,7 @@ void FileChooser::showPlatformDialog (OwnedArray<File>& results, | |||
| const File& currentFileOrDirectory, | |||
| const String& filter, | |||
| bool selectsDirectory, | |||
| bool selectsFiles, | |||
| bool isSaveDialogue, | |||
| bool warnAboutOverwritingExistingFiles, | |||
| bool selectMultipleFiles, | |||
| @@ -497,6 +497,16 @@ bool juce_launchFile (const String& fileName, | |||
| #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 | |||
| bool PlatformUtilities::makeFSRefFromPath (FSRef* destFSRef, const String& path) | |||
| @@ -148,6 +148,7 @@ void FileChooser::showPlatformDialog (OwnedArray<File>& results, | |||
| const File& currentFileOrDirectory, | |||
| const String& filter, | |||
| bool selectsDirectory, | |||
| bool selectsFiles, | |||
| bool isSaveDialogue, | |||
| bool warnAboutOverwritingExistingFiles, | |||
| bool selectMultipleFiles, | |||
| @@ -677,6 +677,14 @@ bool juce_launchFile (const String& fileName, | |||
| return hInstance > (HINSTANCE) 32; | |||
| } | |||
| void File::revealToUser() const throw() | |||
| { | |||
| if (isDirectory()) | |||
| startAsProcess(); | |||
| else if (getParentDirectory().exists()) | |||
| getParentDirectory().startAsProcess(); | |||
| } | |||
| //============================================================================== | |||
| 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 | |||
| // 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); | |||
| } | |||