From 1a266e822bef7951259e6cbadbbaa71a0458a308 Mon Sep 17 00:00:00 2001 From: ed Date: Mon, 15 May 2017 09:29:15 +0100 Subject: [PATCH] Projucer: The Projucer now adds a unique suffix to the target project folder of duplicate exporters and the 'selected exporter' drop-down now defaults to the first exporter that can launch the project if none were previously selected --- .../Project Saving/jucer_ProjectExporter.cpp | 57 +++++++++++++++++++ .../Project Saving/jucer_ProjectExporter.h | 4 +- .../Project/jucer_ConfigTree_Exporter.h | 14 ++++- .../Source/Project/jucer_HeaderComponent.h | 10 +++- .../Projucer/Source/Project/jucer_Project.cpp | 39 ++++++++++++- .../Projucer/Source/Project/jucer_Project.h | 3 + .../Source/Utility/jucer_JucerTreeViewBase.h | 5 +- 7 files changed, 124 insertions(+), 8 deletions(-) diff --git a/extras/Projucer/Source/Project Saving/jucer_ProjectExporter.cpp b/extras/Projucer/Source/Project Saving/jucer_ProjectExporter.cpp index 99af25731a..0d0f2a99f4 100644 --- a/extras/Projucer/Source/Project Saving/jucer_ProjectExporter.cpp +++ b/extras/Projucer/Source/Project Saving/jucer_ProjectExporter.cpp @@ -93,6 +93,55 @@ StringArray ProjectExporter::getExporterNames() return s; } +String ProjectExporter::getValueTreeNameForExporter (const String& exporterName) +{ + if (exporterName == XCodeProjectExporter::getNameMac()) + return XCodeProjectExporter::getValueTreeTypeName (false); + + if (exporterName == XCodeProjectExporter::getNameiOS()) + return XCodeProjectExporter::getValueTreeTypeName (true); + + if (exporterName == MSVCProjectExporterVC2013::getName()) + return MSVCProjectExporterVC2013::getValueTreeTypeName(); + + if (exporterName == MSVCProjectExporterVC2015::getName()) + return MSVCProjectExporterVC2015::getValueTreeTypeName(); + + if (exporterName == MSVCProjectExporterVC2017::getName()) + return MSVCProjectExporterVC2017::getValueTreeTypeName(); + + if (exporterName == MakefileProjectExporter::getNameLinux()) + return MakefileProjectExporter::getValueTreeTypeName(); + + if (exporterName == AndroidProjectExporter::getName()) + return AndroidProjectExporter::getValueTreeTypeName(); + + if (exporterName == CodeBlocksProjectExporter::getNameLinux()) + return CodeBlocksProjectExporter::getValueTreeTypeName (CodeBlocksProjectExporter::CodeBlocksOS::linuxTarget); + + if (exporterName == CodeBlocksProjectExporter::getNameWindows()) + return CodeBlocksProjectExporter::getValueTreeTypeName (CodeBlocksProjectExporter::CodeBlocksOS::windowsTarget); + + return {}; +} + +StringArray ProjectExporter::getAllDefaultBuildsFolders() +{ + StringArray folders; + + folders.add (getDefaultBuildsRootFolder() + "iOS"); + folders.add (getDefaultBuildsRootFolder() + "MacOSX"); + folders.add (getDefaultBuildsRootFolder() + "VisualStudio2013"); + folders.add (getDefaultBuildsRootFolder() + "VisualStudio2015"); + folders.add (getDefaultBuildsRootFolder() + "VisualStudio2017"); + folders.add (getDefaultBuildsRootFolder() + "LinuxMakefile"); + folders.add (getDefaultBuildsRootFolder() + "CodeBlocksWindows"); + folders.add (getDefaultBuildsRootFolder() + "CodeBlocksLinux"); + folders.add (getDefaultBuildsRootFolder() + "Android"); + + return folders; +} + String ProjectExporter::getCurrentPlatformExporterName() { #if JUCE_MAC @@ -171,6 +220,14 @@ ProjectExporter::~ProjectExporter() void ProjectExporter::updateDeprecatedProjectSettingsInteractively() {} +String ProjectExporter::getName() const +{ + if (! getAllDefaultBuildsFolders().contains (getTargetLocationString())) + return name + " - " + getTargetLocationString(); + + return name; +} + File ProjectExporter::getTargetFolder() const { return project.resolveFilename (getTargetLocationString()); diff --git a/extras/Projucer/Source/Project Saving/jucer_ProjectExporter.h b/extras/Projucer/Source/Project Saving/jucer_ProjectExporter.h index 11b7e8d5a1..dfb32efd5b 100644 --- a/extras/Projucer/Source/Project Saving/jucer_ProjectExporter.h +++ b/extras/Projucer/Source/Project Saving/jucer_ProjectExporter.h @@ -60,6 +60,8 @@ public: static StringArray getExporterNames(); static Array getExporterTypes(); + static String getValueTreeNameForExporter (const String& exporterName); + static StringArray getAllDefaultBuildsFolders(); static ProjectExporter* createNewExporter (Project&, const int index); static ProjectExporter* createNewExporter (Project&, const String& name); @@ -125,7 +127,7 @@ public: } //============================================================================== - String getName() const { return name; } + String getName() const; File getTargetFolder() const; Project& getProject() noexcept { return project; } diff --git a/extras/Projucer/Source/Project/jucer_ConfigTree_Exporter.h b/extras/Projucer/Source/Project/jucer_ConfigTree_Exporter.h index eed380fd5b..5d1aefaf87 100644 --- a/extras/Projucer/Source/Project/jucer_ConfigTree_Exporter.h +++ b/extras/Projucer/Source/Project/jucer_ConfigTree_Exporter.h @@ -24,7 +24,8 @@ ============================================================================== */ -class ExporterItem : public ConfigTreeItemBase +class ExporterItem : public ConfigTreeItemBase, + private Value::Listener { public: ExporterItem (Project& p, ProjectExporter* e, int index) @@ -32,6 +33,8 @@ public: exporterIndex (index) { configListTree.addListener (this); + targetLocationValue.referTo (exporter->getTargetLocationValue()); + targetLocationValue.addListener (this); } int getItemHeight() const override { return 25; } @@ -42,6 +45,7 @@ public: String getDisplayName() const override { return exporter->getName(); } void setName (const String&) override {} bool isMissing() const override { return false; } + String getTooltip() override { return getDisplayName(); } static Icon getIconForExporter (ProjectExporter* e) { @@ -155,6 +159,14 @@ private: ValueTree configListTree; int exporterIndex; + Value targetLocationValue; + + void valueChanged (Value& value) override + { + if (value == exporter->getTargetLocationValue()) + refreshSubItems(); + } + //============================================================================== struct SettingsComp : public Component { diff --git a/extras/Projucer/Source/Project/jucer_HeaderComponent.h b/extras/Projucer/Source/Project/jucer_HeaderComponent.h index a62fc8e60d..88d2af6fe0 100644 --- a/extras/Projucer/Source/Project/jucer_HeaderComponent.h +++ b/extras/Projucer/Source/Project/jucer_HeaderComponent.h @@ -316,7 +316,7 @@ public: auto selectedName = getSelectedExporterName(); exporterBox.clear(); - int preferredExporterIndex = 0; + auto preferredExporterIndex = -1; int i = 0; for (Project::ExporterIterator exporter (*project); exporter.next(); ++i) @@ -326,12 +326,13 @@ public: if (selectedName == exporter->getName()) exporterBox.setSelectedId (i + 1); - if (exporter->canLaunchProject()) + if (exporter->canLaunchProject() && preferredExporterIndex == -1) preferredExporterIndex = i; } if (exporterBox.getSelectedItemIndex() == -1) - exporterBox.setSelectedItemIndex (preferredExporterIndex); + exporterBox.setSelectedItemIndex (preferredExporterIndex != -1 ? preferredExporterIndex + : 0); updateExporterButton(); } @@ -427,7 +428,10 @@ private: void changeListenerCallback (ChangeBroadcaster* source) override { if (source == project) + { updateName(); + updateExporters(); + } } void valueTreePropertyChanged (ValueTree&, const Identifier&) override {} diff --git a/extras/Projucer/Source/Project/jucer_Project.cpp b/extras/Projucer/Source/Project/jucer_Project.cpp index c16f6f7150..b7dce7d0ca 100644 --- a/extras/Projucer/Source/Project/jucer_Project.cpp +++ b/extras/Projucer/Source/Project/jucer_Project.cpp @@ -1413,8 +1413,11 @@ void Project::addNewExporter (const String& exporterName) { ScopedPointer exp (ProjectExporter::createNewExporter (*this, exporterName)); - ValueTree exporters (getExporters()); - exporters.addChild (exp->settings, -1, getUndoManagerFor (exporters)); + exp->getTargetLocationValue() = exp->getTargetLocationString() + + getUniqueTargetFolderSuffixForExporter (exp->getName(), exp->getTargetLocationString()); + + auto exportersTree = getExporters(); + exportersTree.addChild (exp->settings, -1, getUndoManagerFor (exportersTree)); } void Project::createExporterForCurrentPlatform() @@ -1422,6 +1425,38 @@ void Project::createExporterForCurrentPlatform() addNewExporter (ProjectExporter::getCurrentPlatformExporterName()); } +String Project::getUniqueTargetFolderSuffixForExporter (const String& exporterName, const String& base) +{ + StringArray buildFolders; + + auto exportersTree = getExporters(); + auto type = ProjectExporter::getValueTreeNameForExporter (exporterName); + + for (int i = 0; i < exportersTree.getNumChildren(); ++i) + { + auto exporterNode = exportersTree.getChild (i); + + if (exporterNode.getType() == Identifier (type)) + buildFolders.add (exporterNode.getProperty ("targetFolder").toString()); + } + + if (buildFolders.size() == 0 || ! buildFolders.contains (base)) + return {}; + + buildFolders.remove (buildFolders.indexOf (base)); + + auto num = 1; + for (auto f : buildFolders) + { + if (! f.endsWith ("_" + String (num))) + break; + + ++num; + } + + return "_" + String (num); +} + //============================================================================== String Project::getFileTemplate (const String& templateName) { diff --git a/extras/Projucer/Source/Project/jucer_Project.h b/extras/Projucer/Source/Project/jucer_Project.h index 141f69afe1..40f805f38f 100644 --- a/extras/Projucer/Source/Project/jucer_Project.h +++ b/extras/Projucer/Source/Project/jucer_Project.h @@ -341,6 +341,9 @@ public: bool hasProjectBeenModified(); void updateModificationTime() { modificationTime = getFile().getLastModificationTime(); } + //============================================================================== + String getUniqueTargetFolderSuffixForExporter (const String& exporterName, const String& baseTargetFolder); + //============================================================================== bool shouldWaitAfterSaving = false; diff --git a/extras/Projucer/Source/Utility/jucer_JucerTreeViewBase.h b/extras/Projucer/Source/Utility/jucer_JucerTreeViewBase.h index e3a8ded1df..3e1b1329b8 100644 --- a/extras/Projucer/Source/Utility/jucer_JucerTreeViewBase.h +++ b/extras/Projucer/Source/Utility/jucer_JucerTreeViewBase.h @@ -30,7 +30,8 @@ class ProjectContentComponent; class Project; //============================================================================== -class JucerTreeViewBase : public TreeViewItem +class JucerTreeViewBase : public TreeViewItem, + public TooltipClient { public: JucerTreeViewBase(); @@ -76,6 +77,8 @@ public: virtual void showPlusMenu(); virtual void handlePopupMenuResult (int resultCode); + String getTooltip() override { return {}; } + //============================================================================== // To handle situations where an item gets deleted before openness is // restored for it, this OpennessRestorer keeps only a pointer to the