/* ============================================================================== This file is part of the JUCE library - "Jules' Utility Class Extensions" Copyright 2004-9 by Raw Material Software Ltd. ------------------------------------------------------------------------------ JUCE can be redistributed and/or modified under the terms of the GNU General Public License (Version 2), as published by the Free Software Foundation. A copy of the license is included in the JUCE distribution, or can be found online 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.rawmaterialsoftware.com/juce for more information. ============================================================================== */ #include "../jucer_Headers.h" #include "jucer_MainWindow.h" #include "jucer_OpenDocumentManager.h" #include "jucer_SourceCodeEditor.h" #include "../model/jucer_ProjectWizard.h" //============================================================================== MainWindow::MainWindow() : DocumentWindow (JUCEApplication::getInstance()->getApplicationName(), Colour::greyLevel (0.6f), DocumentWindow::allButtons) { setUsingNativeTitleBar (true); setContentComponent (new ProjectContentComponent()); setApplicationCommandManagerToWatch (commandManager); #if JUCE_MAC setMacMainMenu (this); #else setMenuBar (this); #endif setResizable (true, false); centreWithSize (700, 600); // restore the last size and position from our settings file.. restoreWindowStateFromString (StoredSettings::getInstance()->getProps() .getValue ("lastMainWindowPos")); // Register all the app commands.. { commandManager->registerAllCommandsForTarget (JUCEApplication::getInstance()); commandManager->registerAllCommandsForTarget (this); // use a temporary one of these to harvest its commands.. ProjectContentComponent pcc; commandManager->registerAllCommandsForTarget (&pcc); DocumentEditorComponent dec (0); commandManager->registerAllCommandsForTarget (&dec); ComponentEditor compEd (0, 0, 0); commandManager->registerAllCommandsForTarget (&compEd); } commandManager->getKeyMappings()->resetToDefaultMappings(); ScopedPointer keys (StoredSettings::getInstance()->getProps().getXmlValue ("keyMappings")); if (keys != 0) commandManager->getKeyMappings()->restoreFromXml (*keys); addKeyListener (commandManager->getKeyMappings()); // don't want the window to take focus when the title-bar is clicked.. setWantsKeyboardFocus (false); //getPeer()->setCurrentRenderingEngine (0); } MainWindow::~MainWindow() { #if JUCE_MAC setMacMainMenu (0); #else setMenuBar (0); #endif removeKeyListener (commandManager->getKeyMappings()); // save the current size and position to our settings file.. StoredSettings::getInstance()->getProps() .setValue ("lastMainWindowPos", getWindowStateAsString()); setContentComponent (0); currentProject = 0; } ProjectContentComponent* MainWindow::getProjectContentComponent() const { return dynamic_cast (getContentComponent()); } void MainWindow::closeButtonPressed() { JUCEApplication::getInstance()->systemRequestedQuit(); } bool MainWindow::closeProject (Project* project) { jassert (project == currentProject && project != 0); if (project == 0) return true; if (! OpenDocumentManager::getInstance()->closeAllDocumentsUsingProject (*project, true)) return false; FileBasedDocument::SaveResult r = project->saveIfNeededAndUserAgrees(); if (r == FileBasedDocument::savedOk) { setProject (0); return true; } return false; } bool MainWindow::closeCurrentProject() { return currentProject == 0 || closeProject (currentProject); } bool MainWindow::closeAllDocuments (bool askUserToSave) { for (int i = OpenDocumentManager::getInstance()->getNumOpenDocuments(); --i >= 0;) { OpenDocumentManager::Document* doc = OpenDocumentManager::getInstance()->getOpenDocument (i); getProjectContentComponent()->hideDocument (doc); if (! OpenDocumentManager::getInstance()->closeDocument (i, askUserToSave)) return false; } return true; } void MainWindow::setProject (Project* newProject) { if (newProject != 0) StoredSettings::getInstance()->setLastProject (newProject->getFile()); getProjectContentComponent()->setProject (newProject); currentProject = newProject; commandManager->commandStatusChanged(); } void MainWindow::reloadLastProject() { openFile (StoredSettings::getInstance()->getLastProject()); } void MainWindow::askUserToOpenFile() { FileChooser fc ("Open File"); if (fc.browseForFileToOpen()) openFile (fc.getResult()); } bool MainWindow::canOpenFile (const File& file) const { return file.hasFileExtension (Project::projectFileExtension) || OpenDocumentManager::getInstance()->canOpenFile (file); } bool MainWindow::openFile (const File& file) { if (file.hasFileExtension (Project::projectFileExtension)) { ScopedPointer newDoc (new Project (file)); if (file == File::nonexistent ? newDoc->loadFromUserSpecifiedFile (true) : newDoc->loadFrom (file, true)) { if (closeCurrentProject()) { setProject (newDoc.release()); return true; } } } else if (file.exists()) { return getProjectContentComponent()->showEditorForFile (file); } return false; } void MainWindow::createNewProject() { ScopedPointer newProj (ProjectWizard::runNewProjectWizard (this)); if (newProj != 0 && closeCurrentProject()) setProject (newProj.release()); } bool MainWindow::isInterestedInFileDrag (const StringArray& filenames) { for (int i = filenames.size(); --i >= 0;) if (canOpenFile (filenames[i])) return true; return false; } void MainWindow::filesDropped (const StringArray& filenames, int mouseX, int mouseY) { for (int i = filenames.size(); --i >= 0;) { const File f (filenames[i]); if (canOpenFile (f) && openFile (f)) break; } } void MainWindow::activeWindowStatusChanged() { DocumentWindow::activeWindowStatusChanged(); if (getProjectContentComponent() != 0) getProjectContentComponent()->updateMissingFileStatuses(); OpenDocumentManager::getInstance()->reloadModifiedFiles(); } void MainWindow::updateTitle (const String& documentName) { String name (JUCEApplication::getInstance()->getApplicationName()); if (documentName.isNotEmpty()) name = documentName + " - " + name; setName (name); } //============================================================================== const StringArray MainWindow::getMenuBarNames() { const char* const names[] = { "File", "Edit", "View", "Window", 0 }; return StringArray ((const char**) names); } const PopupMenu MainWindow::getMenuForIndex (int topLevelMenuIndex, const String& menuName) { PopupMenu menu; if (topLevelMenuIndex == 0) { // "File" menu menu.addCommandItem (commandManager, CommandIDs::newProject); menu.addSeparator(); menu.addCommandItem (commandManager, CommandIDs::open); PopupMenu recentFiles; StoredSettings::getInstance()->recentFiles.createPopupMenuItems (recentFiles, 100, true, true); menu.addSubMenu ("Open recent file", recentFiles); menu.addSeparator(); menu.addCommandItem (commandManager, CommandIDs::closeDocument); menu.addCommandItem (commandManager, CommandIDs::saveDocument); menu.addCommandItem (commandManager, CommandIDs::saveDocumentAs); menu.addSeparator(); menu.addCommandItem (commandManager, CommandIDs::closeProject); menu.addCommandItem (commandManager, CommandIDs::saveProject); menu.addCommandItem (commandManager, CommandIDs::saveProjectAs); menu.addSeparator(); menu.addCommandItem (commandManager, CommandIDs::openProjectInIDE); #if ! JUCE_MAC menu.addSeparator(); menu.addCommandItem (commandManager, StandardApplicationCommandIDs::quit); #endif } else if (topLevelMenuIndex == 1) { // "Edit" menu menu.addCommandItem (commandManager, CommandIDs::undo); menu.addCommandItem (commandManager, CommandIDs::redo); menu.addSeparator(); menu.addCommandItem (commandManager, StandardApplicationCommandIDs::cut); menu.addCommandItem (commandManager, StandardApplicationCommandIDs::copy); menu.addCommandItem (commandManager, StandardApplicationCommandIDs::paste); menu.addCommandItem (commandManager, StandardApplicationCommandIDs::del); menu.addCommandItem (commandManager, StandardApplicationCommandIDs::selectAll); menu.addCommandItem (commandManager, StandardApplicationCommandIDs::deselectAll); menu.addSeparator(); menu.addCommandItem (commandManager, CommandIDs::toFront); menu.addCommandItem (commandManager, CommandIDs::toBack); menu.addSeparator(); menu.addCommandItem (commandManager, CommandIDs::group); menu.addCommandItem (commandManager, CommandIDs::ungroup); menu.addSeparator(); menu.addCommandItem (commandManager, CommandIDs::bringBackLostItems); } else if (topLevelMenuIndex == 2) { // "View" menu menu.addCommandItem (commandManager, CommandIDs::showProjectSettings); //menu.addCommandItem (commandManager, CommandIDs::test); menu.addSeparator(); menu.addCommandItem (commandManager, CommandIDs::showGrid); menu.addCommandItem (commandManager, CommandIDs::enableSnapToGrid); /* const int currentSnapSize = getActiveDocument() != 0 ? getActiveDocument()->getSnappingGridSize() : 0; PopupMenu m; for (int i = 0; i < numElementsInArray (snapSizes); ++i) m.addItem (300 + i, String (snapSizes[i]) + " pixels", true, snapSizes[i] == currentSnapSize); menu.addSubMenu ("Grid size", m, getActiveDocument() != 0);*/ menu.addSeparator(); menu.addCommandItem (commandManager, CommandIDs::zoomIn); menu.addCommandItem (commandManager, CommandIDs::zoomOut); menu.addCommandItem (commandManager, CommandIDs::zoomNormal); /* menu.addSeparator(); PopupMenu overlays; overlays.addCommandItem (commandManager, CommandIDs::compOverlay0); overlays.addCommandItem (commandManager, CommandIDs::compOverlay33); overlays.addCommandItem (commandManager, CommandIDs::compOverlay66); overlays.addCommandItem (commandManager, CommandIDs::compOverlay100); menu.addSubMenu ("Component Overlay", overlays, getActiveDocument() != 0 && getActiveDocument()->getComponentLayout() != 0);*/ menu.addSeparator(); menu.addCommandItem (commandManager, CommandIDs::useTabbedWindows); //menu.addSeparator(); //menu.addCommandItem (commandManager, CommandIDs::showPrefs); } else if (topLevelMenuIndex == 3) { // "Window" menu const int numDocs = jmin (50, OpenDocumentManager::getInstance()->getNumOpenDocuments()); for (int i = 0; i < numDocs; ++i) { OpenDocumentManager::Document* doc = OpenDocumentManager::getInstance()->getOpenDocument(i); menu.addItem (300 + i, doc->getName()); } menu.addSeparator(); menu.addCommandItem (commandManager, CommandIDs::closeAllDocuments); } return menu; } void MainWindow::menuItemSelected (int menuItemID, int topLevelMenuIndex) { if (menuItemID >= 100 && menuItemID < 200) { // open a file from the "recent files" menu const File file (StoredSettings::getInstance()->recentFiles.getFile (menuItemID - 100)); openFile (file); } else if (menuItemID == 201) { LookAndFeel::setDefaultLookAndFeel (0); } else if (menuItemID >= 300 && menuItemID < 400) { OpenDocumentManager::Document* doc = OpenDocumentManager::getInstance()->getOpenDocument (menuItemID - 300); getProjectContentComponent()->showDocument (doc); } } //============================================================================== ApplicationCommandTarget* MainWindow::getNextCommandTarget() { return 0; } void MainWindow::getAllCommands (Array & commands) { const CommandID ids[] = { CommandIDs::newProject, CommandIDs::open, CommandIDs::showPrefs, CommandIDs::closeAllDocuments, CommandIDs::saveAll }; commands.addArray (ids, numElementsInArray (ids)); } void MainWindow::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result) { switch (commandID) { case CommandIDs::newProject: result.setInfo ("New Project...", "Creates a new Jucer project", CommandCategories::general, 0); result.defaultKeypresses.add (KeyPress ('o', ModifierKeys::commandModifier, 0)); break; case CommandIDs::open: result.setInfo ("Open...", "Opens a Jucer project", CommandCategories::general, 0); result.defaultKeypresses.add (KeyPress ('o', ModifierKeys::commandModifier, 0)); break; case CommandIDs::showPrefs: result.setInfo ("Preferences...", "Shows the preferences panel.", CommandCategories::general, 0); result.defaultKeypresses.add (KeyPress (',', ModifierKeys::commandModifier, 0)); break; case CommandIDs::closeAllDocuments: result.setInfo ("Close All Documents", "Closes all open documents", CommandCategories::general, 0); result.setActive (OpenDocumentManager::getInstance()->getNumOpenDocuments() > 0); break; case CommandIDs::saveAll: result.setInfo ("Save All", "Saves all open documents", CommandCategories::general, 0); result.setActive (OpenDocumentManager::getInstance()->anyFilesNeedSaving()); break; default: break; } } bool MainWindow::perform (const InvocationInfo& info) { switch (info.commandID) { case CommandIDs::newProject: createNewProject(); break; case CommandIDs::open: askUserToOpenFile(); break; case CommandIDs::showPrefs: // PrefsPanel::show(); break; case CommandIDs::saveAll: OpenDocumentManager::getInstance()->saveAll(); break; case CommandIDs::closeAllDocuments: closeAllDocuments (true); break; default: return false; } return true; }