diff --git a/Code/Editor/Core/QtEditorApplication.cpp b/Code/Editor/Core/QtEditorApplication.cpp index 17d4a84703..46e789cd7c 100644 --- a/Code/Editor/Core/QtEditorApplication.cpp +++ b/Code/Editor/Core/QtEditorApplication.cpp @@ -243,7 +243,7 @@ namespace Editor } EditorQtApplication::EditorQtApplication(int& argc, char** argv) - : QApplication(argc, argv) + : AzQtApplication(argc, argv) , m_inWinEventFilter(false) , m_stylesheet(new AzQtComponents::O3DEStylesheet(this)) , m_idleTimer(new QTimer(this)) @@ -253,8 +253,6 @@ namespace Editor setWindowIcon(QIcon(":/Application/res/o3de_editor.ico")); // set the default key store for our preferences: - setOrganizationName("O3DE"); - setOrganizationDomain("o3de.org"); setApplicationName("O3DE Editor"); connect(m_idleTimer, &QTimer::timeout, this, &EditorQtApplication::maybeProcessIdle); diff --git a/Code/Editor/Core/QtEditorApplication.h b/Code/Editor/Core/QtEditorApplication.h index c7c971a253..2e3612095e 100644 --- a/Code/Editor/Core/QtEditorApplication.h +++ b/Code/Editor/Core/QtEditorApplication.h @@ -8,7 +8,6 @@ #pragma once #if !defined(Q_MOC_RUN) -#include #include #include #include @@ -20,6 +19,7 @@ #include #include #include +#include #endif class QFileInfo; @@ -48,7 +48,7 @@ namespace Editor void ScanDirectories(QFileInfoList& directoryList, const QStringList& filters, QFileInfoList& files, ScanDirectoriesUpdateCallBack updateCallback = nullptr); class EditorQtApplication - : public QApplication + : public AzQtComponents::AzQtApplication , public QAbstractNativeEventFilter , public IEditorNotifyListener , public AZ::UserSettingsOwnerRequestBus::Handler diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Application/AzQtApplication.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Application/AzQtApplication.cpp new file mode 100644 index 0000000000..594a339448 --- /dev/null +++ b/Code/Framework/AzQtComponents/AzQtComponents/Application/AzQtApplication.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +#include // This should be the first include to make sure Windows.h is defined with NOMINMAX +#include + +namespace AzQtComponents +{ + + AzQtApplication::AzQtApplication(int& argc, char** argv) + : QApplication(argc, argv) + { + // Use a common Qt settings path for applications that don't register their own application name + QApplication::setOrganizationName("O3DE"); + QApplication::setOrganizationDomain("o3de.org"); + QApplication::setApplicationName("O3DE Tools Application"); + + AzQtComponents::PrepareQtPaths(); + + QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); + } + + void AzQtApplication::InitializeDpiScaling() + { + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); + QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); + QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); + AzQtComponents::Utilities::HandleDpiAwareness(AzQtComponents::Utilities::SystemDpiAware); + } +} // namespace AzQtComponents + diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Application/AzQtApplication.h b/Code/Framework/AzQtComponents/AzQtComponents/Application/AzQtApplication.h new file mode 100644 index 0000000000..2aa4be646c --- /dev/null +++ b/Code/Framework/AzQtComponents/AzQtComponents/Application/AzQtApplication.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include + +#include + +namespace AzQtComponents +{ + //! Base class for O3DE Tools Applications + class AZ_QT_COMPONENTS_API AzQtApplication + : public QApplication + { + public: + AzQtApplication(int& argc, char** argv); + + //! Initializes Qt DPI scaling to handle displays with high display densities, such as Retina displays. + //! Currently, this uses Qt's system DPI awareness, in which a common device scaling factor will be + //! calculated across all attached screens. + //! \warning This must be called before this AzQtApplication instance is initialized. + static void InitializeDpiScaling(); + }; + +} // namespace AzQtComponents + + + diff --git a/Code/Framework/AzQtComponents/AzQtComponents/azqtcomponents_files.cmake b/Code/Framework/AzQtComponents/AzQtComponents/azqtcomponents_files.cmake index 9c137f3692..af1a3a9f56 100644 --- a/Code/Framework/AzQtComponents/AzQtComponents/azqtcomponents_files.cmake +++ b/Code/Framework/AzQtComponents/AzQtComponents/azqtcomponents_files.cmake @@ -8,6 +8,8 @@ set(FILES AzQtComponentsAPI.h + Application/AzQtApplication.cpp + Application/AzQtApplication.h Buses/DragAndDrop.h Buses/ShortcutDispatch.h DragAndDrop/MainWindowDragAndDrop.h diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Logger/TraceLogger.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Logger/TraceLogger.cpp new file mode 100644 index 0000000000..5f1546bf83 --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Logger/TraceLogger.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +#include +#include + + +namespace AzToolsFramework +{ + TraceLogger::TraceLogger() + { + AZ::Debug::TraceMessageBus::Handler::BusConnect(); + } + + TraceLogger::~TraceLogger() + { + AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); + } + + bool TraceLogger::OnOutput(const char* window, const char* message) + { + if (m_logFile) + { + m_logFile->AppendLog(AzFramework::LogFile::SEV_NORMAL, window, message); + } + else + { + m_startupLogSink.push_back({ window, message }); + } + return false; + } + + void TraceLogger::WriteStartupLog(const AZStd::string& logFileName) + { + using namespace AzFramework; + + AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); + AZ_Assert(fileIO != nullptr, "FileIO should be running at this point"); + + // There is no log system online so we have to create your own log file. + char resolveBuffer[AZ_MAX_PATH_LEN] = { 0 }; + fileIO->ResolvePath("@user@", resolveBuffer, AZ_MAX_PATH_LEN); + + // Note: @log@ hasn't been set at this point + AZStd::string logDirectory; + StringFunc::Path::Join(resolveBuffer, "log", logDirectory); + fileIO->SetAlias("@log@", logDirectory.c_str()); + + fileIO->CreatePath("@root@"); + fileIO->CreatePath("@user@"); + fileIO->CreatePath("@log@"); + + AZStd::string logPath; + StringFunc::Path::Join(logDirectory.c_str(), logFileName.c_str(), logPath); + + m_logFile.reset(aznew LogFile(logPath.c_str())); + if (m_logFile) + { + m_logFile->SetMachineReadable(false); + for (const LogMessage& message : m_startupLogSink) + { + m_logFile->AppendLog(LogFile::SEV_NORMAL, message.window.c_str(), message.message.c_str()); + } + m_startupLogSink = {}; + m_logFile->FlushLog(); + } + } +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Logger/TraceLogger.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Logger/TraceLogger.h new file mode 100644 index 0000000000..a10f4fc2df --- /dev/null +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Logger/TraceLogger.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include +#include + +namespace AzToolsFramework +{ + //! Connects and disconnects TraceMessageBus and allows for logging for O3DE Tools Applications + class TraceLogger + : public AZ::Debug::TraceMessageBus::Handler + { + public: + TraceLogger(); + ~TraceLogger(); + + //! Intalize logging for O3DEToolsApplications + void WriteStartupLog(const AZStd::string& logFileName); + + protected: + ////////////////////////////////////////////////////////////////////////// + // AZ::Debug::TraceMessageBus::Handler overrides... + bool OnOutput(const char* window, const char* message) override; + ////////////////////////////////////////////////////////////////////////// + + struct LogMessage + { + public: + AZStd::string window; + AZStd::string message; + }; + AZStd::vector m_startupLogSink; + AZStd::unique_ptr m_logFile; + }; +} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake index c5ae0e0c9c..1111020f48 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake @@ -148,6 +148,8 @@ set(FILES Entity/SliceEditorEntityOwnershipServiceBus.h Fingerprinting/TypeFingerprinter.h Fingerprinting/TypeFingerprinter.cpp + Logger/TraceLogger.cpp + Logger/TraceLogger.h Manipulators/AngularManipulator.cpp Manipulators/AngularManipulator.h Manipulators/BaseManipulator.cpp diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index 70a1877d32..10ad1df5f3 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -73,9 +73,9 @@ namespace MaterialEditor MaterialEditorApplication::MaterialEditorApplication(int* argc, char*** argv) : Application(argc, argv) - , QApplication(*argc, *argv) + , AzQtApplication(*argc, *argv) { - AZ::Debug::TraceMessageBus::Handler::BusConnect(); + QApplication::setApplicationName("O3DE Material Editor"); AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization( *AZ::SettingsRegistry::Get(), GetBuildTargetName()); @@ -89,10 +89,9 @@ namespace MaterialEditor MaterialEditorApplication::~MaterialEditorApplication() { - AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusDisconnect(); AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusDisconnect(); MaterialEditorWindowNotificationBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); + AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusDisconnect(); } void MaterialEditorApplication::CreateReflectionManager() @@ -357,42 +356,6 @@ namespace MaterialEditor } } - void MaterialEditorApplication::WriteStartupLog() - { - using namespace AzFramework; - - AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); - AZ_Assert(fileIO != nullptr, "FileIO should be running at this point"); - - // There is no log system online so we have to create your own log file. - char resolveBuffer[AZ_MAX_PATH_LEN] = { 0 }; - fileIO->ResolvePath("@user@", resolveBuffer, AZ_MAX_PATH_LEN); - - // Note: @log@ hasn't been set at this point - AZStd::string logDirectory; - StringFunc::Path::Join(resolveBuffer, "log", logDirectory); - fileIO->SetAlias("@log@", logDirectory.c_str()); - - fileIO->CreatePath("@root@"); - fileIO->CreatePath("@user@"); - fileIO->CreatePath("@log@"); - - AZStd::string logPath; - StringFunc::Path::Join(logDirectory.c_str(), "MaterialEditor.log", logPath); - - m_logFile.reset(aznew LogFile(logPath.c_str())); - if (m_logFile) - { - m_logFile->SetMachineReadable(false); - for (const LogMessage& message : m_startupLogSink) - { - m_logFile->AppendLog(LogFile::SEV_NORMAL, message.window.c_str(), message.message.c_str()); - } - m_startupLogSink = {}; - m_logFile->FlushLog(); - } - } - void MaterialEditorApplication::LoadSettings() { AZ::SerializeContext* context = nullptr; @@ -480,7 +443,7 @@ namespace MaterialEditor return; } - WriteStartupLog(); + m_traceLogger.WriteStartupLog("MaterialEditor.log"); if (!LaunchDiscoveryService()) { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h index 2269bd1a6d..e6fe9401f6 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h @@ -21,8 +21,9 @@ #include #include #include +#include +#include -#include #include namespace MaterialEditor @@ -31,7 +32,7 @@ namespace MaterialEditor class MaterialEditorApplication : public AzFramework::Application - , public QApplication + , public AzQtComponents::AzQtApplication , private AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler , private MaterialEditorWindowNotificationBus::Handler , private AzFramework::AssetSystemStatusBus::Handler @@ -100,12 +101,11 @@ namespace MaterialEditor ////////////////////////////////////////////////////////////////////////// // AZ::Debug::TraceMessageBus::Handler overrides... bool OnOutput(const char* window, const char* message) override; - ////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////// void CompileCriticalAssets(); void ProcessCommandLine(const AZ::CommandLine& commandLine); - void WriteStartupLog(); void LoadSettings(); void UnloadSettings(); @@ -125,6 +125,8 @@ namespace MaterialEditor AZStd::vector m_startupLogSink; AZStd::unique_ptr m_logFile; + AzToolsFramework::TraceLogger m_traceLogger; + //! Local user settings are used to store material browser tree expansion state AZ::UserSettingsProvider m_localUserSettings; diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/main.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/main.cpp index 0c4aff752c..47432ed83c 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/main.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/main.cpp @@ -25,21 +25,7 @@ int main(int argc, char** argv) { - QApplication::setOrganizationName("O3DE"); - QApplication::setOrganizationDomain("o3de.org"); - QApplication::setApplicationName("O3DE Material Editor"); - - AzQtComponents::PrepareQtPaths(); - - QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); - - // Must be set before QApplication is initialized, so that we support HighDpi monitors, like the Retina displays - // on Windows 10 - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); - QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); - QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); - AzQtComponents::Utilities::HandleDpiAwareness(AzQtComponents::Utilities::SystemDpiAware); + AzQtComponents::AzQtApplication::InitializeDpiScaling(); MaterialEditor::MaterialEditorApplication app(&argc, &argv); diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp index 1978d261aa..a39480637b 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp @@ -69,8 +69,10 @@ namespace ShaderManagementConsole ShaderManagementConsoleApplication::ShaderManagementConsoleApplication(int* argc, char*** argv) : Application(argc, argv) - , QApplication(*argc, *argv) + , AzQtApplication(*argc, *argv) { + QApplication::setApplicationName("O3DE Shader Management Console"); + // The settings registry has been created at this point, so add the CMake target AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization( *AZ::SettingsRegistry::Get(), GetBuildTargetName()); @@ -151,7 +153,6 @@ namespace ShaderManagementConsole { AzFramework::AssetSystemStatusBus::Handler::BusConnect(); AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusConnect(); - AZ::Debug::TraceMessageBus::Handler::BusConnect(); AzFramework::Application::StartCommon(systemEntity); @@ -163,7 +164,6 @@ namespace ShaderManagementConsole void ShaderManagementConsoleApplication::OnShaderManagementConsoleWindowClosing() { ExitMainLoop(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); ShaderManagementConsoleWindowNotificationBus::Handler::BusDisconnect(); AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusDisconnect(); } @@ -344,6 +344,8 @@ namespace ShaderManagementConsole return; } + m_traceLogger.WriteStartupLog("ShaderManagementConsole.log"); + //[GFX TODO][ATOM-415] Try to factor out some of this stuff with AtomSampleViewerApplication AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusConnect(); AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotificationBus::Broadcast(&AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotifications::OnDatabaseInitialized); diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h index eecc6231a7..a137e3a646 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h @@ -8,7 +8,6 @@ #pragma once - #include #include #include @@ -19,18 +18,20 @@ #include #include +#include #include #include -#include +#include + #include namespace ShaderManagementConsole { class ShaderManagementConsoleApplication : public AzFramework::Application - , public QApplication + , public AzQtComponents::AzQtApplication , private AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler , private ShaderManagementConsoleWindowNotificationBus::Handler , private AzFramework::AssetSystemStatusBus::Handler @@ -114,6 +115,8 @@ namespace ShaderManagementConsole static void PyIdleWaitFrames(uint32_t frames); + AzToolsFramework::TraceLogger m_traceLogger; + //! Local user settings are used to store asset browser tree expansion state AZ::UserSettingsProvider m_localUserSettings; diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/main.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/main.cpp index 0ca41d0d07..d6f017eee8 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/main.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/main.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -24,23 +25,10 @@ int main(int argc, char** argv) { - QApplication::setOrganizationName("O3DE"); - QApplication::setOrganizationDomain("o3de.com"); - QApplication::setApplicationName("O3DE Shader Management Console"); - - AzQtComponents::PrepareQtPaths(); - - QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); - - // Must be set before QApplication is initialized, so that we support HighDpi monitors, like the Retina displays - // on Windows 10 - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); - QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); - QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); - AzQtComponents::Utilities::HandleDpiAwareness(AzQtComponents::Utilities::PerScreenDpiAware); + AzQtComponents::AzQtApplication::InitializeDpiScaling(); ShaderManagementConsole::ShaderManagementConsoleApplication app(&argc, &argv); + AZ::IO::FixedMaxPath engineRootPath; if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) {