feat: finish FileFilters class in dialog helper.
- finish FileFilters class representing the file types area in popup dialog.
This commit is contained in:
parent
b8a56efd7c
commit
359aff82ac
|
@ -2,9 +2,81 @@
|
||||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||||
|
|
||||||
#include "EncodingHelper.hpp"
|
#include "EncodingHelper.hpp"
|
||||||
|
#include "StringHelper.hpp"
|
||||||
|
|
||||||
namespace YYCC::DialogHelper {
|
namespace YYCC::DialogHelper {
|
||||||
|
|
||||||
|
#pragma region FileFilters
|
||||||
|
|
||||||
|
bool FileFilters::Add(const char* filter_name, std::initializer_list<const char*> il) {
|
||||||
|
// assign filter name
|
||||||
|
if (filter_name == nullptr) return false;
|
||||||
|
FilterName name(filter_name);
|
||||||
|
|
||||||
|
// assign filter patterns
|
||||||
|
FilterModes modes;
|
||||||
|
for (const char* pattern : il) {
|
||||||
|
if (pattern != nullptr) modes.emplace_back(std::string(pattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
// check filter patterns
|
||||||
|
if (modes.empty()) return false;
|
||||||
|
|
||||||
|
// add into pairs and return
|
||||||
|
m_Filters.emplace_back(std::make_pair(name, modes));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileFilters::Clear() {
|
||||||
|
m_Filters.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileFilters::Generate(UINT& filter_count, COMDLG_FILTERSPEC*& filter_specs) {
|
||||||
|
// init defualt value to prevent the scenario that caller do not check return value.
|
||||||
|
filter_count = 0u;
|
||||||
|
filter_specs = nullptr;
|
||||||
|
|
||||||
|
// clear win string vector and build new one
|
||||||
|
m_WinFilters.clear();
|
||||||
|
for (const auto& it : m_Filters) {
|
||||||
|
// convert name to wchar
|
||||||
|
WinFilterName name;
|
||||||
|
if (!YYCC::EncodingHelper::UTF8ToWchar(it.first.c_str(), name))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// convert pattern and join them
|
||||||
|
std::string joined_modes(YYCC::StringHelper::Join(it.second, u8";"));
|
||||||
|
WinFilterModes modes;
|
||||||
|
if (!YYCC::EncodingHelper::UTF8ToWchar(joined_modes.c_str(), modes))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// append new pair
|
||||||
|
m_WinFilters.emplace_back(std::make_pair(name, modes));
|
||||||
|
}
|
||||||
|
|
||||||
|
// check filter size
|
||||||
|
// if it overflow the maximum value, return false
|
||||||
|
size_t count = m_WinFilters.size();
|
||||||
|
if (count > std::numeric_limits<UINT>::max())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// create new win data struct
|
||||||
|
// and assign string pointer from internal built win string vector.
|
||||||
|
m_WinDataStruct.reset(new COMDLG_FILTERSPEC[count]);
|
||||||
|
for (size_t i = 0u; i < count; ++i) {
|
||||||
|
m_WinDataStruct[i].pszName = m_WinFilters[i].first.c_str();
|
||||||
|
m_WinDataStruct[i].pszSpec = m_WinFilters[i].second.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// set return value
|
||||||
|
filter_count = static_cast<UINT>(count);
|
||||||
|
filter_specs = m_WinDataStruct.get();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
|
||||||
//template<bool TIsOpen, bool TMultiSelection>
|
//template<bool TIsOpen, bool TMultiSelection>
|
||||||
//bool GeneralFileDialog(const FileDialogParameter& params, std::vector<std::string>& ret) {
|
//bool GeneralFileDialog(const FileDialogParameter& params, std::vector<std::string>& ret) {
|
||||||
// // make sure multi-selection only available in open mode
|
// // make sure multi-selection only available in open mode
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "WinImportPrefix.hpp"
|
#include "WinImportPrefix.hpp"
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
@ -13,6 +15,57 @@
|
||||||
|
|
||||||
namespace YYCC::DialogHelper {
|
namespace YYCC::DialogHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The class represent the file types region in file dialog.
|
||||||
|
*/
|
||||||
|
class FileFilters {
|
||||||
|
public:
|
||||||
|
FileFilters() :
|
||||||
|
m_Filters(),
|
||||||
|
m_WinFilters(), m_WinDataStruct(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add a filter pair in file types list.
|
||||||
|
* @param filter_name[in] The friendly name of the filter.
|
||||||
|
* @param il[in] A C++ initialize list.
|
||||||
|
* Every entries must be `const char*` represent a single filter pattern.
|
||||||
|
* The list at least should have one valid pattern.
|
||||||
|
* This function will not validate these filter patterns, so please write them carefully.
|
||||||
|
* @return True if added success, otherwise false.
|
||||||
|
* @remarks This function allow you register multiple filter patterns for single friendly name.
|
||||||
|
* For example: `Add("Microsoft Word (*.doc; *.docx)", {"*.doc", "*.docx"})`
|
||||||
|
*/
|
||||||
|
bool Add(const char* filter_name, std::initializer_list<const char*> il);
|
||||||
|
/**
|
||||||
|
* @brief Clear filter pairs for following re-use.
|
||||||
|
*/
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate Windows dialog system used data struct.
|
||||||
|
* @param filter_count[out] The count of generated filter data struct.
|
||||||
|
* @param filter_specs[out] The pointer to generated filter data struct.
|
||||||
|
* @remarks User should not call this function. This function is used by internal functions.
|
||||||
|
* @return True if generation is success, otherwise false.
|
||||||
|
*/
|
||||||
|
bool Generate(UINT& filter_count, COMDLG_FILTERSPEC*& filter_specs);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using FilterModes = std::vector<std::string>;
|
||||||
|
using FilterName = std::string;
|
||||||
|
using FilterPair = std::pair<FilterName, FilterModes>;
|
||||||
|
|
||||||
|
std::vector<FilterPair> m_Filters;
|
||||||
|
|
||||||
|
using WinFilterModes = std::wstring;
|
||||||
|
using WinFilterName = std::wstring;
|
||||||
|
using WinFilterPair = std::pair<WinFilterName, WinFilterModes>;
|
||||||
|
|
||||||
|
std::vector<WinFilterPair> m_WinFilters;
|
||||||
|
std::unique_ptr<COMDLG_FILTERSPEC[]> m_WinDataStruct;
|
||||||
|
};
|
||||||
|
|
||||||
//struct FileDialogParameter {
|
//struct FileDialogParameter {
|
||||||
// FileDialogParameter() :
|
// FileDialogParameter() :
|
||||||
// m_Owner(nullptr),
|
// m_Owner(nullptr),
|
||||||
|
|
|
@ -5,3 +5,4 @@
|
||||||
#include "StringHelper.hpp"
|
#include "StringHelper.hpp"
|
||||||
#include "EncodingHelper.hpp"
|
#include "EncodingHelper.hpp"
|
||||||
#include "TerminalHelper.hpp"
|
#include "TerminalHelper.hpp"
|
||||||
|
#include "DialogHelper.hpp"
|
||||||
|
|
|
@ -52,9 +52,23 @@ namespace Testbench {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void DialogTestbench() {
|
||||||
|
YYCC::DialogHelper::FileFilters test;
|
||||||
|
test.Add("Microsoft Word (*.docx; *.doc)", {"*.docx", "*.doc"});
|
||||||
|
test.Add("Microsoft Excel (*.xlsx; *.xls)", {"*.xlsx", "*.xls"});
|
||||||
|
test.Add("Microsoft PowerPoint (*.pptx; *.ppt)", {"*.pptx", "*.ppt"});
|
||||||
|
test.Add("Text File (*.*)", {"*.txt"});
|
||||||
|
test.Add("All Files (*.*)", {"*.*"});
|
||||||
|
|
||||||
|
UINT count;
|
||||||
|
COMDLG_FILTERSPEC* specs;
|
||||||
|
bool ret = test.Generate(count, specs);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** args) {
|
int main(int argc, char** args) {
|
||||||
Testbench::TerminalTestbench();
|
Testbench::TerminalTestbench();
|
||||||
Testbench::StringTestbench();
|
Testbench::StringTestbench();
|
||||||
|
Testbench::DialogTestbench();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user