| @@ -256,8 +256,7 @@ public: | |||
| void clicked() | |||
| { | |||
| // create two colour selector components for our background and | |||
| // text colour.. | |||
| #if JUCE_MODAL_LOOPS_PERMITTED | |||
| ColourSelector colourSelector; | |||
| colourSelector.setName ("background"); | |||
| colourSelector.setCurrentColour (findColour (TextButton::buttonColourId)); | |||
| @@ -267,6 +266,7 @@ public: | |||
| CallOutBox callOut (colourSelector, *this, 0); | |||
| callOut.runModalLoop(); | |||
| #endif | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster* source) | |||
| @@ -703,10 +703,6 @@ public: | |||
| customiseButton.setTopLeftPosition (orientationButton.getRight() + 20, orientationButton.getY()); | |||
| } | |||
| ~ToolbarDemoComp() | |||
| { | |||
| } | |||
| void resized() | |||
| { | |||
| if (toolbar.isVertical()) | |||
| @@ -925,10 +921,6 @@ public: | |||
| addTab ("misc widgets", getRandomBrightColour(), createMiscPage(), true); | |||
| } | |||
| ~DemoTabbedComponent() | |||
| { | |||
| } | |||
| void buttonClicked (Button* button) | |||
| { | |||
| BubbleMessageComponent* bmc = new BubbleMessageComponent(); | |||
| @@ -966,10 +958,6 @@ public: | |||
| setStatusMessage ("Getting ready..."); | |||
| } | |||
| ~DemoBackgroundThread() | |||
| { | |||
| } | |||
| void run() | |||
| { | |||
| setProgress (-1.0); // setting a value beyond the range 0 -> 1 will show a spinning bar.. | |||
| @@ -1119,10 +1107,6 @@ public: | |||
| transformSlider.addListener (this); | |||
| } | |||
| ~WidgetsDemo() | |||
| { | |||
| } | |||
| void resized() | |||
| { | |||
| tabs.setBounds (10, 40, getWidth() - 20, getHeight() - 50); | |||
| @@ -1220,6 +1204,13 @@ public: | |||
| demoComponent->performDemoMenuItem (result); | |||
| } | |||
| static void alertBoxResultChosen (int result, WidgetsDemo* demoComponent) | |||
| { | |||
| AlertWindow::showMessageBoxAsync (AlertWindow::InfoIcon, | |||
| "Alert Box", | |||
| "Result code: " + String (result)); | |||
| } | |||
| void performDemoMenuItem (int result) | |||
| { | |||
| if (result >= 100 && result < 105) | |||
| @@ -1240,15 +1231,17 @@ public: | |||
| } | |||
| else if (result == 110) | |||
| { | |||
| bool userPickedOk | |||
| = AlertWindow::showOkCancelBox (AlertWindow::QuestionIcon, | |||
| "This is an ok/cancel AlertWindow", | |||
| "And this is the AlertWindow's message. Blah blah blah blah blah blah blah blah blah blah blah blah blah."); | |||
| (void) userPickedOk; // (just avoids a compiler warning about unused variables) | |||
| AlertWindow::showOkCancelBox (AlertWindow::QuestionIcon, | |||
| "This is an ok/cancel AlertWindow", | |||
| "And this is the AlertWindow's message. Blah blah blah blah blah blah blah blah blah blah blah blah blah.", | |||
| String::empty, | |||
| String::empty, | |||
| 0, | |||
| ModalCallbackFunction::forComponent (alertBoxResultChosen, this)); | |||
| } | |||
| else if (result == 111) | |||
| { | |||
| #if JUCE_MODAL_LOOPS_PERMITTED | |||
| AlertWindow w ("AlertWindow demo..", | |||
| "This AlertWindow has a couple of extra components added to show how to add drop-down lists and text entry boxes.", | |||
| AlertWindow::QuestionIcon); | |||
| @@ -1276,11 +1269,13 @@ public: | |||
| String text = w.getTextEditorContents ("text"); | |||
| } | |||
| #endif | |||
| } | |||
| else if (result == 112) | |||
| { | |||
| DemoBackgroundThread demoThread; | |||
| #if JUCE_MODAL_LOOPS_PERMITTED | |||
| if (demoThread.runThread()) | |||
| { | |||
| // thread finished normally.. | |||
| @@ -1295,24 +1290,28 @@ public: | |||
| "Progress window", | |||
| "You pressed cancel!"); | |||
| } | |||
| #endif | |||
| } | |||
| else if (result == 120) | |||
| { | |||
| #if JUCE_MODAL_LOOPS_PERMITTED | |||
| ColourSelectorDialogWindow colourDialog; | |||
| // this will run an event loop until the dialog's closeButtonPressed() | |||
| // method causes the loop to exit. | |||
| colourDialog.runModalLoop(); | |||
| #endif | |||
| } | |||
| else if (result == 140) | |||
| { | |||
| #if JUCE_MAC | |||
| #if JUCE_MAC | |||
| AppleRemoteTestWindow test; | |||
| test.runModalLoop(); | |||
| #endif | |||
| #endif | |||
| } | |||
| else if (result >= 121 && result < 139) | |||
| { | |||
| #if JUCE_MODAL_LOOPS_PERMITTED | |||
| const bool useNativeVersion = result < 130; | |||
| if (result > 130) | |||
| result -= 10; | |||
| @@ -1388,6 +1387,7 @@ public: | |||
| "You picked: " + chosenDirectory.getFullPathName()); | |||
| } | |||
| } | |||
| #endif | |||
| } | |||
| else if (result == 1001) | |||
| { | |||
| @@ -40,7 +40,7 @@ MainWindow::MainWindow() | |||
| DocumentWindow::allButtons) | |||
| { | |||
| setUsingNativeTitleBar (true); | |||
| setContentComponent (new ProjectContentComponent()); | |||
| setContentOwned (new ProjectContentComponent(), false); | |||
| #if ! JUCE_MAC | |||
| JucerApplication* app = static_cast<JucerApplication*> (JUCEApplication::getInstance()); | |||
| @@ -91,7 +91,7 @@ MainWindow::~MainWindow() | |||
| StoredSettings::getInstance()->getProps() | |||
| .setValue ("lastMainWindowPos", getWindowStateAsString()); | |||
| setContentComponent (0); | |||
| clearContentComponent(); | |||
| currentProject = 0; | |||
| } | |||
| @@ -112,7 +112,8 @@ public: | |||
| writeXmlOrThrow (*manifest, target.getChildFile ("AndroidManifest.xml"), "utf-8", 100); | |||
| } | |||
| writeJNIMakefile (jniFolder.getChildFile ("Android.mk")); | |||
| writeApplicationMk (jniFolder.getChildFile ("Application.mk")); | |||
| writeAndroidMk (jniFolder.getChildFile ("Android.mk")); | |||
| { | |||
| ScopedPointer<XmlElement> antBuildXml (createAntBuildXML()); | |||
| @@ -178,7 +179,20 @@ private: | |||
| } | |||
| } | |||
| void writeJNIMakefile (const File& file) | |||
| void writeApplicationMk (const File& file) | |||
| { | |||
| MemoryOutputStream mo; | |||
| mo << "# Automatically generated makefile, created by the Jucer" << newLine | |||
| << "# Don't edit this file! Your changes will be overwritten when you re-save the Jucer project!" << newLine | |||
| << newLine | |||
| << "APP_STL := stlport_static" << newLine | |||
| << "APP_CPPFLAGS += -fsigned-char -fexceptions -frtti" << newLine; | |||
| overwriteFileIfDifferentOrThrow (file, mo); | |||
| } | |||
| void writeAndroidMk (const File& file) | |||
| { | |||
| Array<RelativePath> files; | |||
| findAllFilesToCompile (project.getMainGroup(), files); | |||
| @@ -188,12 +202,12 @@ private: | |||
| files.add (juceWrapperFiles.getReference(i)); | |||
| MemoryOutputStream mo; | |||
| writeJNIMakefile (mo, files); | |||
| writeAndroidMk (mo, files); | |||
| overwriteFileIfDifferentOrThrow (file, mo); | |||
| } | |||
| void writeJNIMakefile (OutputStream& out, const Array<RelativePath>& files) | |||
| void writeAndroidMk (OutputStream& out, const Array<RelativePath>& files) | |||
| { | |||
| out << "# Automatically generated makefile, created by the Jucer" << newLine | |||
| << "# Don't edit this file! Your changes will be overwritten when you re-save the Jucer project!" << newLine | |||
| @@ -209,20 +223,23 @@ private: | |||
| for (int i = 0; i < files.size(); ++i) | |||
| out << " ../" << escapeSpaces (files.getReference(i).toUnixStyle()) << "\\" << newLine; | |||
| String cFlags ("-fsigned-char"); | |||
| out << newLine | |||
| << "ifeq ($(CONFIG),Debug)" << newLine | |||
| << " LOCAL_CFLAGS += -g " << cFlags << createPreprocessorDefs (true) << newLine | |||
| << " LOCAL_CPPFLAGS += " << createCPPFlags (true) << newLine | |||
| << "else" << newLine | |||
| << " LOCAL_CFLAGS += " << cFlags << createPreprocessorDefs (false) << newLine | |||
| << " LOCAL_CPPFLAGS += " << createCPPFlags (false) << newLine | |||
| << "endif" << newLine | |||
| << newLine | |||
| << "include $(BUILD_SHARED_LIBRARY)" << newLine; | |||
| } | |||
| const String createPreprocessorDefs (bool forDebug) | |||
| const String createCPPFlags (bool forDebug) | |||
| { | |||
| String flags ("-fsigned-char -fexceptions -frtti"); | |||
| if (forDebug) | |||
| flags << " -g"; | |||
| StringPairArray defines; | |||
| defines.set ("JUCE_ANDROID", "1"); | |||
| @@ -242,12 +259,14 @@ private: | |||
| if (config.isDebug() == forDebug) | |||
| { | |||
| flags << " -O" << config.getGCCOptimisationFlag(); | |||
| defines = mergePreprocessorDefs (defines, getAllPreprocessorDefs (config)); | |||
| break; | |||
| } | |||
| } | |||
| return createGCCPreprocessorFlags (defines); | |||
| return flags + createGCCPreprocessorFlags (defines); | |||
| } | |||
| //============================================================================== | |||
| @@ -68,6 +68,10 @@ public: | |||
| commandManager->registerAllCommandsForTarget (mainWindow); | |||
| mainWindow->menuItemsChanged(); | |||
| if (commandLine.isNotEmpty() && mainWindow->getGraphEditor() != 0) | |||
| mainWindow->getGraphEditor()->graph.loadFrom (File::getCurrentWorkingDirectory() | |||
| .getChildFile (commandLine), true); | |||
| } | |||
| void shutdown() | |||
| @@ -644,12 +644,15 @@ public: | |||
| void runTest() | |||
| { | |||
| beginTest ("Round-trip conversion"); | |||
| beginTest ("Round-trip conversion: Int8"); | |||
| Test1 <AudioData::Int8>::test (*this); | |||
| beginTest ("Round-trip conversion: Int16"); | |||
| Test1 <AudioData::Int16>::test (*this); | |||
| beginTest ("Round-trip conversion: Int24"); | |||
| Test1 <AudioData::Int24>::test (*this); | |||
| beginTest ("Round-trip conversion: Int32"); | |||
| Test1 <AudioData::Int32>::test (*this); | |||
| beginTest ("Round-trip conversion: Float32"); | |||
| Test1 <AudioData::Float32>::test (*this); | |||
| } | |||
| }; | |||
| @@ -244,9 +244,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; | |||
| @@ -319,7 +319,9 @@ 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 | |||
| @@ -33,7 +33,7 @@ | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 53 | |||
| #define JUCE_BUILDNUMBER 31 | |||
| #define JUCE_BUILDNUMBER 32 | |||
| /** Current Juce version number. | |||
| @@ -56,6 +56,7 @@ FileChooser::~FileChooser() | |||
| { | |||
| } | |||
| #if JUCE_MODAL_LOOPS_PERMITTED | |||
| bool FileChooser::browseForFileToOpen (FilePreviewComponent* previewComponent) | |||
| { | |||
| return showDialog (false, true, false, false, false, previewComponent); | |||
| @@ -81,21 +82,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<File>& FileChooser::getResults() const | |||
| { | |||
| return results; | |||
| } | |||
| #if JUCE_MODAL_LOOPS_PERMITTED | |||
| bool FileChooser::showDialog (const bool selectsDirectories, | |||
| const bool selectsFiles, | |||
| const bool isSave, | |||
| @@ -169,6 +155,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<File>& FileChooser::getResults() const | |||
| { | |||
| return results; | |||
| } | |||
| //============================================================================== | |||
| FilePreviewComponent::FilePreviewComponent() | |||
| { | |||
| @@ -126,6 +126,7 @@ FileChooserDialogBox::~FileChooserDialogBox() | |||
| } | |||
| //============================================================================== | |||
| #if JUCE_MODAL_LOOPS_PERMITTED | |||
| bool FileChooserDialogBox::show (int w, int h) | |||
| { | |||
| return showAt (-1, -1, w, h); | |||
| @@ -155,6 +156,7 @@ bool FileChooserDialogBox::showAt (int x, int y, int w, int h) | |||
| setVisible (false); | |||
| return ok; | |||
| } | |||
| #endif | |||
| void FileChooserDialogBox::centreWithDefaultSize (Component* componentToCentreAround) | |||
| { | |||
| @@ -97,6 +97,7 @@ public: | |||
| ~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 | |||
| @@ -114,6 +115,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. | |||
| @@ -156,6 +156,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()) | |||
| @@ -164,6 +165,7 @@ void FileSearchPathListComponent::returnKeyPressed (int row) | |||
| path.add (chooser.getResult(), row); | |||
| changed(); | |||
| } | |||
| #endif | |||
| } | |||
| void FileSearchPathListComponent::listBoxItemDoubleClicked (int row, const MouseEvent&) | |||
| @@ -237,12 +239,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) | |||
| { | |||
| @@ -110,6 +110,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(), | |||
| @@ -121,6 +122,9 @@ void FilenameComponent::buttonClicked (Button*) | |||
| { | |||
| setCurrentFile (fc.getResult(), true); | |||
| } | |||
| #else | |||
| jassertfalse; // needs rewriting to deal with non-modal environments | |||
| #endif | |||
| } | |||
| void FilenameComponent::comboBoxChanged (ComboBox*) | |||
| @@ -1729,12 +1729,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)); | |||
| @@ -1512,7 +1512,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 | |||
| } | |||
| //============================================================================== | |||
| @@ -1533,6 +1538,7 @@ void PopupMenu::showMenuAsync (const Options& options, ModalComponentManager::Ca | |||
| } | |||
| //============================================================================== | |||
| #if JUCE_MODAL_LOOPS_PERMITTED | |||
| int PopupMenu::show (const int itemIdThatMustBeVisible, | |||
| const int minimumWidth, const int maximumNumColumns, | |||
| const int standardItemHeight, | |||
| @@ -1575,6 +1581,7 @@ int PopupMenu::showAt (Component* componentToAttachTo, | |||
| return showWithOptionalCallback (options, callback, true); | |||
| } | |||
| #endif | |||
| bool JUCE_CALLTYPE PopupMenu::dismissAllActiveMenus() | |||
| { | |||
| @@ -291,26 +291,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); | |||
| }; | |||
| @@ -310,7 +310,7 @@ inline int64 abs64 (const int64 n) throw() | |||
| template <typename Type> | |||
| 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))); | |||
| @@ -55,7 +55,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. | |||
| @@ -83,7 +83,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. | |||
| @@ -127,7 +127,10 @@ private: | |||
| @see JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR, LeakedObjectDetector | |||
| */ | |||
| #define JUCE_LEAK_DETECTOR(OwnerClass) JUCE_NAMESPACE::LeakedObjectDetector<OwnerClass> JUCE_JOIN_MACRO (leakDetector, __LINE__); | |||
| #define JUCE_LEAK_DETECTOR(OwnerClass) \ | |||
| friend class JUCE_NAMESPACE::LeakedObjectDetector<OwnerClass>; \ | |||
| static const char* getLeakedObjectClassName() throw() { return #OwnerClass; } \ | |||
| JUCE_NAMESPACE::LeakedObjectDetector<OwnerClass> JUCE_JOIN_MACRO (leakDetector, __LINE__); | |||
| #else | |||
| #define JUCE_LEAK_DETECTOR(OwnerClass) | |||
| #endif | |||
| @@ -0,0 +1,147 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-10 by Raw Material Software Ltd. | |||
| ------------------------------------------------------------------------------ | |||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||
| Public License (Version 2), as published by the Free Software Foundation. | |||
| A copy of the license is included in the JUCE distribution, or can be found | |||
| online at www.gnu.org/licenses. | |||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||
| ------------------------------------------------------------------------------ | |||
| To release a closed-source product which uses JUCE, commercial licenses are | |||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||
| ============================================================================== | |||
| */ | |||
| #ifndef __JUCE_OPTIONALSCOPEDPOINTER_JUCEHEADER__ | |||
| #define __JUCE_OPTIONALSCOPEDPOINTER_JUCEHEADER__ | |||
| #include "juce_ScopedPointer.h" | |||
| //============================================================================== | |||
| /** | |||
| Holds a pointer to an object which can optionally be deleted when this pointer | |||
| goes out of scope. | |||
| This acts in many ways like a ScopedPointer, but allows you to specify whether or | |||
| not the object is deleted. | |||
| @see ScopedPointer | |||
| */ | |||
| template <class ObjectType> | |||
| class OptionalScopedPointer | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| /** Creates an empty OptionalScopedPointer. */ | |||
| OptionalScopedPointer() : shouldDelete (false) {} | |||
| /** Creates an OptionalScopedPointer to point to a given object, and specifying whether | |||
| the OptionalScopedPointer will delete it. | |||
| If takeOwnership is true, then the OptionalScopedPointer will act like a ScopedPointer, | |||
| deleting the object when it is itself deleted. If this parameter is false, then the | |||
| OptionalScopedPointer just holds a normal pointer to the object, and won't delete it. | |||
| */ | |||
| OptionalScopedPointer (ObjectType* objectToHold, bool takeOwnership) | |||
| : object (objectToHold), shouldDelete (takeOwnership) | |||
| { | |||
| } | |||
| /** Takes ownership of the object that another OptionalScopedPointer holds. | |||
| Like a normal ScopedPointer, the objectToTransferFrom object will become null, | |||
| as ownership of the managed object is transferred to this object. | |||
| The flag to indicate whether or not to delete the managed object is also | |||
| copied from the source object. | |||
| */ | |||
| OptionalScopedPointer (OptionalScopedPointer& objectToTransferFrom) | |||
| : object (objectToTransferFrom.release()), | |||
| shouldDelete (objectToTransferFrom.shouldDelete) | |||
| { | |||
| } | |||
| /** Takes ownership of the object that another OptionalScopedPointer holds. | |||
| Like a normal ScopedPointer, the objectToTransferFrom object will become null, | |||
| as ownership of the managed object is transferred to this object. | |||
| The ownership flag that says whether or not to delete the managed object is also | |||
| copied from the source object. | |||
| */ | |||
| OptionalScopedPointer& operator= (OptionalScopedPointer& objectToTransferFrom) | |||
| { | |||
| if (object != objectToTransferFrom.object) | |||
| { | |||
| clear(); | |||
| object = objectToTransferFrom.object; | |||
| } | |||
| shouldDelete = objectToTransferFrom.shouldDelete; | |||
| return *this; | |||
| } | |||
| /** The destructor may or may not delete the object that is being held, depending on the | |||
| takeOwnership flag that was specified when the object was first passed into an | |||
| OptionalScopedPointer constructor. | |||
| */ | |||
| ~OptionalScopedPointer() | |||
| { | |||
| clear(); | |||
| } | |||
| //============================================================================== | |||
| /** Returns the object that this pointer is managing. */ | |||
| inline operator ObjectType*() const throw() { return object; } | |||
| /** Returns the object that this pointer is managing. */ | |||
| inline ObjectType& operator*() const throw() { return *object; } | |||
| /** Lets you access methods and properties of the object that this pointer is holding. */ | |||
| inline ObjectType* operator->() const throw() { return object; } | |||
| //============================================================================== | |||
| /** Removes the current object from this OptionalScopedPointer without deleting it. | |||
| This will return the current object, and set this OptionalScopedPointer to a null pointer. | |||
| */ | |||
| ObjectType* release() throw() { return object.release(); } | |||
| /** Resets this pointer to null, possibly deleting the object that it holds, if it has | |||
| ownership of it. | |||
| */ | |||
| void clear() | |||
| { | |||
| if (! shouldDelete) | |||
| object.release(); | |||
| } | |||
| //============================================================================== | |||
| /** Swaps this object with another OptionalScopedPointer. | |||
| The two objects simply exchange their states. | |||
| */ | |||
| void swapWith (OptionalScopedPointer<ObjectType>& other) throw() | |||
| { | |||
| object.swapWith (other.object); | |||
| swapVariables (shouldDelete, other.shouldDelete); | |||
| } | |||
| private: | |||
| //============================================================================== | |||
| ScopedPointer<ObjectType> object; | |||
| bool shouldDelete; | |||
| }; | |||
| #endif // __JUCE_OPTIONALSCOPEDPOINTER_JUCEHEADER__ | |||
| @@ -367,7 +367,7 @@ public: | |||
| { | |||
| while (--maxBytesToRead >= 0) | |||
| { | |||
| if (*dataToTest <= 0) | |||
| if (((signed char) *dataToTest) <= 0) | |||
| return *dataToTest == 0; | |||
| ++dataToTest; | |||
| @@ -79,7 +79,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; | |||
| @@ -115,7 +115,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) | |||
| { | |||
| @@ -135,7 +135,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; | |||
| @@ -486,7 +486,7 @@ public: | |||
| { | |||
| while (--maxBytesToRead >= 0 && *dataToTest != 0) | |||
| { | |||
| const char byte = *dataToTest; | |||
| const signed char byte = (signed char) *dataToTest; | |||
| if (byte < 0) | |||
| { | |||
| @@ -122,7 +122,6 @@ bool FileBasedDocument::loadFrom (const File& newFile, | |||
| return false; | |||
| } | |||
| #endif | |||
| bool FileBasedDocument::loadFromUserSpecifiedFile (const bool showMessageOnFailure) | |||
| { | |||
| @@ -146,7 +145,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, | |||