diff --git a/extras/Introjucer/Source/Application/jucer_Application.h b/extras/Introjucer/Source/Application/jucer_Application.h index 6aa7727d98..743109d616 100644 --- a/extras/Introjucer/Source/Application/jucer_Application.h +++ b/extras/Introjucer/Source/Application/jucer_Application.h @@ -28,6 +28,7 @@ #include "../jucer_Headers.h" #include "jucer_MainWindow.h" #include "jucer_CommandLine.h" +#include "../project/jucer_Module.h" #include "jucer_AutoUpdater.h" #include "../Code Editor/jucer_SourceCodeEditor.h" diff --git a/extras/Introjucer/Source/Application/jucer_AutoUpdater.h b/extras/Introjucer/Source/Application/jucer_AutoUpdater.h index fc422b5911..af17b27ece 100644 --- a/extras/Introjucer/Source/Application/jucer_AutoUpdater.h +++ b/extras/Introjucer/Source/Application/jucer_AutoUpdater.h @@ -109,8 +109,6 @@ public: bool isDifferentVersionToCurrent() const { -JUCE_COMPILER_WARNING("testing") -return true; return version != JUCE_STRINGIFY(JUCE_MAJOR_VERSION) "." JUCE_STRINGIFY(JUCE_MINOR_VERSION) "." JUCE_STRINGIFY(JUCE_BUILDNUMBER) @@ -141,23 +139,69 @@ return true; } else { -JUCE_COMPILER_WARNING("todo") + if (! AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, + TRANS("Download JUCE version 123?").replace ("123", info.version), + TRANS("A new version of JUCE is available - would you like to download it?"))) + { + return; + } - File targetFolder; + File targetFolder (findDefaultModulesFolder()); -// FileChooser f; + if (isJuceModulesFolder (targetFolder)) + targetFolder = targetFolder.getParentDirectory(); - DownloadNewVersionThread::performDownload (info.url, targetFolder); + FileChooser chooser (TRANS("Please select the location into which you'd like to install the new version"), + targetFolder); + + if (chooser.browseForDirectory()) + { + targetFolder = chooser.getResult(); + + if (isJuceModulesFolder (targetFolder)) + targetFolder = targetFolder.getParentDirectory(); + + if (targetFolder.getChildFile ("JUCE").isDirectory()) + targetFolder = targetFolder.getChildFile ("JUCE"); + + if (targetFolder.getChildFile (".git").isDirectory()) + { + AlertWindow::showMessageBox (AlertWindow::WarningIcon, + TRANS ("Downloading new JUCE version"), + TRANS ("This folder is a GIT repository!\n\n" + "You should use a \"git pull\" to update it to the latest version. " + "Or to use the Introjucer to get an update, you should select an empty " + "folder into which you'd like to download the new code.")); + + return; + } + + if (isJuceFolder (targetFolder)) + { + if (! AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, + TRANS("Overwrite existing JUCE folder?"), + TRANS("Do you want to overwrite the folder:\n\n" + "xfldrx\n\n" + " ..with the latest version from juce.com?\n\n" + "(Please note that this will overwrite everything in that folder!)") + .replace ("xfldrx", targetFolder.getFullPathName()))) + { + return; + } + } + else + { + targetFolder = targetFolder.getChildFile ("JUCE").getNonexistentSibling(); + } + DownloadNewVersionThread::performDownload (info.url, targetFolder); + } } } } static bool isZipFolder (const File& f) { -JUCE_COMPILER_WARNING("testing") -return true; - return f.getChildFile ("modules").isDirectory() && f.getChildFile ("extras").isDirectory() && f.getChildFile ("examples").isDirectory() @@ -220,7 +264,7 @@ private: } else { -JUCE_COMPILER_WARNING("todo") + new RelaunchTimer (targetFolder); } } } @@ -252,7 +296,7 @@ JUCE_COMPILER_WARNING("todo") if (threadShouldExit()) return Result::fail ("cancel"); - size_t written = mo.writeFromInputStream (*in, 8192); + int64 written = mo.writeFromInputStream (*in, 8192); if (written == 0) break; @@ -273,7 +317,8 @@ JUCE_COMPILER_WARNING("todo") { setStatusMessage ("Installing..."); - File tempUnzipped; + File unzipTarget; + bool isUsingTempFolder = false; { MemoryInputStream input (data, false); @@ -282,32 +327,43 @@ JUCE_COMPILER_WARNING("todo") if (zip.getNumEntries() == 0) return Result::fail ("The downloaded file wasn't a valid JUCE file!"); - tempUnzipped = targetFolder.getNonexistentSibling(); + unzipTarget = targetFolder; - if (! tempUnzipped.createDirectory()) - return Result::fail ("Couldn't create a folder to unzip the new version!"); + if (unzipTarget.exists()) + { + isUsingTempFolder = true; + unzipTarget = targetFolder.getNonexistentSibling(); - Result r (zip.uncompressTo (tempUnzipped)); + if (! unzipTarget.createDirectory()) + return Result::fail ("Couldn't create a folder to unzip the new version!"); + } + + Result r (zip.uncompressTo (unzipTarget)); if (r.failed()) { - tempUnzipped.deleteRecursively(); + if (isUsingTempFolder) + unzipTarget.deleteRecursively(); + return r; } } - File oldFolder (targetFolder.getSiblingFile (targetFolder.getFileNameWithoutExtension() + "_old").getNonexistentSibling()); - - if (! targetFolder.moveFileTo (targetFolder.getNonexistentSibling())) + if (isUsingTempFolder) { - tempUnzipped.deleteRecursively(); - return Result::fail ("Could not remove the existing folder!"); - } + File oldFolder (targetFolder.getSiblingFile (targetFolder.getFileNameWithoutExtension() + "_old").getNonexistentSibling()); - if (! tempUnzipped.moveFileTo (targetFolder)) - { - tempUnzipped.deleteRecursively(); - return Result::fail ("Could not overwrite the existing folder!"); + if (! targetFolder.moveFileTo (oldFolder)) + { + unzipTarget.deleteRecursively(); + return Result::fail ("Could not remove the existing folder!"); + } + + if (! unzipTarget.moveFileTo (targetFolder)) + { + unzipTarget.deleteRecursively(); + return Result::fail ("Could not overwrite the existing folder!"); + } } return Result::ok(); @@ -320,6 +376,37 @@ JUCE_COMPILER_WARNING("todo") JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DownloadNewVersionThread) }; + struct RelaunchTimer : private Timer + { + RelaunchTimer (const File& f) : parentFolder (f) + { + startTimer (1500); + } + + void timerCallback() override + { + stopTimer(); + + File app = parentFolder.getChildFile ( + #if JUCE_MAC + "Introjucer.app"); + #elif JUCE_WINDOWS + "Introjucer.exe"); + #elif JUCE_LINUX + "Introjucer"); + #endif + + JUCEApplication::quit(); + + if (app.exists()) + app.startAsProcess(); + + delete this; + } + + File parentFolder; + }; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LatestVersionChecker) }; diff --git a/extras/Introjucer/Source/Application/jucer_MainWindow.cpp b/extras/Introjucer/Source/Application/jucer_MainWindow.cpp index 341ccce81a..eb0ab70adf 100644 --- a/extras/Introjucer/Source/Application/jucer_MainWindow.cpp +++ b/extras/Introjucer/Source/Application/jucer_MainWindow.cpp @@ -543,3 +543,24 @@ Project* MainWindowList::getFrontmostProject() return nullptr; } + +File findDefaultModulesFolder (bool mustContainJuceCoreModule) +{ + const MainWindowList& windows = IntrojucerApp::getApp().mainWindowList; + + for (int i = windows.windows.size(); --i >= 0;) + { + if (Project* p = windows.windows.getUnchecked (i)->getProject()) + { + const File f (EnabledModuleList::findDefaultModulesFolder (*p)); + + if (isJuceModulesFolder (f) || (f.isDirectory() && ! mustContainJuceCoreModule)) + return f; + } + } + + if (mustContainJuceCoreModule) + return findDefaultModulesFolder (false); + + return File::nonexistent; +} diff --git a/extras/Introjucer/Source/Project/jucer_Module.cpp b/extras/Introjucer/Source/Project/jucer_Module.cpp index 2c33ed6178..4ba59aeb93 100644 --- a/extras/Introjucer/Source/Project/jucer_Module.cpp +++ b/extras/Introjucer/Source/Project/jucer_Module.cpp @@ -895,3 +895,13 @@ void EnabledModuleList::addModuleOfferingToCopy (const File& f) addModule (m.manifestFile, areMostModulesCopiedLocally()); } + +bool isJuceFolder (const File& f) +{ + return isJuceModulesFolder (f.getChildFile ("modules")); +} + +bool isJuceModulesFolder (const File& f) +{ + return f.isDirectory() && f.getChildFile ("juce_core").isDirectory(); +} diff --git a/extras/Introjucer/Source/Project/jucer_Module.h b/extras/Introjucer/Source/Project/jucer_Module.h index 7b72160f66..fecd48319a 100644 --- a/extras/Introjucer/Source/Project/jucer_Module.h +++ b/extras/Introjucer/Source/Project/jucer_Module.h @@ -30,6 +30,11 @@ class ProjectExporter; class ProjectSaver; +//============================================================================== +File findDefaultModulesFolder (bool mustContainJuceCoreModule = true); +bool isJuceModulesFolder (const File&); +bool isJuceFolder (const File&); + //============================================================================== struct ModuleDescription { diff --git a/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.cpp b/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.cpp index 41a9074f65..576d1353d9 100644 --- a/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.cpp +++ b/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.cpp @@ -30,7 +30,7 @@ #include "../Project Saving/jucer_ProjectExporter.h" #include "../Utility/jucer_TranslationTool.h" #include "../Utility/jucer_JucerTreeViewBase.h" -#include "jucer_NewFileWizard.h" +#include "../Wizards/jucer_NewFileWizard.h" #include "jucer_GroupInformationComponent.h" //============================================================================== @@ -241,7 +241,8 @@ void ProjectContentComponent::resized() if (contentView != nullptr) contentView->setBounds (r); - logo->setBounds (r.reduced (r.getWidth() / 4, r.getHeight() / 4)); + if (logo != nullptr) + logo->setBounds (r.reduced (r.getWidth() / 4, r.getHeight() / 4)); } void ProjectContentComponent::lookAndFeelChanged() diff --git a/extras/Introjucer/Source/Wizards/jucer_NewFileWizard.h b/extras/Introjucer/Source/Wizards/jucer_NewFileWizard.h index c1d0d7166e..b97328e0ad 100644 --- a/extras/Introjucer/Source/Wizards/jucer_NewFileWizard.h +++ b/extras/Introjucer/Source/Wizards/jucer_NewFileWizard.h @@ -26,7 +26,7 @@ #define __JUCER_NEWFILEWIZARD_JUCEHEADER__ #include "../jucer_Headers.h" -#include "jucer_Project.h" +#include "../Project/jucer_Project.h" //============================================================================== diff --git a/extras/Introjucer/Source/Wizards/jucer_NewProjectWizard.h b/extras/Introjucer/Source/Wizards/jucer_NewProjectWizard.h index d83efa4910..6e034d6df9 100644 --- a/extras/Introjucer/Source/Wizards/jucer_NewProjectWizard.h +++ b/extras/Introjucer/Source/Wizards/jucer_NewProjectWizard.h @@ -77,33 +77,6 @@ static File& getLastWizardFolder() return lastFolder; } -static bool isJuceModulesFolder (const File& f) -{ - return f.isDirectory() - && f.getChildFile ("juce_core").isDirectory(); -} - -static File findDefaultModulesFolder (bool mustContainJuceCoreModule = true) -{ - const MainWindowList& windows = IntrojucerApp::getApp().mainWindowList; - - for (int i = windows.windows.size(); --i >= 0;) - { - if (Project* p = windows.windows.getUnchecked (i)->getProject()) - { - const File f (EnabledModuleList::findDefaultModulesFolder (*p)); - - if (isJuceModulesFolder (f) || (f.isDirectory() && ! mustContainJuceCoreModule)) - return f; - } - } - - if (mustContainJuceCoreModule) - return findDefaultModulesFolder (false); - - return File::nonexistent; -} - //============================================================================== struct NewProjectWizard { diff --git a/extras/Introjucer/Source/Wizards/jucer_NewProjectWizardClasses.cpp b/extras/Introjucer/Source/Wizards/jucer_NewProjectWizardClasses.cpp index d9399866e6..33dbcd5eb7 100644 --- a/extras/Introjucer/Source/Wizards/jucer_NewProjectWizardClasses.cpp +++ b/extras/Introjucer/Source/Wizards/jucer_NewProjectWizardClasses.cpp @@ -24,8 +24,8 @@ #include "../jucer_Headers.h" #include "jucer_NewProjectWizardClasses.h" -#include "jucer_ProjectType.h" -#include "jucer_Module.h" +#include "../Project/jucer_ProjectType.h" +#include "../Project/jucer_Module.h" #include "../Project Saving/jucer_ProjectExporter.h" #include "../Application/jucer_Application.h" #include "../Application/jucer_MainWindow.h" diff --git a/extras/Introjucer/Source/Wizards/jucer_NewProjectWizardComponent.h b/extras/Introjucer/Source/Wizards/jucer_NewProjectWizardComponent.h index 9f4f7a5d60..d4f104fa1e 100644 --- a/extras/Introjucer/Source/Wizards/jucer_NewProjectWizardComponent.h +++ b/extras/Introjucer/Source/Wizards/jucer_NewProjectWizardComponent.h @@ -154,7 +154,7 @@ public: listBox.setOpaque (false); listBox.setMultipleSelectionEnabled (true); listBox.setClickingTogglesRowSelection (true); - listBox.setColour (ListBox::ColourIds::backgroundColourId, Colours::white.withAlpha (0.0f)); + listBox.setColour (ListBox::backgroundColourId, Colours::white.withAlpha (0.0f)); addAndMakeVisible (listBox); selectDefaultExporterIfNoneSelected(); @@ -203,7 +203,7 @@ public: if (rowIsSelected) g.fillAll (Colour (0x99f29000)); - Rectangle dotSelect (height, height); + Rectangle dotSelect ((float) height, (float) height); dotSelect.reduce (12, 12); g.setColour (Colour (0x33ffffff)); diff --git a/extras/Introjucer/Source/Wizards/jucer_TemplateThumbnailsComponent.h b/extras/Introjucer/Source/Wizards/jucer_TemplateThumbnailsComponent.h index 7c6f713bed..d4de897678 100644 --- a/extras/Introjucer/Source/Wizards/jucer_TemplateThumbnailsComponent.h +++ b/extras/Introjucer/Source/Wizards/jucer_TemplateThumbnailsComponent.h @@ -38,13 +38,13 @@ public: { // svg for thumbnail icon ScopedPointer svg (XmlDocument::parse (thumbSvg)); - assert (svg != nullptr); + jassert (svg != nullptr); thumb = Drawable::createFromSVG (*svg); // svg for thumbnail background highlight ScopedPointer backSvg (XmlDocument::parse (BinaryData::wizard_Highlight_svg)); - assert (backSvg != nullptr); + jassert (backSvg != nullptr); hoverBackground = Drawable::createFromSVG (*backSvg); @@ -60,7 +60,7 @@ public: if (isMouseOverButton) { - if (getStyle() == ButtonStyle::ImageFitted) + if (getStyle() == ImageFitted) { hoverBackground->drawWithin (g, bounds, RectanglePlacement::centred, 1.0); thumb->drawWithin (g, bounds, RectanglePlacement::centred, 1.0); @@ -75,7 +75,7 @@ public: } else { - if (getStyle() == ButtonStyle::ImageFitted) + if (getStyle() == ImageFitted) { thumb->drawWithin (g, bounds, RectanglePlacement::centred, 1.0); } @@ -89,7 +89,7 @@ public: Rectangle textTarget; // center the text for the text buttons or position the text in the image buttons - if (getStyle() != ButtonStyle::ImageFitted) + if (getStyle() != ImageFitted) { textTarget = getLocalBounds().toFloat(); } @@ -145,7 +145,7 @@ public: ScopedPointer wizard (createWizardType (i)); TemplateOptionButton* b = new TemplateOptionButton (wizard->getName(), - TemplateOptionButton::ButtonStyle::ImageFitted, + TemplateOptionButton::ImageFitted, wizard->getIcon()); optionButtons.add (b); addAndMakeVisible (b); @@ -156,9 +156,9 @@ public: // Handle Open Project button functionality ApplicationCommandManager& commandManager = IntrojucerApp::getCommandManager(); - addAndMakeVisible (blankProjectButton = new TemplateOptionButton ("Create Blank Project", TemplateOptionButton::ButtonStyle::ImageOnButtonBackground, BinaryData::wizard_Openfile_svg)); - addAndMakeVisible (exampleProjectButton = new TemplateOptionButton ("Open Example Project", TemplateOptionButton::ButtonStyle::ImageOnButtonBackground, BinaryData::wizard_Openfile_svg)); - addAndMakeVisible (openProjectButton = new TemplateOptionButton ("Open Existing Project", TemplateOptionButton::ButtonStyle::ImageOnButtonBackground, BinaryData::wizard_Openfile_svg)); + addAndMakeVisible (blankProjectButton = new TemplateOptionButton ("Create Blank Project", TemplateOptionButton::ImageOnButtonBackground, BinaryData::wizard_Openfile_svg)); + addAndMakeVisible (exampleProjectButton = new TemplateOptionButton ("Open Example Project", TemplateOptionButton::ImageOnButtonBackground, BinaryData::wizard_Openfile_svg)); + addAndMakeVisible (openProjectButton = new TemplateOptionButton ("Open Existing Project", TemplateOptionButton::ImageOnButtonBackground, BinaryData::wizard_Openfile_svg)); blankProjectButton->addListener (this); exampleProjectButton->addListener (this); @@ -191,7 +191,7 @@ public: void resized() override { Rectangle allOpts = getLocalBounds().reduced (40, 60); - allOpts.removeFromBottom (allOpts.getHeight() * 0.25); + allOpts.removeFromBottom (allOpts.getHeight() / 4); const int numHorizIcons = 4; const int optStep = allOpts.getWidth() / numHorizIcons; diff --git a/modules/juce_core/xml/juce_XmlDocument.h b/modules/juce_core/xml/juce_XmlDocument.h index d2a5b49e03..c032b854df 100644 --- a/modules/juce_core/xml/juce_XmlDocument.h +++ b/modules/juce_core/xml/juce_XmlDocument.h @@ -41,7 +41,7 @@ @code XmlDocument myDocument (File ("myfile.xml")); - XmlElement* mainElement = myDocument.getDocumentElement(); + ScopedPointer mainElement (myDocument.getDocumentElement()); if (mainElement == nullptr) { @@ -57,7 +57,7 @@ Or you can use the static helper methods for quick parsing.. @code - XmlElement* xml = XmlDocument::parse (myXmlFile); + ScopedPointer xml (XmlDocument::parse (myXmlFile)); if (xml != nullptr && xml->hasTagName ("foobar")) { diff --git a/modules/juce_graphics/geometry/juce_Path.cpp b/modules/juce_graphics/geometry/juce_Path.cpp index 5a6b2f8662..65c211fe3a 100644 --- a/modules/juce_graphics/geometry/juce_Path.cpp +++ b/modules/juce_graphics/geometry/juce_Path.cpp @@ -501,13 +501,20 @@ void Path::addRoundedRectangle (float x, float y, float w, float h, float cs) addRoundedRectangle (x, y, w, h, cs, cs); } -void Path::addTriangle (const float x1, const float y1, - const float x2, const float y2, - const float x3, const float y3) +void Path::addTriangle (float x1, float y1, + float x2, float y2, + float x3, float y3) { - startNewSubPath (x1, y1); - lineTo (x2, y2); - lineTo (x3, y3); + addTriangle (Point (x1, y1), + Point (x2, y2), + Point (x3, y3)); +} + +void Path::addTriangle (Point p1, Point p2, Point p3) +{ + startNewSubPath (p1); + lineTo (p2); + lineTo (p3); closeSubPath(); } diff --git a/modules/juce_graphics/geometry/juce_Path.h b/modules/juce_graphics/geometry/juce_Path.h index ac319f96f3..c680089f2d 100644 --- a/modules/juce_graphics/geometry/juce_Path.h +++ b/modules/juce_graphics/geometry/juce_Path.h @@ -377,6 +377,18 @@ public: float x2, float y2, float x3, float y3); + /** Adds a triangle to the path. + + The triangle is added as a new closed sub-path. (Any currently open paths will be left open). + + Note that whether the vertices are specified in clockwise or anticlockwise + order will affect how the triangle is filled when it overlaps other + shapes (the winding order setting will affect this of course). + */ + void addTriangle (Point point1, + Point point2, + Point point3); + /** Adds a quadrilateral to the path. The quad is added as a new closed sub-path. (Any currently open paths will be left open). diff --git a/modules/juce_gui_basics/buttons/juce_TextButton.h b/modules/juce_gui_basics/buttons/juce_TextButton.h index b9093b27bd..31c477ba71 100644 --- a/modules/juce_gui_basics/buttons/juce_TextButton.h +++ b/modules/juce_gui_basics/buttons/juce_TextButton.h @@ -102,7 +102,7 @@ public: private: #if JUCE_CATCH_DEPRECATED_CODE_MISUSE - // Note that this method has been removed - instead, see LookAndFeel::getTextButtonWidthToFitText() + // Note that this method has been removed - instead, see LookAndFeel::getTextButtonFont() virtual int getFont() { return 0; } #endif