/********************************************************************** Audacity: A Digital Audio Editor AudacityLogger.cpp ******************************************************************//** \class AudacityLogger \brief AudacityLogger is a thread-safe logger class Provides thread-safe logging based on the wxWidgets log facility. *//*******************************************************************/ #include "AudacityLogger.h" #include "Internat.h" #include "MemoryX.h" #include #include #include #include #include // // AudacityLogger class // // By providing an Audacity specific logging class, it can be made thread-safe and, // as such, can be used by the ever growing threading within Audacity. // AudacityLogger *AudacityLogger::Get() { static std::once_flag flag; std::call_once( flag, []{ // wxWidgets will clean up the logger for the main thread, so we can say // safenew. See: // http://docs.wxwidgets.org/3.0/classwx_log.html#a2525bf54fa3f31dc50e6e3cd8651e71d std::unique_ptr < wxLog > // DELETE any previous logger { wxLog::SetActiveTarget(safenew AudacityLogger) }; } ); // Use dynamic_cast so that we get a NULL ptr in case our logger // is no longer the target. return dynamic_cast(wxLog::GetActiveTarget()); } AudacityLogger::AudacityLogger() : wxEvtHandler(), wxLog() { mUpdated = false; } AudacityLogger::~AudacityLogger() = default; void AudacityLogger::Flush() { if (mUpdated && mListener && mListener()) mUpdated = false; } auto AudacityLogger::SetListener(Listener listener) -> Listener { auto result = std::move(mListener); mListener = std::move(listener); return result; } void AudacityLogger::DoLogText(const wxString & str) { if (!wxIsMainThread()) { wxMutexGuiEnter(); } if (mBuffer.empty()) { wxString stamp; TimeStamp(&stamp); mBuffer << stamp << _TS("Audacity ") << AUDACITY_VERSION_STRING << wxT("\n"); } mBuffer << str << wxT("\n"); mUpdated = true; Flush(); if (!wxIsMainThread()) { wxMutexGuiLeave(); } } bool AudacityLogger::SaveLog(const wxString &fileName) const { wxFFile file(fileName, wxT("w")); if (file.IsOpened()) { file.Write(mBuffer); file.Close(); return true; } return false; } bool AudacityLogger::ClearLog() { mBuffer = wxEmptyString; DoLogText(wxT("Log Cleared.")); return true; } wxString AudacityLogger::GetLog(int count) { if (count == 0) { return mBuffer; } wxString buffer; auto lines = wxStringTokenize(mBuffer, wxT("\r\n"), wxTOKEN_RET_DELIMS); for (int index = lines.size() - 1; index >= 0 && count > 0; --index, --count) { buffer.Prepend(lines[index]); } return buffer; }