|
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2013 - Raw Material Software Ltd.
-
- Permission is granted to use this software under the terms of either:
- a) the GPL v2 (or any later version)
- b) the Affero GPL v3
-
- Details of these licenses can be found 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.juce.com for more information.
-
- ==============================================================================
- */
-
- #include "jucer_NewProjectWizard.h"
- #include "jucer_ProjectType.h"
- #include "jucer_Module.h"
- #include "../Project Saving/jucer_ProjectExporter.h"
- #include "../Application/jucer_Application.h"
- #include "../Application/jucer_MainWindow.h"
-
-
- struct NewProjectWizardClasses
- {
- //==============================================================================
- static void createFileCreationOptionComboBox (Component& setupComp,
- OwnedArray<Component>& itemsCreated,
- const StringArray& fileOptions)
- {
- ComboBox* c = new ComboBox();
- itemsCreated.add (c);
- setupComp.addChildAndSetID (c, "filesToCreate");
-
- c->addItemList (fileOptions, 1);
- c->setSelectedId (1, dontSendNotification);
-
- Label* l = new Label (String::empty, TRANS("Files to Auto-Generate") + ":");
- l->attachToComponent (c, true);
- itemsCreated.add (l);
-
- c->setBounds ("parent.width / 2 + 160, 10, parent.width - 10, top + 22");
- }
-
- static int getFileCreationComboResult (Component& setupComp)
- {
- if (ComboBox* cb = dynamic_cast<ComboBox*> (setupComp.findChildWithID ("filesToCreate")))
- return cb->getSelectedItemIndex();
-
- jassertfalse;
- return 0;
- }
-
- static void setExecutableNameForAllTargets (Project& project, const String& exeName)
- {
- for (Project::ExporterIterator exporter (project); exporter.next();)
- for (ProjectExporter::ConfigIterator config (*exporter); config.next();)
- config->getTargetBinaryName() = exeName;
- }
-
- static Project::Item createSourceGroup (Project& project)
- {
- return project.getMainGroup().addNewSubGroup ("Source", 0);
- }
-
- static File& getLastWizardFolder()
- {
- #if JUCE_WINDOWS
- static File lastFolder (File::getSpecialLocation (File::userDocumentsDirectory));
- #else
- static File lastFolder (File::getSpecialLocation (File::userHomeDirectory));
- #endif
-
- 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
- {
- NewProjectWizard() {}
- virtual ~NewProjectWizard() {}
-
- //==============================================================================
- virtual String getName() = 0;
- virtual String getDescription() = 0;
-
- virtual void addSetupItems (Component&, OwnedArray<Component>&) {}
- virtual Result processResultsFromSetupItems (Component&) { return Result::ok(); }
-
- virtual bool initialiseProject (Project& project) = 0;
-
- virtual StringArray getDefaultModules()
- {
- static const char* mods[] =
- {
- "juce_core",
- "juce_events",
- "juce_graphics",
- "juce_data_structures",
- "juce_gui_basics",
- "juce_gui_extra",
- "juce_cryptography",
- "juce_video",
- "juce_opengl",
- "juce_audio_basics",
- "juce_audio_devices",
- "juce_audio_formats",
- "juce_audio_processors",
- nullptr
- };
-
- return StringArray (mods);
- }
-
- String appTitle;
- File targetFolder, projectFile, modulesFolder;
- Component* ownerWindow;
- StringArray failedFiles;
-
- //==============================================================================
- Project* runWizard (Component* window,
- const String& projectName,
- const File& target)
- {
- ownerWindow = window;
- appTitle = projectName;
- targetFolder = target;
-
- if (! targetFolder.exists())
- {
- if (! targetFolder.createDirectory())
- failedFiles.add (targetFolder.getFullPathName());
- }
- else if (FileHelpers::containsAnyNonHiddenFiles (targetFolder))
- {
- if (! AlertWindow::showOkCancelBox (AlertWindow::InfoIcon,
- TRANS("New Juce Project"),
- TRANS("The folder you chose isn't empty - are you sure you want to create the project there?")
- + "\n\n"
- + TRANS("Any existing files with the same names may be overwritten by the new files.")))
- return nullptr;
- }
-
- projectFile = targetFolder.getChildFile (File::createLegalFileName (appTitle))
- .withFileExtension (Project::projectFileExtension);
-
- ScopedPointer<Project> project (new Project (projectFile));
-
- if (failedFiles.size() == 0)
- {
- project->setFile (projectFile);
- project->setTitle (appTitle);
- project->getBundleIdentifier() = project->getDefaultBundleIdentifier();
-
- if (! initialiseProject (*project))
- return nullptr;
-
- addDefaultModules (*project);
-
- if (project->save (false, true) != FileBasedDocument::savedOk)
- return nullptr;
-
- project->setChangedFlag (false);
- }
-
- if (failedFiles.size() > 0)
- {
- AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
- TRANS("Errors in Creating Project!"),
- TRANS("The following files couldn't be written:")
- + "\n\n"
- + failedFiles.joinIntoString ("\n", 0, 10));
- return nullptr;
- }
-
- return project.release();
- }
-
- bool selectJuceFolder()
- {
- for (;;)
- {
- FileChooser fc ("Select your JUCE modules folder...",
- findDefaultModulesFolder(),
- "*");
-
- if (! fc.browseForDirectory())
- return false;
-
- if (isJuceModulesFolder (fc.getResult()))
- {
- modulesFolder = fc.getResult();
- return true;
- }
-
- AlertWindow::showMessageBox (AlertWindow::WarningIcon,
- "Not a valid JUCE modules folder!",
- "Please select the folder containing your juce_* modules!\n\n"
- "This is required so that the new project can be given some essential core modules.");
- }
- }
-
- //==============================================================================
- File getSourceFilesFolder() const
- {
- return projectFile.getSiblingFile ("Source");
- }
-
- void createSourceFolder()
- {
- if (! getSourceFilesFolder().createDirectory())
- failedFiles.add (getSourceFilesFolder().getFullPathName());
- }
-
- void addDefaultModules (Project& project)
- {
- StringArray mods (getDefaultModules());
-
- ModuleList list;
- list.addAllModulesInFolder (modulesFolder);
-
- for (int i = 0; i < mods.size(); ++i)
- if (const ModuleDescription* info = list.getModuleWithID (mods[i]))
- project.getModules().addModule (info->manifestFile, true);
- }
- };
-
- //==============================================================================
- struct GUIAppWizard : public NewProjectWizard
- {
- GUIAppWizard() {}
-
- String getName() { return TRANS("GUI Application"); }
- String getDescription() { return TRANS("Creates a standard application"); }
-
- void addSetupItems (Component& setupComp, OwnedArray<Component>& itemsCreated)
- {
- const String fileOptions[] = { TRANS("Create a Main.cpp file"),
- TRANS("Create a Main.cpp file and a basic window"),
- TRANS("Don't create any files") };
-
- createFileCreationOptionComboBox (setupComp, itemsCreated,
- StringArray (fileOptions, numElementsInArray (fileOptions)));
- }
-
- Result processResultsFromSetupItems (Component& setupComp)
- {
- createMainCpp = createWindow = false;
-
- switch (getFileCreationComboResult (setupComp))
- {
- case 0: createMainCpp = true; break;
- case 1: createMainCpp = createWindow = true; break;
- case 2: break;
- default: jassertfalse; break;
- }
-
- return Result::ok();
- }
-
- bool initialiseProject (Project& project)
- {
- createSourceFolder();
-
- File mainCppFile = getSourceFilesFolder().getChildFile ("Main.cpp");
- File contentCompCpp = getSourceFilesFolder().getChildFile ("MainComponent.cpp");
- File contentCompH = contentCompCpp.withFileExtension (".h");
- String contentCompName = "MainContentComponent";
-
- project.getProjectTypeValue() = ProjectType::getGUIAppTypeName();
-
- Project::Item sourceGroup (createSourceGroup (project));
-
- setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle));
-
- String appHeaders (CodeHelpers::createIncludeStatement (project.getAppIncludeFile(), mainCppFile));
-
- if (createWindow)
- {
- appHeaders << newLine << CodeHelpers::createIncludeStatement (contentCompH, mainCppFile);
-
- String windowH = project.getFileTemplate ("jucer_ContentCompTemplate_h")
- .replace ("INCLUDE_JUCE", CodeHelpers::createIncludeStatement (project.getAppIncludeFile(), contentCompH), false)
- .replace ("CONTENTCOMPCLASS", contentCompName, false)
- .replace ("HEADERGUARD", CodeHelpers::makeHeaderGuardName (contentCompH), false);
-
- String windowCpp = project.getFileTemplate ("jucer_ContentCompTemplate_cpp")
- .replace ("INCLUDE_JUCE", CodeHelpers::createIncludeStatement (project.getAppIncludeFile(), contentCompCpp), false)
- .replace ("INCLUDE_CORRESPONDING_HEADER", CodeHelpers::createIncludeStatement (contentCompH, contentCompCpp), false)
- .replace ("CONTENTCOMPCLASS", contentCompName, false);
-
- if (! FileHelpers::overwriteFileWithNewDataIfDifferent (contentCompH, windowH))
- failedFiles.add (contentCompH.getFullPathName());
-
- if (! FileHelpers::overwriteFileWithNewDataIfDifferent (contentCompCpp, windowCpp))
- failedFiles.add (contentCompCpp.getFullPathName());
-
- sourceGroup.addFile (contentCompCpp, -1, true);
- sourceGroup.addFile (contentCompH, -1, false);
- }
-
- if (createMainCpp)
- {
- String mainCpp = project.getFileTemplate (createWindow ? "jucer_MainTemplate_Window_cpp"
- : "jucer_MainTemplate_NoWindow_cpp")
- .replace ("APPHEADERS", appHeaders, false)
- .replace ("APPCLASSNAME", CodeHelpers::makeValidIdentifier (appTitle + "Application", false, true, false), false)
- .replace ("APPNAME", CodeHelpers::addEscapeChars (appTitle), false)
- .replace ("CONTENTCOMPCLASS", contentCompName, false)
- .replace ("ALLOWMORETHANONEINSTANCE", "true", false);
-
- if (! FileHelpers::overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp))
- failedFiles.add (mainCppFile.getFullPathName());
-
- sourceGroup.addFile (mainCppFile, -1, true);
- }
-
- project.createExporterForCurrentPlatform();
-
- return true;
- }
-
- private:
- bool createMainCpp, createWindow;
- };
-
- //==============================================================================
- struct ConsoleAppWizard : public NewProjectWizard
- {
- ConsoleAppWizard() {}
-
- String getName() { return TRANS("Console Application"); }
- String getDescription() { return TRANS("Creates a command-line application with no GUI features"); }
-
- void addSetupItems (Component& setupComp, OwnedArray<Component>& itemsCreated)
- {
- const String fileOptions[] = { TRANS("Create a Main.cpp file"),
- TRANS("Don't create any files") };
-
- createFileCreationOptionComboBox (setupComp, itemsCreated,
- StringArray (fileOptions, numElementsInArray (fileOptions)));
- }
-
- Result processResultsFromSetupItems (Component& setupComp)
- {
- createMainCpp = false;
-
- switch (getFileCreationComboResult (setupComp))
- {
- case 0: createMainCpp = true; break;
- case 1: break;
- default: jassertfalse; break;
- }
-
- return Result::ok();
- }
-
- bool initialiseProject (Project& project)
- {
- createSourceFolder();
-
- project.getProjectTypeValue() = ProjectType::getConsoleAppTypeName();
-
- Project::Item sourceGroup (createSourceGroup (project));
-
- setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle));
-
- if (createMainCpp)
- {
- File mainCppFile = getSourceFilesFolder().getChildFile ("Main.cpp");
- String appHeaders (CodeHelpers::createIncludeStatement (project.getAppIncludeFile(), mainCppFile));
-
- String mainCpp = project.getFileTemplate ("jucer_MainConsoleAppTemplate_cpp")
- .replace ("APPHEADERS", appHeaders, false);
-
- if (! FileHelpers::overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp))
- failedFiles.add (mainCppFile.getFullPathName());
-
- sourceGroup.addFile (mainCppFile, -1, true);
- }
-
- project.createExporterForCurrentPlatform();
-
- return true;
- }
-
- private:
- bool createMainCpp;
- };
-
- //==============================================================================
- struct AudioPluginAppWizard : public NewProjectWizard
- {
- AudioPluginAppWizard() {}
-
- String getName() override { return TRANS("Audio Plug-In"); }
- String getDescription() override { return TRANS("Creates an audio plugin project"); }
-
- StringArray getDefaultModules() override
- {
- StringArray s (NewProjectWizard::getDefaultModules());
- s.add ("juce_audio_plugin_client");
- return s;
- }
-
- bool initialiseProject (Project& project) override
- {
- createSourceFolder();
-
- String filterClassName = CodeHelpers::makeValidIdentifier (appTitle, true, true, false) + "AudioProcessor";
- filterClassName = filterClassName.substring (0, 1).toUpperCase() + filterClassName.substring (1);
- String editorClassName = filterClassName + "Editor";
-
- File filterCppFile = getSourceFilesFolder().getChildFile ("PluginProcessor.cpp");
- File filterHFile = filterCppFile.withFileExtension (".h");
- File editorCppFile = getSourceFilesFolder().getChildFile ("PluginEditor.cpp");
- File editorHFile = editorCppFile.withFileExtension (".h");
-
- project.getProjectTypeValue() = ProjectType::getAudioPluginTypeName();
-
- Project::Item sourceGroup (createSourceGroup (project));
- project.getConfigFlag ("JUCE_QUICKTIME") = Project::configFlagDisabled; // disabled because it interferes with RTAS build on PC
-
- setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle));
-
- String appHeaders (CodeHelpers::createIncludeStatement (project.getAppIncludeFile(), filterCppFile));
-
- String filterCpp = project.getFileTemplate ("jucer_AudioPluginFilterTemplate_cpp")
- .replace ("FILTERHEADERS", CodeHelpers::createIncludeStatement (filterHFile, filterCppFile)
- + newLine + CodeHelpers::createIncludeStatement (editorHFile, filterCppFile), false)
- .replace ("FILTERCLASSNAME", filterClassName, false)
- .replace ("EDITORCLASSNAME", editorClassName, false);
-
- String filterH = project.getFileTemplate ("jucer_AudioPluginFilterTemplate_h")
- .replace ("APPHEADERS", appHeaders, false)
- .replace ("FILTERCLASSNAME", filterClassName, false)
- .replace ("HEADERGUARD", CodeHelpers::makeHeaderGuardName (filterHFile), false);
-
- String editorCpp = project.getFileTemplate ("jucer_AudioPluginEditorTemplate_cpp")
- .replace ("EDITORCPPHEADERS", CodeHelpers::createIncludeStatement (filterHFile, filterCppFile)
- + newLine + CodeHelpers::createIncludeStatement (editorHFile, filterCppFile), false)
- .replace ("FILTERCLASSNAME", filterClassName, false)
- .replace ("EDITORCLASSNAME", editorClassName, false);
-
- String editorH = project.getFileTemplate ("jucer_AudioPluginEditorTemplate_h")
- .replace ("EDITORHEADERS", appHeaders + newLine + CodeHelpers::createIncludeStatement (filterHFile, filterCppFile), false)
- .replace ("FILTERCLASSNAME", filterClassName, false)
- .replace ("EDITORCLASSNAME", editorClassName, false)
- .replace ("HEADERGUARD", CodeHelpers::makeHeaderGuardName (editorHFile), false);
-
- if (! FileHelpers::overwriteFileWithNewDataIfDifferent (filterCppFile, filterCpp))
- failedFiles.add (filterCppFile.getFullPathName());
-
- if (! FileHelpers::overwriteFileWithNewDataIfDifferent (filterHFile, filterH))
- failedFiles.add (filterHFile.getFullPathName());
-
- if (! FileHelpers::overwriteFileWithNewDataIfDifferent (editorCppFile, editorCpp))
- failedFiles.add (editorCppFile.getFullPathName());
-
- if (! FileHelpers::overwriteFileWithNewDataIfDifferent (editorHFile, editorH))
- failedFiles.add (editorHFile.getFullPathName());
-
- sourceGroup.addFile (filterCppFile, -1, true);
- sourceGroup.addFile (filterHFile, -1, false);
- sourceGroup.addFile (editorCppFile, -1, true);
- sourceGroup.addFile (editorHFile, -1, false);
-
- project.createExporterForCurrentPlatform();
-
- return true;
- }
- };
-
- //==============================================================================
- struct StaticLibraryWizard : public NewProjectWizard
- {
- StaticLibraryWizard() {}
-
- String getName() override { return TRANS("Static Library"); }
- String getDescription() override { return TRANS("Creates a static library"); }
-
- bool initialiseProject (Project& project) override
- {
- createSourceFolder();
- project.getProjectTypeValue() = ProjectType::getStaticLibTypeName();
- createSourceGroup (project);
- setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle));
- project.createExporterForCurrentPlatform();
-
- return true;
- }
- };
-
- //==============================================================================
- struct DynamicLibraryWizard : public NewProjectWizard
- {
- DynamicLibraryWizard() {}
-
- String getName() override { return TRANS("Dynamic Library"); }
- String getDescription() override { return TRANS("Creates a dynamic library"); }
-
- bool initialiseProject (Project& project) override
- {
- createSourceFolder();
- project.getProjectTypeValue() = ProjectType::getDynamicLibTypeName();
- createSourceGroup (project);
- setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle));
- project.createExporterForCurrentPlatform();
-
- return true;
- }
- };
-
- //==============================================================================
- class WizardComp : public Component,
- private ButtonListener,
- private ComboBoxListener,
- private TextEditorListener
- {
- public:
- WizardComp()
- : projectName (TRANS("Project name")),
- nameLabel (String::empty, TRANS("Project Name") + ":"),
- typeLabel (String::empty, TRANS("Project Type") + ":"),
- fileBrowser (FileBrowserComponent::saveMode | FileBrowserComponent::canSelectDirectories,
- getLastWizardFolder(), nullptr, nullptr),
- fileOutline (String::empty, TRANS("Project Folder") + ":"),
- createButton (TRANS("Create") + "..."),
- cancelButton (TRANS("Cancel"))
- {
- setOpaque (true);
- setSize (600, 500);
-
- addChildAndSetID (&projectName, "projectName");
- projectName.setText ("NewProject");
- projectName.setBounds ("100, 14, parent.width / 2 - 10, top + 22");
- nameLabel.attachToComponent (&projectName, true);
- projectName.addListener (this);
-
- addChildAndSetID (&projectType, "projectType");
- projectType.addItemList (getWizardNames(), 1);
- projectType.setSelectedId (1, dontSendNotification);
- projectType.setBounds ("100, projectName.bottom + 4, projectName.right, top + 22");
- typeLabel.attachToComponent (&projectType, true);
- projectType.addListener (this);
-
- addChildAndSetID (&fileOutline, "fileOutline");
- fileOutline.setColour (GroupComponent::outlineColourId, Colours::black.withAlpha (0.2f));
- fileOutline.setTextLabelPosition (Justification::centred);
- fileOutline.setBounds ("10, projectType.bottom + 20, projectType.right, parent.height - 10");
-
- addChildAndSetID (&fileBrowser, "fileBrowser");
- fileBrowser.setBounds ("fileOutline.left + 10, fileOutline.top + 20, fileOutline.right - 10, fileOutline.bottom - 12");
- fileBrowser.setFilenameBoxLabel ("Folder:");
-
- addChildAndSetID (&createButton, "createButton");
- createButton.setBounds ("right - 140, bottom - 24, parent.width - 10, parent.height - 10");
- createButton.addListener (this);
-
- addChildAndSetID (&cancelButton, "cancelButton");
- cancelButton.addShortcut (KeyPress (KeyPress::escapeKey));
- cancelButton.setBounds ("right - 140, createButton.top, createButton.left - 10, createButton.bottom");
- cancelButton.addListener (this);
-
- updateCustomItems();
- updateCreateButton();
- }
-
- void paint (Graphics& g) override
- {
- g.fillAll (Colour::greyLevel (0.93f));
- }
-
- void buttonClicked (Button* b) override
- {
- if (b == &createButton)
- {
- createProject();
- }
- else
- {
- if (MainWindow* mw = dynamic_cast<MainWindow*> (getTopLevelComponent()))
- {
- #if ! JUCE_MAC
- if (IntrojucerApp::getApp().mainWindowList.windows.size() == 1)
- mw->setProject (nullptr);
- else
- #endif
- IntrojucerApp::getApp().mainWindowList.closeWindow (mw);
- }
- }
- }
-
- void createProject()
- {
- MainWindow* mw = Component::findParentComponentOfClass<MainWindow>();
- jassert (mw != nullptr);
-
- ScopedPointer<NewProjectWizard> wizard (createWizard());
-
- if (wizard != nullptr)
- {
- Result result (wizard->processResultsFromSetupItems (*this));
-
- if (result.failed())
- {
- AlertWindow::showMessageBox (AlertWindow::WarningIcon,
- TRANS("Create Project"),
- result.getErrorMessage());
- return;
- }
-
- if (! wizard->selectJuceFolder())
- return;
-
- ScopedPointer<Project> project (wizard->runWizard (mw, projectName.getText(),
- fileBrowser.getSelectedFile (0)));
-
- if (project != nullptr)
- mw->setProject (project.release());
- }
- }
-
- void updateCustomItems()
- {
- customItems.clear();
-
- ScopedPointer<NewProjectWizard> wizard (createWizard());
-
- if (wizard != nullptr)
- wizard->addSetupItems (*this, customItems);
- }
-
- void comboBoxChanged (ComboBox*) override
- {
- updateCustomItems();
- }
-
- void textEditorTextChanged (TextEditor&) override
- {
- updateCreateButton();
-
- fileBrowser.setFileName (File::createLegalFileName (projectName.getText()));
- }
-
- private:
- ComboBox projectType;
- TextEditor projectName;
- Label nameLabel, typeLabel;
- FileBrowserComponent fileBrowser;
- GroupComponent fileOutline;
- TextButton createButton, cancelButton;
- OwnedArray<Component> customItems;
-
- NewProjectWizard* createWizard()
- {
- return createWizardType (projectType.getSelectedItemIndex());
- }
-
- void updateCreateButton()
- {
- createButton.setEnabled (projectName.getText().trim().isNotEmpty());
- }
- };
-
- //==============================================================================
- static int getNumWizards()
- {
- return 5;
- }
-
- static NewProjectWizard* createWizardType (int index)
- {
- switch (index)
- {
- case 0: return new GUIAppWizard();
- case 1: return new ConsoleAppWizard();
- case 2: return new AudioPluginAppWizard();
- case 3: return new StaticLibraryWizard();
- case 4: return new DynamicLibraryWizard();
- default: jassertfalse; break;
- }
-
- return nullptr;
- }
-
- static StringArray getWizardNames()
- {
- StringArray s;
-
- for (int i = 0; i < getNumWizards(); ++i)
- {
- ScopedPointer<NewProjectWizard> wiz (createWizardType (i));
- s.add (wiz->getName());
- }
-
- return s;
- }
- };
-
- Component* createNewProjectWizardComponent()
- {
- return new NewProjectWizardClasses::WizardComp();
- }
|