1 /*
2   ==============================================================================
3 
4    This file is part of the JUCE library.
5    Copyright (c) 2020 - Raw Material Software Limited
6 
7    JUCE is an open source library subject to commercial or open-source
8    licensing.
9 
10    By using JUCE, you agree to the terms of both the JUCE 6 End-User License
11    Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
12 
13    End User License Agreement: www.juce.com/juce-6-licence
14    Privacy Policy: www.juce.com/juce-privacy-policy
15 
16    Or: You may also use this code under the terms of the GPL v3 (see
17    www.gnu.org/licenses).
18 
19    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21    DISCLAIMED.
22 
23   ==============================================================================
24 */
25 
26 #pragma once
27 
28 #include "UserAccount/jucer_LicenseController.h"
29 #include "jucer_MainWindow.h"
30 #include "../Project/Modules/jucer_Modules.h"
31 #include "jucer_AutoUpdater.h"
32 #include "../CodeEditor/jucer_SourceCodeEditor.h"
33 #include "../Utility/UI/jucer_ProjucerLookAndFeel.h"
34 
35 struct ChildProcessCache;
36 
37 //==============================================================================
38 class ProjucerApplication   : public JUCEApplication,
39                               private AsyncUpdater
40 {
41 public:
42     ProjucerApplication() = default;
43 
44     static ProjucerApplication& getApp();
45     static ApplicationCommandManager& getCommandManager();
46 
47     //==============================================================================
48     void initialise (const String& commandLine) override;
49     void shutdown() override;
50     void systemRequestedQuit() override;
51     void deleteLogger();
52 
getApplicationName()53     const String getApplicationName() override       { return "Projucer"; }
getApplicationVersion()54     const String getApplicationVersion() override    { return ProjectInfo::versionString; }
55 
56     String getVersionDescription() const;
moreThanOneInstanceAllowed()57     bool moreThanOneInstanceAllowed() override       { return true; } // this is handled manually in initialise()
58 
59     void anotherInstanceStarted (const String& commandLine) override;
60 
61     //==============================================================================
62     MenuBarModel* getMenuModel();
63 
64     void getAllCommands (Array<CommandID>&) override;
65     void getCommandInfo (CommandID commandID, ApplicationCommandInfo&) override;
66     bool perform (const InvocationInfo&) override;
67 
68     bool isLiveBuildEnabled() const;
69     bool isGUIEditorEnabled() const;
70 
71     //==============================================================================
72     bool openFile (const File&);
73     void showPathsWindow (bool highlightJUCEPath = false);
74     PropertiesFile::Options getPropertyFileOptionsFor (const String& filename, bool isProjectSettings);
75     void selectEditorColourSchemeWithName (const String& schemeName);
76 
77     //==============================================================================
78     void rescanJUCEPathModules();
79     void rescanUserPathModules();
80 
getJUCEPathModulesList()81     AvailableModulesList& getJUCEPathModulesList()     { return jucePathModulesList; }
getUserPathsModulesList()82     AvailableModulesList& getUserPathsModulesList()    { return userPathsModulesList; }
83 
getLicenseController()84     LicenseController& getLicenseController()          { return *licenseController; }
85 
86     bool isAutomaticVersionCheckingEnabled() const;
87     void setAutomaticVersionCheckingEnabled (bool shouldBeEnabled);
88 
89     bool shouldPromptUserAboutIncorrectJUCEPath() const;
90     void setShouldPromptUserAboutIncorrectJUCEPath (bool shouldPrompt);
91 
92     static File getJUCEExamplesDirectoryPathFromGlobal() noexcept;
93     static Array<File> getSortedExampleDirectories() noexcept;
94     static Array<File> getSortedExampleFilesInDirectory (const File&) noexcept;
95 
96     //==============================================================================
97     ProjucerLookAndFeel lookAndFeel;
98 
99     std::unique_ptr<StoredSettings> settings;
100     std::unique_ptr<Icons> icons;
101 
102     struct MainMenuModel;
103     std::unique_ptr<MainMenuModel> menuModel;
104 
105     MainWindowList mainWindowList;
106     OpenDocumentManager openDocumentManager;
107     std::unique_ptr<ApplicationCommandManager> commandManager;
108 
109     bool isRunningCommandLine = false;
110     std::unique_ptr<ChildProcessCache> childProcessCache;
111 
112 private:
113     //==============================================================================
114     void handleAsyncUpdate() override;
115     void doBasicApplicationSetup();
116 
117     void initCommandManager();
118     bool initialiseLogger (const char* filePrefix);
119     void initialiseWindows (const String& commandLine);
120 
121     void createNewProject();
122     void createNewProjectFromClipboard();
123     void createNewPIP();
124     void askUserToOpenFile();
125     void saveAllDocuments();
126     bool closeAllDocuments (OpenDocumentManager::SaveIfNeeded askUserToSave);
127     bool closeAllMainWindows();
128     void closeAllMainWindowsAndQuitIfNeeded();
129     void clearRecentFiles();
130 
131     StringArray getMenuNames();
132     PopupMenu createMenu (const String& menuName);
133     PopupMenu createFileMenu();
134     PopupMenu createEditMenu();
135     PopupMenu createViewMenu();
136     PopupMenu createBuildMenu();
137     void createColourSchemeItems (PopupMenu&);
138     PopupMenu createWindowMenu();
139     PopupMenu createDocumentMenu();
140     PopupMenu createToolsMenu();
141     PopupMenu createHelpMenu();
142     PopupMenu createExtraAppleMenuItems();
143     void handleMainMenuCommand (int menuItemID);
144     PopupMenu createExamplesPopupMenu() noexcept;
145 
146     void findAndLaunchExample (int);
147 
148     void checkIfGlobalJUCEPathHasChanged();
149     File tryToFindDemoRunnerExecutable();
150     File tryToFindDemoRunnerProject();
151     void launchDemoRunner();
152 
153     void setColourScheme (int index, bool saveSetting);
154     void setEditorColourScheme (int index, bool saveSetting);
155     void updateEditorColourSchemeIfNeeded();
156 
157     void showUTF8ToolWindow();
158     void showSVGPathDataToolWindow();
159     void showAboutWindow();
160     void showEditorColourSchemeWindow();
161     void showPIPCreatorWindow();
162 
163     void launchForumBrowser();
164     void launchModulesBrowser();
165     void launchClassesBrowser();
166     void launchTutorialsBrowser();
167 
168     void doLoginOrLogout();
169     void showLoginForm();
170 
171     void enableOrDisableLiveBuild();
172     void enableOrDisableGUIEditor();
173 
174     //==============================================================================
175    #if JUCE_MAC
176     class AppleMenuRebuildListener  : private MenuBarModel::Listener
177     {
178     public:
AppleMenuRebuildListener()179         AppleMenuRebuildListener()
180         {
181             if (auto* model = ProjucerApplication::getApp().getMenuModel())
182                 model->addListener (this);
183         }
184 
~AppleMenuRebuildListener()185         ~AppleMenuRebuildListener() override
186         {
187             if (auto* model = ProjucerApplication::getApp().getMenuModel())
188                 model->removeListener (this);
189         }
190 
191     private:
menuBarItemsChanged(MenuBarModel *)192         void menuBarItemsChanged (MenuBarModel*) override  {}
193 
menuCommandInvoked(MenuBarModel *,const ApplicationCommandTarget::InvocationInfo & info)194         void menuCommandInvoked (MenuBarModel*,
195                                  const ApplicationCommandTarget::InvocationInfo& info) override
196         {
197             if (info.commandID == CommandIDs::enableNewVersionCheck)
198                 Timer::callAfterDelay (50, [] { ProjucerApplication::getApp().rebuildAppleMenu(); });
199         }
200     };
201 
202     void rebuildAppleMenu();
203 
204     std::unique_ptr<AppleMenuRebuildListener> appleMenuRebuildListener;
205    #endif
206 
207     //==============================================================================
208     std::unique_ptr<LicenseController> licenseController;
209 
210     void* server = nullptr;
211     std::unique_ptr<TooltipWindow> tooltipWindow;
212     AvailableModulesList jucePathModulesList, userPathsModulesList;
213 
214     std::unique_ptr<Component> utf8Window, svgPathWindow, aboutWindow, pathsWindow,
215                                editorColourSchemeWindow, pipCreatorWindow;
216 
217     std::unique_ptr<FileLogger> logger;
218 
219     int numExamples = 0;
220     std::unique_ptr<AlertWindow> demoRunnerAlert;
221     bool hasScannedForDemoRunnerExecutable = false, hasScannedForDemoRunnerProject = false;
222     File lastJUCEPath, lastDemoRunnerExectuableFile, lastDemoRunnerProjectFile;
223    #if JUCE_LINUX || JUCE_BSD
224     ChildProcess makeProcess;
225    #endif
226 
227     int selectedColourSchemeIndex = 0, selectedEditorColourSchemeIndex = 0;
228 
229     //==============================================================================
230     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjucerApplication)
231 };
232