/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #include #include #include #include #include #include #include #include #include #include #include #include namespace O3DE::ProjectManager { Application::~Application() { TearDown(); } bool Application::Init(bool interactive) { constexpr const char* applicationName { "O3DE" }; QApplication::setOrganizationName(applicationName); QApplication::setOrganizationDomain("o3de.org"); QCoreApplication::setApplicationName(applicationName); QCoreApplication::setApplicationVersion("1.0"); // Use the LogComponent for non-dev logging log RegisterComponentDescriptor(AzFramework::LogComponent::CreateDescriptor()); // set the log alias to .o3de/Logs instead of the default user/logs AZ::IO::FixedMaxPath path = AZ::Utils::GetO3deLogsDirectory(); // DevWriteStorage is where the event log is written during development m_settingsRegistry->Set(AZ::SettingsRegistryMergeUtils::FilePathKey_DevWriteStorage, path.LexicallyNormal().Native()); // Save event logs to .o3de/Logs/eventlogger/EventLogO3DE.azsl m_settingsRegistry->Set(AZ::SettingsRegistryMergeUtils::BuildTargetNameKey, applicationName); Start(AzFramework::Application::Descriptor()); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); AzQtComponents::Utilities::HandleDpiAwareness(AzQtComponents::Utilities::SystemDpiAware); // Create the actual Qt Application - this needs to happen before using QMessageBox m_app.reset(new QApplication(*GetArgC(), *GetArgV())); if(!InitLog(applicationName)) { AZ_Warning("ProjectManager", false, "Failed to init logging"); } m_pythonBindings = AZStd::make_unique(GetEngineRoot()); if (!m_pythonBindings || !m_pythonBindings->PythonStarted()) { if (interactive) { QMessageBox::critical(nullptr, QObject::tr("Failed to start Python"), QObject::tr("This tool requires an O3DE engine with a Python runtime, " "but either Python is missing or mis-configured. Please rename " "your python/runtime folder to python/runtime_bak, then run " "python/get_python.bat to restore the Python runtime folder.")); } return false; } const AZ::CommandLine* commandLine = GetCommandLine(); AZ_Assert(commandLine, "Failed to get command line"); ProjectManagerScreen startScreen = ProjectManagerScreen::Projects; if (size_t screenSwitchCount = commandLine->GetNumSwitchValues("screen"); screenSwitchCount > 0) { QString screenOption = commandLine->GetSwitchValue("screen", screenSwitchCount - 1).c_str(); ProjectManagerScreen screen = ProjectUtils::GetProjectManagerScreen(screenOption); if (screen != ProjectManagerScreen::Invalid) { startScreen = screen; } } AZ::IO::FixedMaxPath projectPath; if (size_t projectSwitchCount = commandLine->GetNumSwitchValues("project-path"); projectSwitchCount > 0) { projectPath = commandLine->GetSwitchValue("project-path", projectSwitchCount - 1).c_str(); } m_mainWindow.reset(new ProjectManagerWindow(nullptr, projectPath, startScreen)); return true; } bool Application::InitLog(const char* logName) { if (!m_entity) { // override the log alias to the O3de Logs directory instead of the default project user/Logs folder AZ::IO::FixedMaxPath path = AZ::Utils::GetO3deLogsDirectory(); AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); AZ_Assert(fileIO, "Failed to get FileIOBase instance"); fileIO->SetAlias("@log@", path.LexicallyNormal().Native().c_str()); // this entity exists because we need a home for LogComponent // and cannot use the system entity because we need to be able to call SetLogFileBaseName // so the log will be named O3DE.log m_entity = aznew AZ::Entity("Application Entity"); if (m_entity) { AzFramework::LogComponent* logger = aznew AzFramework::LogComponent(); AZ_Assert(logger, "Failed to create LogComponent"); logger->SetLogFileBaseName(logName); m_entity->AddComponent(logger); m_entity->Init(); m_entity->Activate(); } } return m_entity != nullptr; } void Application::TearDown() { if (m_entity) { m_entity->Deactivate(); delete m_entity; m_entity = nullptr; } m_pythonBindings.reset(); m_mainWindow.reset(); m_app.reset(); } bool Application::Run() { // Set up the Style Manager AzQtComponents::StyleManager styleManager(qApp); styleManager.initialize(qApp, GetEngineRoot()); // setup stylesheets and hot reloading AZ::IO::FixedMaxPath engineRoot(GetEngineRoot()); QDir rootDir(engineRoot.c_str()); const auto pathOnDisk = rootDir.absoluteFilePath("Code/Tools/ProjectManager/Resources"); const auto qrcPath = QStringLiteral(":/ProjectManager/style"); AzQtComponents::StyleManager::addSearchPaths("style", pathOnDisk, qrcPath, engineRoot); // set stylesheet after creating the main window or their styles won't get updated AzQtComponents::StyleManager::setStyleSheet(m_mainWindow.data(), QStringLiteral("style:ProjectManager.qss")); // the decoration wrapper is intended to remember window positioning and sizing auto wrapper = new AzQtComponents::WindowDecorationWrapper(); wrapper->setGuest(m_mainWindow.data()); wrapper->show(); m_mainWindow->show(); qApp->setQuitOnLastWindowClosed(true); // Run the application return qApp->exec(); } }