123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770 |
- /*
- * 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
- *
- */
- // Description : implementation of the CLogFile class.
- #include "EditorDefs.h"
- #include "LogFile.h"
- // Qt
- #include <QTextEdit>
- #include <QScrollBar>
- #include <QListWidget>
- #include <QGuiApplication>
- #include <QScreen>
- // Editor
- #include "CryEdit.h" // for CCryEditApp
- #include "ProcessInfo.h" // for ProcessMemInfo
- #include "Controls/ConsoleSCB.h" // for CConsoleSCB
- #include <AzCore/std/ranges/ranges_algorithm.h>
- #include <stdarg.h>
- #if !defined(AZ_PLATFORM_WINDOWS)
- #include <time.h>
- #include <QTime>
- #else
- #include <Wbemidl.h>
- #pragma comment(lib, "wbemuuid.lib")
- #endif
- #if defined(AZ_PLATFORM_MAC)
- #include <mach/clock.h>
- #include <mach/mach.h>
- #include <Carbon/Carbon.h>
- #endif
- // Static member variables
- SANDBOX_API QListWidget* CLogFile::m_hWndListBox = nullptr;
- SANDBOX_API QTextEdit* CLogFile::m_hWndEditBox = nullptr;
- bool CLogFile::m_bShowMemUsage = false;
- bool CLogFile::m_bIsQuitting = false;
- //////////////////////////////////////////////////////////////////////////
- SANDBOX_API void Error(const char* format, ...)
- {
- va_list ArgList;
- va_start(ArgList, format);
- ErrorV(format, ArgList);
- va_end(ArgList);
- }
- //////////////////////////////////////////////////////////////////////////
- SANDBOX_API void ErrorV(const char* format, va_list argList)
- {
- char szBuffer[MAX_LOGBUFFER_SIZE];
- azvsnprintf(szBuffer, MAX_LOGBUFFER_SIZE, format, argList);
- QString str = "####-ERROR-####: ";
- str += szBuffer;
- CryWarning(VALIDATOR_MODULE_EDITOR, VALIDATOR_ERROR, "%s", str.toUtf8().data());
- if (!CCryEditApp::instance()->IsInTestMode() && !CCryEditApp::instance()->IsInExportMode() && !CCryEditApp::instance()->IsInLevelLoadTestMode())
- {
- if (gEnv && gEnv->pSystem)
- {
- gEnv->pSystem->ShowMessage(szBuffer, "Error", MB_OK | MB_ICONERROR | MB_APPLMODAL);
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////
- SANDBOX_API void Warning(const char* format, ...)
- {
- va_list ArgList;
- va_start(ArgList, format);
- WarningV(format, ArgList);
- va_end(ArgList);
- }
- //////////////////////////////////////////////////////////////////////////
- SANDBOX_API void WarningV(const char* format, va_list argList)
- {
- char szBuffer[MAX_LOGBUFFER_SIZE];
- azvsnprintf(szBuffer, MAX_LOGBUFFER_SIZE, format, argList);
- CryWarning(VALIDATOR_MODULE_EDITOR, VALIDATOR_WARNING, "%s", szBuffer);
- bool bNoUI = false;
- ICVar* pCVar = gEnv->pConsole->GetCVar("sys_no_crash_dialog");
- if (pCVar->GetIVal() != 0)
- {
- bNoUI = true;
- }
- if (!CCryEditApp::instance()->IsInTestMode() && !CCryEditApp::instance()->IsInExportMode() && !bNoUI)
- {
- if (gEnv && gEnv->pSystem)
- {
- gEnv->pSystem->ShowMessage(szBuffer, "Warning", MB_OK | MB_ICONWARNING | MB_APPLMODAL);
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////
- SANDBOX_API void Log(const char* format, ...)
- {
- va_list ArgList;
- va_start(ArgList, format);
- LogV(format, ArgList);
- va_end(ArgList);
- }
- //////////////////////////////////////////////////////////////////////////
- SANDBOX_API void LogV(const char* format, va_list argList)
- {
- char szBuffer[MAX_LOGBUFFER_SIZE];
- azvsnprintf(szBuffer, MAX_LOGBUFFER_SIZE, format, argList);
- CLogFile::WriteLine(szBuffer);
- }
- //////////////////////////////////////////////////////////////////////////
- const char* CLogFile::GetLogFileName()
- {
- if (gEnv && gEnv->pLog)
- {
- // Return the path
- return gEnv->pLog->GetFileName();
- }
- else
- {
- return "";
- }
- }
- void CLogFile::AttachListBox(QListWidget* hWndListBox)
- {
- m_hWndListBox = hWndListBox;
- }
- void CLogFile::AttachEditBox(QTextEdit* hWndEditBox)
- {
- m_hWndEditBox = hWndEditBox;
- }
- void CLogFile::FormatLine(const char * format, ...)
- {
- ////////////////////////////////////////////////////////////////////////
- // Write a line with printf style formatting
- ////////////////////////////////////////////////////////////////////////
- va_list ArgList;
- va_start(ArgList, format);
- FormatLineV(format, ArgList);
- va_end(ArgList);
- }
- void CLogFile::FormatLineV(const char * format, va_list argList)
- {
- char szBuffer[MAX_LOGBUFFER_SIZE];
- azvsnprintf(szBuffer, MAX_LOGBUFFER_SIZE, format, argList);
- CryLog("%s", szBuffer);
- }
- namespace LogFileInternal
- {
- #if defined(AZ_PLATFORM_WINDOWS)
- // Stores information about the OS queried from WMI
- struct OSInfo
- {
- // Stores the Name property from Win32_OperatingSystem
- AZStd::string m_name;
- // Stores the Version property from Win32_OperatingSystem
- AZStd::string m_version;
- };
- // This uses the GetVersionEx API which was deprecated in Windows 10
- // as a fall back to query the version information for Windows
- // On Windows 10 and after, this always returns the version as 6.2
- OSInfo QueryOSInfoUsingGetVersionEx()
- {
- OSInfo osInfo;
- OSVERSIONINFO osVersionInfo;
- osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- AZ_PUSH_DISABLE_WARNING(4996, "-Wunknown-warning-option")
- GetVersionEx(&osVersionInfo);
- AZ_POP_DISABLE_WARNING;
- // Default the name of the operating system to just Windows as the version information
- // is based on the manifest at the time application was built, which probably
- // does not match the current version of Windows that is running
- osInfo.m_name = "Windows";
- osInfo.m_version = AZStd::string::format("%ld.%ld", osVersionInfo.dwMajorVersion, osVersionInfo.dwMinorVersion);
- return osInfo;
- }
- // This specifically avoids using the GetVersion/GetVersionEx WinAPI
- // functions because those will only return the version of Windows
- // that was manifested at the time the application was built
- // and not the version of Windows that is currently running
- // https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getversion
- AZ::Outcome<OSInfo, AZStd::string> QueryOSInfoUsingWMI()
- {
- // Get the thread Id as an numeric value
- static_assert(sizeof(AZStd::thread_id) <= sizeof(uintptr_t), "Thread Id should less than a size of a pointer");
- // Using curly braces to zero initalize all bytes the uintptr_t
- // If the thread Id is < sizeof(uintptr_t), the high bytes would be zeroed out
- uintptr_t numericThreadId{};
- *reinterpret_cast<AZStd::thread_id*>(&numericThreadId) = AZStd::this_thread::get_id();
- OSInfo osInfo;
- // Query the Windows version using WMI
- HRESULT hResult = CoInitialize(nullptr);
- if (FAILED(hResult))
- {
- return AZ::Failure(AZStd::string::format(
- "Failed to initialize the Com library on thread %#" PRIxPTR ": %lu", numericThreadId, static_cast<unsigned long>(hResult)));
- }
- // Obtain the initial locator to Windows Management on a particular host computer.
- IWbemLocator* locator = nullptr;
- hResult = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&locator);
- if (FAILED(hResult))
- {
- return AZ::Failure(
- AZStd::string::format("Failed to create the Windows Management COM class: %lu", static_cast<unsigned long>(hResult)));
- }
- // Connect to the root\cimv2 namespace with the current user and obtain pointer pSvc to make IWbemServices calls.
- IWbemServices* services = nullptr;
- auto serverPath = SysAllocString(TEXT(R"(ROOT\CIMV2)"));
- hResult = locator->ConnectServer(serverPath, nullptr, nullptr, 0, 0, nullptr, nullptr, &services);
- SysFreeString(serverPath);
- if (FAILED(hResult))
- {
- return AZ::Failure(
- AZStd::string::format("Could not connect the WMI on the local machine: %lu", static_cast<unsigned long>(hResult)));
- }
- // Set the IWbemServices proxy so that impersonation of the user (client) occurs.
- hResult = CoSetProxyBlanket(
- services,
- RPC_C_AUTHN_WINNT,
- RPC_C_AUTHZ_NONE,
- nullptr,
- RPC_C_AUTHN_LEVEL_CALL,
- RPC_C_IMP_LEVEL_IMPERSONATE,
- nullptr,
- EOAC_NONE);
- if (FAILED(hResult))
- {
- return AZ::Failure(
- AZStd::string::format("Cannot impersonate current user for proxy call: %lu", static_cast<unsigned long>(hResult)));
- }
- IEnumWbemClassObject* classObjectEnumerator = nullptr;
- // query the Name and Version property from the Win32_OperatingSystem class
- // https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-operatingsystem
- AZStd::wstring propertyQuery{ L"SELECT Name,Version FROM Win32_OperatingSystem" };
- // ExecQuery expects BSTR types
- auto query = SysAllocString(propertyQuery.c_str());
- auto language = SysAllocString(L"WQL");
- hResult =
- services->ExecQuery(language, query, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, nullptr, &classObjectEnumerator);
- SysFreeString(language);
- SysFreeString(query);
- if (FAILED(hResult))
- {
- return AZ::Failure(AZStd::string::format(
- "WQL query from Win32_OperatingSystem WMI class has failed: %lu", static_cast<unsigned long>(hResult)));
- }
- // prepare to enumerate the object, blocking until the objects are ready
- IWbemClassObject* classObject = nullptr;
- ULONG numResults = 0;
- hResult = classObjectEnumerator->Next(WBEM_INFINITE, 1, &classObject, &numResults);
- if (FAILED(hResult))
- {
- return AZ::Failure(AZStd::string::format(
- "Enumerating the CIM objects has failed with result code: %lu", static_cast<unsigned long>(hResult)));
- }
- else if (classObject == nullptr || numResults == 0)
- {
- return AZ::Failure(AZStd::string(
- "There are no CIM objects found when querying the Win32_OperatingSystem class"));
- }
- constexpr const wchar_t* namePropertyName{ L"Name" };
- constexpr const wchar_t* versionPropertyName{ L"Version" };
- // get the class object's property value
- VARIANT propertyValue;
- // Query the Name field
- if (FAILED(classObject->Get(namePropertyName, 0, &propertyValue, nullptr, nullptr)))
- {
- return AZ::Failure(AZStd::string::format(
- R"(Could not retrieve the ")" AZ_TRAIT_FORMAT_STRING_PRINTF_WSTRING R"(" property from the CIM object: %lu)", namePropertyName, static_cast<unsigned long>(hResult)));
- }
- // If the name is a binary string copy it over
- if ((propertyValue.vt & VT_BSTR) == VT_BSTR)
- {
- AZStd::to_string(osInfo.m_name, V_BSTR(&propertyValue));
- }
- // VariantClear must be called on the variant retrieved from `IWbemClassObject::Get`
- // according to the documentation:
- // https://learn.microsoft.com/en-us/windows/win32/api/wbemcli/nf-wbemcli-iwbemclassobject-get
- VariantClear(&propertyValue);
- // Query the Version field
- if (FAILED(classObject->Get(versionPropertyName, 0, &propertyValue, nullptr, nullptr)))
- {
- {
- return AZ::Failure(AZStd::string::format(
- R"(Could not retrieve the ")" AZ_TRAIT_FORMAT_STRING_PRINTF_WSTRING R"(" property from the CIM object: %lu)", versionPropertyName, static_cast<unsigned long>(hResult)));
- }
- }
- // If the name is a binary string copy it over
- if ((propertyValue.vt & VT_BSTR) == VT_BSTR)
- {
- AZStd::to_string(osInfo.m_version, V_BSTR(&propertyValue));
- }
- // VariantClear must be called on the variant retrieved from `IWbemClassObject::Get`
- // according to the documentation:
- // https://learn.microsoft.com/en-us/windows/win32/api/wbemcli/nf-wbemcli-iwbemclassobject-get
- VariantClear(&propertyValue);
- if (classObject)
- {
- classObject->Release();
- }
- if (classObjectEnumerator)
- {
- classObjectEnumerator->Release();
- }
- if (services)
- {
- services->Release();
- }
- if (locator)
- {
- locator->Release();
- }
- CoUninitialize();
- return osInfo;
- }
- OSInfo QueryOSInfo()
- {
- auto queryOSInfoOutcome = QueryOSInfoUsingWMI();
- if (!queryOSInfoOutcome)
- {
- CryLog("Failed to query Windows version info using WMI with error: %s.\n"
- "Falling back to using GetVersionEx", queryOSInfoOutcome.GetError().c_str());
- return QueryOSInfoUsingGetVersionEx();
- }
- return queryOSInfoOutcome.GetValue();
- }
- #endif
- }
- void CLogFile::AboutSystem()
- {
- #if defined(AZ_PLATFORM_WINDOWS) || defined(AZ_PLATFORM_LINUX)
- //////////////////////////////////////////////////////////////////////
- // Write the system informations to the log
- //////////////////////////////////////////////////////////////////////
- char szBuffer[MAX_LOGBUFFER_SIZE];
- //wchar_t szCPUModel[64];
- MEMORYSTATUS MemoryStatus;
- #endif // defined(AZ_PLATFORM_WINDOWS) || defined(AZ_PLATFORM_LINUX)
- #if defined(AZ_PLATFORM_WINDOWS)
- wchar_t szLanguageBufferW[64];
- DEVMODE DisplayConfig;
- //////////////////////////////////////////////////////////////////////
- // Display editor and Windows version
- //////////////////////////////////////////////////////////////////////
- // Get system language
- GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT, LOCALE_SENGLANGUAGE,
- szLanguageBufferW, sizeof(szLanguageBufferW));
- AZStd::string szLanguageBuffer;
- AZStd::to_string(szLanguageBuffer, szLanguageBufferW);
- // Format and send OS information line
- azsnprintf(szBuffer, MAX_LOGBUFFER_SIZE, "Current Language: %s ", szLanguageBuffer.c_str());
- CryLog("%s", szBuffer);
- #else
- QLocale locale;
- CryLog("Current Language: %s (%s)", qPrintable(QLocale::languageToString(locale.language())), qPrintable(QLocale::countryToString(locale.country())));
- #endif
- #if defined(AZ_PLATFORM_WINDOWS)
- // Format and send OS version line
- auto osInfo = LogFileInternal::QueryOSInfo();
- QString str = QString("%1 %2").arg(osInfo.m_name.c_str()).arg(osInfo.m_version.c_str());
- //////////////////////////////////////////////////////////////////////
- // Show Windows directory
- //////////////////////////////////////////////////////////////////////
- CryLog("%s", str.toUtf8().data());
- #elif defined(AZ_PLATFORM_LINUX)
- // TODO: Add more detail about the current Linux Distro
- CryLog("Linux");
- #elif AZ_TRAIT_OS_PLATFORM_APPLE
- QString operatingSystemName;
- if (QSysInfo::MacintoshVersion >= Q_MV_OSX(10, 12))
- {
- operatingSystemName = "macOS ";
- }
- else
- {
- operatingSystemName = "OS X ";
- }
- int majorVersion = 0;
- int minorVersion = 0;
- AZ_PUSH_DISABLE_WARNING(, "-Wdeprecated-declarations")
- Gestalt(gestaltSystemVersionMajor, &majorVersion);
- Gestalt(gestaltSystemVersionMinor, &minorVersion);
- AZ_POP_DISABLE_WARNING
- CryLog("%s - %d.%d", qPrintable(operatingSystemName), majorVersion, minorVersion);
- #else
- CryLog("Unknown Operating System");
- #endif
- //////////////////////////////////////////////////////////////////////
- // Send system time & date
- //////////////////////////////////////////////////////////////////////
- #if defined(AZ_PLATFORM_WINDOWS)
- str = "Local time is ";
- azstrtime(szBuffer);
- str += szBuffer;
- str += " ";
- azstrdate(szBuffer);
- str += szBuffer;
- azsnprintf(szBuffer, MAX_LOGBUFFER_SIZE, ", system running for %ld minutes", GetTickCount() / 60000);
- str += szBuffer;
- CryLog("%s", str.toUtf8().data());
- #else
- struct timespec ts;
- #if AZ_TRAIT_OS_PLATFORM_APPLE
- clock_serv_t cclock;
- mach_timespec_t mts;
- host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
- clock_get_time(cclock, &mts);
- mach_port_deallocate(mach_task_self(), cclock);
- ts.tv_sec = mts.tv_sec;
- #else
- clock_gettime(CLOCK_MONOTONIC, &ts);
- #endif
- CryLog("Local time is %s, system running for %ld minutes", qPrintable(QTime::currentTime().toString("hh:mm:ss")), ts.tv_sec / 60);
- #endif
- //////////////////////////////////////////////////////////////////////
- // Send system memory status
- //////////////////////////////////////////////////////////////////////
- #if defined(AZ_PLATFORM_WINDOWS) || defined(AZ_PLATFORM_LINUX)
- GlobalMemoryStatus(&MemoryStatus);
- azsnprintf(szBuffer, MAX_LOGBUFFER_SIZE, "%zdMB phys. memory installed, %zdMB paging available",
- MemoryStatus.dwTotalPhys / 1048576 + 1,
- MemoryStatus.dwAvailPageFile / 1048576);
- CryLog("%s", szBuffer);
- #elif defined(AZ_PLATFORM_LINUX)
- //KDAB_TODO
- #else
- SInt32 mb = 0, lmb = 0;
- AZ_PUSH_DISABLE_WARNING(, "-Wdeprecated-declarations")
- Gestalt(gestaltPhysicalRAMSizeInMegabytes, &mb);
- Gestalt(gestaltLogicalRAMSize, &lmb);
- AZ_POP_DISABLE_WARNING
- CryLog("%dMB phys. memory installed, %dMB paging available", mb, lmb);
- #endif
- //////////////////////////////////////////////////////////////////////
- // Send display settings
- //////////////////////////////////////////////////////////////////////
- #if defined(AZ_PLATFORM_WINDOWS)
- EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &DisplayConfig);
- GetPrivateProfileStringW(L"boot.description", L"display.drv",
- L"(Unknown graphics card)", szLanguageBufferW, sizeof(szLanguageBufferW),
- L"system.ini");
- AZStd::to_string(szLanguageBuffer, szLanguageBufferW);
- azsnprintf(szBuffer, MAX_LOGBUFFER_SIZE, "Current display mode is %ldx%ldx%ld, %s",
- DisplayConfig.dmPelsWidth, DisplayConfig.dmPelsHeight,
- DisplayConfig.dmBitsPerPel, szLanguageBuffer.c_str());
- CryLog("%s", szBuffer);
- #else
- auto screen = QGuiApplication::primaryScreen();
- if (screen)
- {
- CryLog("Current display mode is %dx%dx%d, %s", screen->size().width(), screen->size().height(), screen->depth(), qPrintable(screen->name()));
- }
- #endif
- //////////////////////////////////////////////////////////////////////
- // Send input device configuration
- //////////////////////////////////////////////////////////////////////
- #if defined(AZ_PLATFORM_WINDOWS)
- str = "";
- // Detect the keyboard type
- switch (GetKeyboardType(0))
- {
- case 1:
- str = "IBM PC/XT (83-key)";
- break;
- case 2:
- str = "ICO (102-key)";
- break;
- case 3:
- str = "IBM PC/AT (84-key)";
- break;
- case 4:
- str = "IBM enhanced (101/102-key)";
- break;
- case 5:
- str = "Nokia 1050";
- break;
- case 6:
- str = "Nokia 9140";
- break;
- case 7:
- str = "Japanese";
- break;
- default:
- str = "Unknown";
- break;
- }
- // Any mouse attached ?
- if (!GetSystemMetrics(SM_MOUSEPRESENT))
- {
- CryLog("%s", (str + " keyboard and no mouse installed").toUtf8().data());
- }
- else
- {
- azsnprintf(szBuffer, MAX_LOGBUFFER_SIZE, " keyboard and %i+ button mouse installed",
- GetSystemMetrics(SM_CMOUSEBUTTONS));
- str += szBuffer;
- CryLog("%s", str.toUtf8().data());
- }
- CryLog("--------------------------------------------------------------------------------");
- #endif
- }
- //////////////////////////////////////////////////////////////////////////
- QString CLogFile::GetMemUsage()
- {
- AZ::ProcessMemInfo mi;
- AZ::QueryMemInfo(mi);
- constexpr int MB = 1024 * 1024;
- QString str;
- str = QStringLiteral("Memory=%1Mb, Pagefile=%2Mb").arg(mi.m_workingSet / MB).arg(mi.m_pagefileUsage / MB);
- //FormatLine( "PeakWorkingSet=%dMb, PeakPagefileUsage=%dMb",pc.PeakWorkingSetSize/MB,pc.PeakPagefileUsage/MB );
- //FormatLine( "PagedPoolUsage=%d",pc.QuotaPagedPoolUsage/MB );
- //FormatLine( "NonPagedPoolUsage=%d",pc.QuotaNonPagedPoolUsage/MB );
- return str;
- }
- //////////////////////////////////////////////////////////////////////////
- void CLogFile::WriteLine(const char* pszString)
- {
- CryLog("%s", pszString);
- }
- //////////////////////////////////////////////////////////////////////////
- void CLogFile::WriteString(const char* pszString)
- {
- if (gEnv && gEnv->pLog)
- {
- gEnv->pLog->LogAppendWithPrevLine("%s", pszString);
- }
- }
- static inline QString CopyAndRemoveColorCode(AZStd::string_view sText)
- {
- QByteArray ret(sText.data(), static_cast<int>(sText.size())); // alloc and copy
- char* s, * d;
- s = ret.data();
- d = s;
- // remove color code in place
- while (*s != 0)
- {
- if (*s == '$' && *(s + 1) >= '0' && *(s + 1) <= '9')
- {
- s += 2;
- continue;
- }
- *d++ = *s++;
- }
- ret.resize(static_cast<int>(d - ret.data()));
- return QString::fromLatin1(ret);
- }
- //////////////////////////////////////////////////////////////////////////
- void CLogFile::OnWriteToConsole(AZStd::string_view sText, bool bNewLine)
- {
- if (!gEnv)
- {
- return;
- }
- // if (GetIEditor()->IsInGameMode())
- // return;
- // Skip any non character.
- auto searchIt = AZStd::ranges::find_if(sText, [](char element) { return element >= 32; });
- sText = AZStd::string_view(searchIt, sText.end());
- // If we have a listbox attached, also output the string to this listbox
- if (m_hWndListBox)
- {
- QString str = CopyAndRemoveColorCode(sText); // editor prinout doesn't support color coded log messages
- if (m_bShowMemUsage)
- {
- str = QString("(") + GetMemUsage() + ")" + str;
- }
- // Add the string to the listbox
- m_hWndListBox->addItem(str);
- // Make sure the recently added string is visible
- m_hWndListBox->scrollToItem(m_hWndListBox->item(m_hWndListBox->count() - 1));
- if (m_hWndEditBox)
- {
- static int nCounter = 0;
- if (nCounter++ > 500)
- {
- // Clean Edit box every 500 lines.
- nCounter = 0;
- m_hWndEditBox->clear();
- }
- // remember selection and the top row
- int len = m_hWndEditBox->document()->toPlainText().length();
- int top = 0;
- int from = m_hWndEditBox->textCursor().selectionStart();
- int to = from + m_hWndEditBox->textCursor().selectionEnd();
- bool keepPos = false;
- if (from != len || to != len)
- {
- keepPos = m_hWndEditBox->hasFocus();
- if (keepPos)
- {
- top = m_hWndEditBox->verticalScrollBar()->value();
- }
- QTextCursor cur = m_hWndEditBox->textCursor();
- cur.setPosition(len);
- m_hWndEditBox->setTextCursor(cur);
- }
- if (bNewLine)
- {
- str = QString("\r\n") + str;
- str = str.trimmed();
- }
- m_hWndEditBox->textCursor().insertText(str);
- // restore selection and the top line
- if (keepPos)
- {
- QTextCursor cur = m_hWndEditBox->textCursor();
- cur.setPosition(from);
- cur.setPosition(to, QTextCursor::KeepAnchor);
- m_hWndEditBox->setTextCursor(cur);
- m_hWndEditBox->verticalScrollBar()->setValue(top);
- }
- }
- }
- if (CConsoleSCB::GetCreatedInstance())
- {
- const QString qtText = QString::fromUtf8(sText.data(), static_cast<int>(sText.size()));
- QString sOutLine(qtText);
- if (gSettings.bShowTimeInConsole)
- {
- char sTime[128];
- time_t ltime;
- time(<ime);
- struct tm today;
- #if AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS
- localtime_s(&today, <ime);
- #else
- today = *localtime(<ime);
- #endif
- strftime(sTime, sizeof(sTime), "<%H:%M:%S> ", &today);
- sOutLine = sTime;
- sOutLine += qtText;
- }
- CConsoleSCB::GetCreatedInstance()->AddToConsole(sOutLine, bNewLine);
- }
- else
- {
- // add to intermediate messages until an instance of CConsoleSCB exists
- CConsoleSCB::AddToPendingLines(QString::fromUtf8(sText.data(), static_cast<int>(sText.size())), bNewLine);
- }
- //////////////////////////////////////////////////////////////////////////
- // Look for exit messages while writing to the console
- //////////////////////////////////////////////////////////////////////////
- if (gEnv && gEnv->pSystem && !gEnv->pSystem->IsQuitting() && !m_bIsQuitting)
- {
- if (QCoreApplication::closingDown())
- {
- m_bIsQuitting = true;
- CCryEditApp::instance()->ExitInstance();
- m_bIsQuitting = false;
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CLogFile::OnWriteToFile([[maybe_unused]] AZStd::string_view sText, [[maybe_unused]] bool bNewLine)
- {
- }
|