//======================================================================
void HeaderComponent::updateExporters() noexcept
{
    auto selectedName = getSelectedExporterName();

    exporterBox.clear();
    auto preferredExporterIndex = -1;

    int i = 0;
    for (Project::ExporterIterator exporter (*project); exporter.next(); ++i)
    {
        exporterBox.addItem (exporter->getName(), i + 1);

        if (selectedName == exporter->getName())
            exporterBox.setSelectedId (i + 1);

        if (exporter->canLaunchProject() && preferredExporterIndex == -1)
            preferredExporterIndex = i;
    }

    if (exporterBox.getSelectedItemIndex() == -1)
        exporterBox.setSelectedItemIndex (preferredExporterIndex != -1 ? preferredExporterIndex
                                                                       : 0);

    updateExporterButton();
}
bool HeaderComponent::canCurrentExporterLaunchProject() const noexcept
{
    for (Project::ExporterIterator exporter (*project); exporter.next();)
        if (exporter->getName() == getSelectedExporterName() && exporter->canLaunchProject())
            return true;

    return false;
}
StringArray ProjectContentComponent::getExportersWhichCanLaunch() const
{
    StringArray s;

    if (project != nullptr)
        for (Project::ExporterIterator exporter (*project); exporter.next();)
            if (exporter->canLaunchProject())
                s.add (exporter->getName());

    return s;
}
void ProjectContentComponent::openInSelectedIDE (bool saveFirst)
{
    if (project != nullptr)
    {
        if (auto* headerComp = dynamic_cast<HeaderComponent*> (header.get()))
        {
            auto selectedIDE = headerComp->getSelectedExporterName();

            for (Project::ExporterIterator exporter (*project); exporter.next();)
            {
                if (exporter->canLaunchProject() && exporter->getName() == selectedIDE)
                {
                    if (saveFirst && ! saveProject (exporter->isXcode()))
                        return;

                    exporter->launchProject();
                    break;
                }
            }
        }
    }
}
void ProjectSaver::writeProjects (const OwnedArray<LibraryModule>& modules, const String& specifiedExporterToSave, bool isCommandLineApp)
{
    ThreadPool threadPool;

    // keep a copy of the basic generated files group, as each exporter may modify it.
    auto originalGeneratedGroup = generatedFilesGroup.state.createCopy();

    CLionProjectExporter* clionExporter = nullptr;
    OwnedArray<ProjectExporter> exporters;

    try
    {
        for (Project::ExporterIterator exp (project); exp.next();)
        {
            if (specifiedExporterToSave.isNotEmpty() && exp->getName() != specifiedExporterToSave)
                continue;

            auto* exporter = exporters.add (exp.exporter.release());

            exporter->initialiseDependencyPathValues();

            if (exporter->getTargetFolder().createDirectory())
            {
                if (exporter->isCLion())
                {
                    clionExporter = dynamic_cast<CLionProjectExporter*> (exporter);
                }
                else
                {
                    exporter->copyMainGroupFromProject();
                    exporter->settings = exporter->settings.createCopy();

                    exporter->addToExtraSearchPaths (RelativePath ("JuceLibraryCode", RelativePath::projectFolder));

                    generatedFilesGroup.state = originalGeneratedGroup.createCopy();
                    exporter->addSettingsForProjectType (project.getProjectType());

                    for (auto& module: modules)
                        module->addSettingsForModuleToExporter (*exporter, *this);

                    generatedFilesGroup.sortAlphabetically (true, true);
                    exporter->getAllGroups().add (generatedFilesGroup);
                }

                if (isCommandLineApp)
                    saveExporter (exporter, modules);
                else
                    threadPool.addJob (new ExporterJob (*this, exporter, modules), true);
            }
            else
            {
                addError ("Can't create folder: " + exporter->getTargetFolder().getFullPathName());
            }
        }
    }
    catch (ProjectExporter::SaveError& saveError)
    {
        addError (saveError.message);
    }

    if (! isCommandLineApp)
        while (threadPool.getNumJobs() > 0)
            Thread::sleep (10);

    if (clionExporter != nullptr)
    {
        for (auto* exporter : exporters)
            clionExporter->writeCMakeListsExporterSection (exporter);

        std::cout << "Finished saving: " << clionExporter->getName() << std::endl;
    }
}