diff --git a/src/yycc/windows/dialog.cpp b/src/yycc/windows/dialog.cpp index c8fa924..b9c0a57 100644 --- a/src/yycc/windows/dialog.cpp +++ b/src/yycc/windows/dialog.cpp @@ -365,11 +365,11 @@ namespace yycc::windows::dialog { enum class GenericFileDialogType { OpenFile, OpenFiles, SaveFile, OpenFolder }; /** - * @brief Extract display name from given IShellItem*. - * @param[in] item The pointer to IShellItem for extracting. - * @return Extract display name, or error occurs. - * @remarks This is an assist function of generic_file_dialog(). - */ + * @brief Extract display name from given IShellItem*. + * @param[in] item The pointer to IShellItem for extracting. + * @return Extract display name, or error occurs. + * @remarks This is an assist function of generic_file_dialog(). + */ static DialogResult extract_display_name(IShellItem* item) { // fetch display name from IShellItem* LPWSTR display_name_ptr; @@ -382,14 +382,14 @@ namespace yycc::windows::dialog { } /** - * @brief Generic file dialog. + * @brief Generic file dialog. * @details This function is the real underlying function of all dialog functions. - * @param[in] params User specified parameter controlling the behavior of this file dialog, including title, file types and etc. - * @return + * @param[in] params User specified parameter controlling the behavior of this file dialog, including title, file types and etc. + * @return * The full path to user selected files or folders. - * For multiple selection, the count of items >= 1. For others, the count of item must be 1. + * For multiple selection, the count of items >= 1. For others, the count of item must be 1. * Or nothing (click "Cancel"), or error occurs. - */ + */ template static DialogResult>> generic_file_dialog(const FileDialog& params) { // Reference: https://learn.microsoft.com/en-us/windows/win32/shell/common-file-dialog diff --git a/src/yycc/windows/dialog.hpp b/src/yycc/windows/dialog.hpp index c2be9de..e3570a6 100644 --- a/src/yycc/windows/dialog.hpp +++ b/src/yycc/windows/dialog.hpp @@ -44,11 +44,11 @@ namespace yycc::windows::dialog { /** * @private - * @brief The class representing the file types region in file dialog. - * @details - * This class is private and served for Windows used. - * Programmer should \b not create this class manually. - */ + * @brief The class representing the file types region in file dialog. + * @details + * This class is private and served for Windows used. + * Programmer should \b not create this class manually. + */ class WinFileFilters { friend class FileFilters; @@ -87,13 +87,13 @@ namespace yycc::windows::dialog { }; /** - * @brief The class representing the file types region in file dialog. - * @details - * This class is served for programmer using. - * But you don't need create it on your own. - * You can simply fetch it by FileDialog::ConfigreFileTypes(), - * because this class is a part of FileDialog. - */ + * @brief The class representing the file types region in file dialog. + * @details + * This class is served for programmer using. + * But you don't need create it on your own. + * You can simply fetch it by FileDialog::ConfigreFileTypes(), + * because this class is a part of FileDialog. + */ class FileFilters { public: using FilterModes = std::vector; @@ -107,16 +107,16 @@ namespace yycc::windows::dialog { public: /** - * @brief Add a filter pair in file types list. - * @param[in] filter_name The friendly name of the filter. - * @param[in] il - * A C++ initialize list containing acceptable file filter pattern. - * Every entries must be a string representing a single filter pattern. - * This list at least should have one pattern. - * @return True if added success, otherwise false. + * @brief Add a filter pair in file types list. + * @param[in] filter_name The friendly name of the filter. + * @param[in] il + * A C++ initialize list containing acceptable file filter pattern. + * Every entries must be a string representing a single filter pattern. + * This list at least should have one pattern. + * @return True if added success, otherwise false. * @warning This function will not validate the content of these filter patterns, so please write them carefully. * @exception std::invalid_argument Given filtern name is blank, or filter patterns is empty. - */ + */ void add_filter(const std::u8string_view& filter_name, std::initializer_list il); /** * @brief Get the count of added file filters. @@ -141,11 +141,11 @@ namespace yycc::windows::dialog { /** * @private - * @brief The class representing the file dialog. - * @details - * This class is served for Windows used. - * Programmer should \b not create this class manually. - */ + * @brief The class representing the file dialog. + * @details + * This class is served for Windows used. + * Programmer should \b not create this class manually. + */ class WinFileDialog { friend class FileDialog; @@ -180,23 +180,23 @@ namespace yycc::windows::dialog { HWND m_WinOwner; WinFileFilters m_WinFileTypes; /** - * @brief The default selected file type in dialog - * @remarks - * This is 1-based index according to Windows specification. - * In other words, when generating this struct from FileDialog to this struct this field should plus 1. - * Because the same field located in FileDialog is 0-based index. - */ + * @brief The default selected file type in dialog + * @remarks + * This is 1-based index according to Windows specification. + * In other words, when generating this struct from FileDialog to this struct this field should plus 1. + * Because the same field located in FileDialog is 0-based index. + */ UINT m_WinDefaultFileTypeIndex; std::optional m_WinTitle, m_WinInitFileName; NS_YYCC_WINDOWS_COM::SmartIShellItem m_WinInitDirectory; }; /** - * @brief The class representing the file dialog. - * @details - * This class is served for programming using to describe every aspectes of the dialog. - * For how to use this struct, see \ref dialog_helper. - */ + * @brief The class representing the file dialog. + * @details + * This class is served for programming using to describe every aspectes of the dialog. + * For how to use this struct, see \ref dialog_helper. + */ class FileDialog { public: FileDialog(); @@ -204,50 +204,50 @@ namespace yycc::windows::dialog { YYCC_DEFAULT_COPY_MOVE(FileDialog) /** - * @brief Set the owner of dialog. - * @param[in] owner The \c HWND pointing to the owner of dialog, or NULL to remove owner. - */ + * @brief Set the owner of dialog. + * @param[in] owner The \c HWND pointing to the owner of dialog, or NULL to remove owner. + */ void set_owner(HWND owner); /** - * @brief Set custom title of dialog - * @param[in] title The string pointer to custom title. - */ + * @brief Set custom title of dialog + * @param[in] title The string pointer to custom title. + */ void set_title(const std::u8string_view& title); /** * @brief Remove custom title of dialog (keep system default) */ void unset_title(); /** - * @brief Set the initial file name of dialog - * @details If set, the file name will always be same one when opening dialog. - * @param[in] init_filename String pointer to initial file name. - */ + * @brief Set the initial file name of dialog + * @details If set, the file name will always be same one when opening dialog. + * @param[in] init_filename String pointer to initial file name. + */ void set_init_file_name(const std::u8string_view& init_filename); /** * @brief Remove custom initial file name of dialog (keep system default) */ void unset_init_file_name(); /** - * @brief Set the initial directory of dialog - * @details If set, the opended directory will always be the same one when opening dialog - * @param[in] init_dir String pointer to initial directory. - */ + * @brief Set the initial directory of dialog + * @details If set, the opended directory will always be the same one when opening dialog + * @param[in] init_dir String pointer to initial directory. + */ void set_init_directory(const std::u8string_view& init_dir); /** * @brief Remove custom initial directory of dialog (keep system default) */ void unset_init_directory(); /** - * @brief Fetch the struct describing file filters for future configuration. - * @return The reference to the struct describing file filters. - */ + * @brief Fetch the struct describing file filters for future configuration. + * @return The reference to the struct describing file filters. + */ FileFilters& configre_file_types(); /** - * @brief Set the index of default selected file filter. - * @param[in] idx - * The index to default file filter. - * This must be a valid index in file filters. - */ + * @brief Set the index of default selected file filter. + * @param[in] idx + * The index to default file filter. + * This must be a valid index in file filters. + */ void set_default_file_type_index(size_t idx); /** * @brief Clear file dialog parameters for following re-use. @@ -256,9 +256,9 @@ namespace yycc::windows::dialog { /** * @private - * @brief Build Windows used dialog info struct. - * @return Built Windows used struct, or error occurs. - */ + * @brief Build Windows used dialog info struct. + * @return Built Windows used struct, or error occurs. + */ DialogResult to_windows() const; protected: @@ -266,12 +266,12 @@ namespace yycc::windows::dialog { std::optional m_Title, m_InitFileName, m_InitDirectory; FileFilters m_FileTypes; /** - * @brief The default selected file type in dialog - * @remarks - * The index Windows used is 1-based index. - * But for universal experience, we order this is 0-based index. - * And do convertion when generating Windows used struct. - */ + * @brief The default selected file type in dialog + * @remarks + * The index Windows used is 1-based index. + * But for universal experience, we order this is 0-based index. + * And do convertion when generating Windows used struct. + */ size_t m_DefaultFileTypeIndex; }; @@ -286,28 +286,28 @@ namespace yycc::windows::dialog { using DialogOutcome = std::optional; /** - * @brief Open the dialog which order user select single file to open. - * @param[in] params The configuration of dialog. - * @return Full path to user selected file, or nothing (click "Cancel"), or error occurs. - */ + * @brief Open the dialog which order user select single file to open. + * @param[in] params The configuration of dialog. + * @return Full path to user selected file, or nothing (click "Cancel"), or error occurs. + */ DialogResult> open_file(const FileDialog& params); /** - * @brief Open the dialog which order user select multiple file to open. - * @param[in] params The configuration of dialog. - * @return The list of full path of user selected files, or nothing (click "Cancel"), or error occurs. - */ + * @brief Open the dialog which order user select multiple file to open. + * @param[in] params The configuration of dialog. + * @return The list of full path of user selected files, or nothing (click "Cancel"), or error occurs. + */ DialogResult>> open_files(const FileDialog& params); /** - * @brief Open the dialog which order user select single file to save. - * @param[in] params The configuration of dialog. - * @return Full path to user selected file, or nothing (click "Cancel"), or error occurs. - */ + * @brief Open the dialog which order user select single file to save. + * @param[in] params The configuration of dialog. + * @return Full path to user selected file, or nothing (click "Cancel"), or error occurs. + */ DialogResult> save_file(const FileDialog& params); /** - * @brief Open the dialog which order user select single directory to open. - * @param[in] params The configuration of dialog. - * @return Full path to user selected directory, or nothing (click "Cancel"), or error occurs. - */ + * @brief Open the dialog which order user select single directory to open. + * @param[in] params The configuration of dialog. + * @return Full path to user selected directory, or nothing (click "Cancel"), or error occurs. + */ DialogResult> open_folder(const FileDialog& params); } diff --git a/testbench/yycc/carton/tabulate.cpp b/testbench/yycc/carton/tabulate.cpp index 33596bd..99b1d28 100644 --- a/testbench/yycc/carton/tabulate.cpp +++ b/testbench/yycc/carton/tabulate.cpp @@ -1,13 +1,61 @@ #include #include #include +#include +#include #define TABULATE ::yycc::carton::tabulate +#define REINTERPRET ::yycc::string::reinterpret namespace yycctest::carton::tabulate { - TEST(CartonTabulate, Main) { - + class CartonTabulate : public ::testing::Test { + protected: + CartonTabulate() : table(3u), ss() { + // setup basic data + table.set_prefix(u8"# "); + table.set_header({u8"中文1", u8"中文2", u8"中文3"}); + table.set_bar(u8"==="); + table.add_row({u8"a", u8"b", u8"c"}); + } + ~CartonTabulate() override = default; + + void expected_print(const std::u8string_view& exp) { + ss.str(""); + table.print(ss); + EXPECT_EQ(REINTERPRET::as_utf8_view(ss.view()), exp); + } + + TABULATE::Tabulate table; + std::stringstream ss; + }; + + TEST_F(CartonTabulate, Full) { + table.show_header(true); + table.show_bar(true); + expected_print(u8"# 中文1 中文2 中文3 \n" + u8"# === === === \n" + u8"# a b c \n"); } -} + TEST_F(CartonTabulate, NoHeader) { + table.show_header(false); + table.show_bar(true); + expected_print(u8"# === === === \n" + u8"# a b c \n"); + } + + TEST_F(CartonTabulate, NoBar) { + table.show_header(true); + table.show_bar(false); + expected_print(u8"# 中文1 中文2 中文3 \n" + u8"# a b c \n"); + } + + TEST_F(CartonTabulate, OnlyData) { + table.show_header(false); + table.show_bar(false); + expected_print(u8"# a b c \n"); + } + +} // namespace yycctest::carton::tabulate