#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2023 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library 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 IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_PLATFORM_INTERACTION_TERMINALMESSAGESERVICE_H #define NUCLEX_PLATFORM_INTERACTION_TERMINALMESSAGESERVICE_H #include "Nuclex/Platform/Config.h" #include "Nuclex/Platform/Interaction/MessageService.h" #include // for std::unique_ptr namespace Nuclex { namespace Platform { namespace Interaction { // ------------------------------------------------------------------------------------------- // /// Shows notifications and questions in the default terminal (stdout) class NUCLEX_PLATFORM_TYPE TerminalMessageService : public MessageService { /// Initializes a new terminal message service public: NUCLEX_PLATFORM_API TerminalMessageService(); /// Frees all resources owned by the terminal message service public: NUCLEX_PLATFORM_API ~TerminalMessageService(); /// Whether the message service is manually word-wrapping lines /// True if the message service is currently word-wrapping lines public: NUCLEX_PLATFORM_API bool IsManuallyWordWrapping() const { return this->doManualWordWrapping; } /// Enables or disables manual word-wrapping of long lines /// True to enable manual word wrapping, false to disable it /// /// /// Depending on the target operating system and terminal application, the terminal may /// cut off long lines, simply have them overflow into the next line or word-wrap them /// like a text editor. /// /// /// If the target system's terminal does word wrapping or you don't mind simple /// overflow wrapping, it's usually best to leave this off because terminals can then /// re-wrap lines accordingly if the window / console buffer is resized. /// /// /// On the other hand, enabling this option will give you nice word-wrapped lines on /// all target systems, until the user resizes the window / console buffer and /// the manual line breaks make all past text break wrongly. /// /// public: NUCLEX_PLATFORM_API void EnableManualWordWrapping(bool enable = true); /// Whether the message service is currently using CR-LF line breaks /// True if the message service is using CR-LF line breaks public: NUCLEX_PLATFORM_API bool IsUsingWindowsLineBreaks() const { return this->useWindowsLineBreaks; } /// Enables or disables CR-LR line breaks /// True to enable CR-LF line breaks, false to use normal ones /// /// /// Short version: on Microsoft operating systems, a line break is generated by /// two characters, a carriage return followed by a line feed character. On Unix /// system, it's simply a line feed character alone. /// /// /// Historical computer systems were using teletype printers (think of an electric /// typewriter with a serial cable attached to it). After writing a line, the writing /// head had to be return to the beginning (carriage return) and then the paper had /// to be pulled forward by one line (line feed). /// /// /// In order to be able to directly print text files, operators commonly used CR-LF /// line endings. It was a crutch in a way, but a widely used one and so it found its /// way into DOS and from there, all Microsoft operating systems. Unix instead went /// straight with the sensible, but less-used approach, using a single line break byte. /// /// /// There are other line break types, but this library only targets Windows and Linux. /// This setting's default / initial value will vary depending on whether the library /// has been built for Windows (true) or Linux (false). /// /// public: NUCLEX_PLATFORM_API void EnableWindowsLineBreaks(bool enable = true); /// Displays a notification containing information to the user /// Topic of the information (normally used as the window title) /// Headline of the message (normally written in bold) /// Message text containing detailed informations public: NUCLEX_PLATFORM_API void Inform( const std::string &topic, const std::string &heading, const std::string &message ) override; /// Displays a warning to the user /// Topic of the warning (normally used as the window title) /// Headline of the message (normally written in bold) /// Message text containing more details public: NUCLEX_PLATFORM_API void Warn( const std::string &topic, const std::string &heading, const std::string &message ) override; /// Displays an error message to the user /// Topic of the error (normally used as the window title) /// Headline of the message (normally written in bold) /// Message text containing more details public: NUCLEX_PLATFORM_API void Complain( const std::string &topic, const std::string &heading, const std::string &message ) override; /// Displays a question to the user, answerable with either yes or no /// Topic of the question (normally used as the window title) /// Basic question being asked (normally written in bold) /// Message text elaborating in the question and actions /// True if the user answered yes, false if the user answered no public: NUCLEX_PLATFORM_API bool AskYesNo( const std::string &topic, const std::string &heading, const std::string &message ) override; /// /// Displays a confirmation prompt to the user, answerable with either ok or cancel /// /// Topic of the conformation (normally used as the window title) /// What the user has to confirm (normally written in bold) /// Message text elaborating the action to be confirmed /// True if the user answered ok, false if the user answered cancel public: NUCLEX_PLATFORM_API bool AskOkCancel( const std::string &topic, const std::string &heading, const std::string &message ) override; /// Displays a question to the user, answerable with yes, no or cancel /// Topic of the question (normally used as the window title) /// Basic question being asked (normally written in bold) /// Message text elaborating in the question and actions /// /// True if the user answered yes, false if the user answered no and nothing if /// the user wishes to cancel /// public: NUCLEX_PLATFORM_API std::optional AskYesNoCancel( const std::string &topic, const std::string &heading, const std::string &message ) override; /// Appends a message to the terminal using manual line wrapping /// Message that will be appended to the terminal /// Maximum width a line of text is allowed to have /// By how many spaces to indent after a line break private: void appendLineWrapped( const std::string &text, std::size_t lineWidth, std::size_t indent = 0 ); /// Whether the message service should do its own word-wrapping private: bool doManualWordWrapping; /// Whether the message service currently uses CR-LF line breaks private: bool useWindowsLineBreaks; /// Stores private data of the platform-dependent implementation private: class ImplementationData; /// Private data used by the platform-dependent implementation private: std::unique_ptr implementationData; }; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Platform::Interaction #endif // NUCLEX_PLATFORM_INTERACTION_TERMINALMESSAGESERVICE_H