Support for dynamic keyboard shortcuts added
This commit is contained in:
parent
f3c0e83d04
commit
5398ccbd5e
@ -7,7 +7,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalIncludeDirectories>..\lib\wxExtend\include;..\lib\stdex\include;..\lib\libZRCola\include</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\lib\wxExtend\include;..\lib\stdex\include;..\lib\libZRCola\include;..\lib\libZRColaUI\include</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
|
@ -57,6 +57,9 @@
|
|||||||
<ClInclude Include="stdafx.h" />
|
<ClInclude Include="stdafx.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\lib\libZRColaUI\build\libZRColaUI.vcxproj">
|
||||||
|
<Project>{c0a84bd2-3870-4cd6-b281-0ab322e3c579}</Project>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\lib\libZRCola\build\libZRCola.vcxproj">
|
<ProjectReference Include="..\lib\libZRCola\build\libZRCola.vcxproj">
|
||||||
<Project>{3c61929e-7289-4101-8d0a-da22d6e1aea8}</Project>
|
<Project>{3c61929e-7289-4101-8d0a-da22d6e1aea8}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
@ -29,10 +29,13 @@ ZRCola::DBSource::~DBSource()
|
|||||||
{
|
{
|
||||||
if (m_db)
|
if (m_db)
|
||||||
m_db->Close();
|
m_db->Close();
|
||||||
|
|
||||||
|
if (m_locale)
|
||||||
|
_free_locale(m_locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ZRCola::DBSource::Open(LPCTSTR _filename)
|
bool ZRCola::DBSource::Open(LPCTSTR filename)
|
||||||
{
|
{
|
||||||
wxASSERT_MSG(!m_db, wxT("database already open"));
|
wxASSERT_MSG(!m_db, wxT("database already open"));
|
||||||
|
|
||||||
@ -43,20 +46,21 @@ bool ZRCola::DBSource::Open(LPCTSTR _filename)
|
|||||||
std::wstring cn;
|
std::wstring cn;
|
||||||
cn = L"Driver={Microsoft Access Driver (*.mdb)};";
|
cn = L"Driver={Microsoft Access Driver (*.mdb)};";
|
||||||
cn += L"Dbq=";
|
cn += L"Dbq=";
|
||||||
cn += _filename;
|
cn += filename;
|
||||||
cn += L";Uid=;Pwd=;";
|
cn += L";Uid=;Pwd=;";
|
||||||
hr = m_db->Open(ATL::CComBSTR(cn.c_str()));
|
hr = m_db->Open(ATL::CComBSTR(cn.c_str()));
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
// Database open and ready.
|
// Database open and ready.
|
||||||
filename = _filename;
|
m_filename = filename;
|
||||||
|
m_locale = _create_locale(LC_ALL, "Slovenian_Slovenia.1250");
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
_ftprintf(stderr, wxT("%s: error ZCC0011: Could not open database (0x%x).\n"), (LPCTSTR)_filename, hr);
|
_ftprintf(stderr, wxT("%s: error ZCC0011: Could not open database (0x%x).\n"), (LPCTSTR)filename, hr);
|
||||||
LogErrors();
|
LogErrors();
|
||||||
}
|
}
|
||||||
m_db.Release();
|
m_db.Release();
|
||||||
} else
|
} else
|
||||||
_ftprintf(stderr, wxT("%s: error ZCC0012: Creating ADOConnection object failed (0x%x).\n"), (LPCTSTR)_filename, hr);
|
_ftprintf(stderr, wxT("%s: error ZCC0012: Creating ADOConnection object failed (0x%x).\n"), (LPCTSTR)filename, hr);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -95,7 +99,38 @@ void ZRCola::DBSource::LogErrors() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ZRCola::DBSource::GetUnicodeString(const CComPtr<ADOField>& f, std::wstring& str) const
|
bool ZRCola::DBSource::GetUnicodeCharacter(const ATL::CComPtr<ADOField>& f, wchar_t& chr) const
|
||||||
|
{
|
||||||
|
wxASSERT_MSG(f, wxT("field is empty"));
|
||||||
|
|
||||||
|
CComVariant v;
|
||||||
|
wxVERIFY(SUCCEEDED(f->get_Value(&v)));
|
||||||
|
|
||||||
|
// Parse the field. Must be exactly one Unicode code.
|
||||||
|
wxVERIFY(SUCCEEDED(v.ChangeType(VT_BSTR)));
|
||||||
|
UINT i = 0, n = ::SysStringLen(V_BSTR(&v));
|
||||||
|
chr = 0;
|
||||||
|
for (; i < n && V_BSTR(&v)[i]; i++) {
|
||||||
|
if (L'0' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'9') chr = chr*0x10 + (V_BSTR(&v)[i] - L'0');
|
||||||
|
else if (L'A' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'F') chr = chr*0x10 + (V_BSTR(&v)[i] - L'A' + 10);
|
||||||
|
else if (L'a' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'f') chr = chr*0x10 + (V_BSTR(&v)[i] - L'a' + 10);
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
if (i <= 0 && 4 < i) {
|
||||||
|
CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
|
||||||
|
_ftprintf(stderr, wxT("%s: error ZCC0030: Syntax error in \"%.*ls\" field (\"%.*ls\"). Unicode code must be one to four hexadecimal characters long.\n"), m_filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
|
||||||
|
return false;
|
||||||
|
} else if (i != n) {
|
||||||
|
CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
|
||||||
|
_ftprintf(stderr, wxT("%s: error ZCC0031: Syntax error in \"%.*ls\" field (\"%.*ls\"). Extra trailing characters.\n"), m_filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ZRCola::DBSource::GetUnicodeString(const ATL::CComPtr<ADOField>& f, std::wstring& str) const
|
||||||
{
|
{
|
||||||
wxASSERT_MSG(f, wxT("field is empty"));
|
wxASSERT_MSG(f, wxT("field is empty"));
|
||||||
|
|
||||||
@ -117,45 +152,64 @@ bool ZRCola::DBSource::GetUnicodeString(const CComPtr<ADOField>& f, std::wstring
|
|||||||
}
|
}
|
||||||
if (j <= 0 || 4 < j) {
|
if (j <= 0 || 4 < j) {
|
||||||
CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
|
CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
|
||||||
_ftprintf(stderr, wxT("%s: error ZCC0020: Syntax error in \"%.*ls\" field (\"%.*ls\"). Unicode code must be one to four hexadecimal characters long.\n"), filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
|
_ftprintf(stderr, wxT("%s: error ZCC0020: Syntax error in \"%.*ls\" field (\"%.*ls\"). Unicode code must be one to four hexadecimal characters long.\n"), m_filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
str += c;
|
str += c;
|
||||||
|
|
||||||
// Skip delimiter(s) and whitespace.
|
// Skip delimiter(s) and whitespace.
|
||||||
for (; i < n && V_BSTR(&v)[i] && (V_BSTR(&v)[i] == L'+' || iswspace(V_BSTR(&v)[i])); i++);
|
for (; i < n && V_BSTR(&v)[i] && (V_BSTR(&v)[i] == L'+' || _iswspace_l(V_BSTR(&v)[i], m_locale)); i++);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ZRCola::DBSource::GetUnicodeCharacter(const CComPtr<ADOField>& f, wchar_t& chr) const
|
bool ZRCola::DBSource::GetKeySequence(const ATL::CComPtr<ADOField>& f, std::vector<keyseq::keycode>& seq) const
|
||||||
{
|
{
|
||||||
wxASSERT_MSG(f, wxT("field is empty"));
|
wxASSERT_MSG(f, wxT("field is empty"));
|
||||||
|
|
||||||
CComVariant v;
|
CComVariant v;
|
||||||
wxVERIFY(SUCCEEDED(f->get_Value(&v)));
|
wxVERIFY(SUCCEEDED(f->get_Value(&v)));
|
||||||
|
|
||||||
// Parse the field. Must be exactly one Unicode code.
|
|
||||||
wxVERIFY(SUCCEEDED(v.ChangeType(VT_BSTR)));
|
wxVERIFY(SUCCEEDED(v.ChangeType(VT_BSTR)));
|
||||||
UINT i = 0, n = ::SysStringLen(V_BSTR(&v));
|
|
||||||
chr = 0;
|
// Convert to uppercase.
|
||||||
for (; i < n && V_BSTR(&v)[i]; i++) {
|
_wcsupr_l(V_BSTR(&v), m_locale);
|
||||||
if (L'0' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'9') chr = chr*0x10 + (V_BSTR(&v)[i] - L'0');
|
|
||||||
else if (L'A' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'F') chr = chr*0x10 + (V_BSTR(&v)[i] - L'A' + 10);
|
// Parse the field. Must be comma delimited sequence of key codes.
|
||||||
else if (L'a' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'f') chr = chr*0x10 + (V_BSTR(&v)[i] - L'a' + 10);
|
seq.clear();
|
||||||
else break;
|
for (UINT i = 0, n = ::SysStringLen(V_BSTR(&v)); i < n && V_BSTR(&v)[i];) {
|
||||||
|
keyseq::keycode kc = {};
|
||||||
|
|
||||||
|
while (i < n && V_BSTR(&v)[i]) {
|
||||||
|
// Parse key code.
|
||||||
|
static const wchar_t str_shift[] = L"SHIFT+", str_ctrl[] = L"CTRL+", str_alt[] = L"ALT+";
|
||||||
|
if (i + _countof(str_shift) <= n && wmemcmp(V_BSTR(&v) + i, str_shift, _countof(str_shift) - 1) == 0) {
|
||||||
|
kc.shift = true;
|
||||||
|
i += _countof(str_shift) - 1;
|
||||||
|
} else if (i + _countof(str_ctrl) <= n && wmemcmp(V_BSTR(&v) + i, str_ctrl, _countof(str_ctrl) - 1) == 0) {
|
||||||
|
kc.ctrl = true;
|
||||||
|
i += _countof(str_ctrl) - 1;
|
||||||
|
} else if (i + _countof(str_alt) <= n && wmemcmp(V_BSTR(&v) + i, str_alt, _countof(str_alt) - 1) == 0) {
|
||||||
|
kc.alt = true;
|
||||||
|
i += _countof(str_alt) - 1;
|
||||||
|
} else {
|
||||||
|
kc.key = V_BSTR(&v)[i];
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (i <= 0 && 4 < i) {
|
}
|
||||||
|
if (i < n && V_BSTR(&v)[i] && V_BSTR(&v)[i] != L',' && !_iswspace_l(V_BSTR(&v)[i], m_locale)) {
|
||||||
CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
|
CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
|
||||||
_ftprintf(stderr, wxT("%s: error ZCC0030: Syntax error in \"%.*ls\" field (\"%.*ls\"). Unicode code must be one to four hexadecimal characters long.\n"), filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
|
_ftprintf(stderr, wxT("%s: error ZCC0060: Syntax error in \"%.*ls\" field (\"%.*ls\"). Key sequences must be \"Ctrl+Alt+<key>\" formatted, delimited by commas and/or space.\n"), m_filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
|
||||||
return false;
|
|
||||||
} else if (i != n) {
|
|
||||||
CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
|
|
||||||
_ftprintf(stderr, wxT("%s: error ZCC0031: Syntax error in \"%.*ls\" field (\"%.*ls\"). Extra trailing characters.\n"), filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
seq.push_back(kc);
|
||||||
|
|
||||||
|
// Skip delimiter(s) and whitespace.
|
||||||
|
for (; i < n && V_BSTR(&v)[i] && (V_BSTR(&v)[i] == L',' || _iswspace_l(V_BSTR(&v)[i], m_locale)); i++);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -169,7 +223,7 @@ bool ZRCola::DBSource::SelectTranslations(ATL::CComPtr<ADORecordset> &rs) const
|
|||||||
|
|
||||||
// Open it.
|
// Open it.
|
||||||
if (FAILED(rs->Open(ATL::CComVariant(L"SELECT [komb], [znak] FROM [VRS_ReplChar] WHERE [rang_komb]=1"), ATL::CComVariant(m_db), adOpenStatic, adLockReadOnly, adCmdText))) {
|
if (FAILED(rs->Open(ATL::CComVariant(L"SELECT [komb], [znak] FROM [VRS_ReplChar] WHERE [rang_komb]=1"), ATL::CComVariant(m_db), adOpenStatic, adLockReadOnly, adCmdText))) {
|
||||||
_ftprintf(stderr, wxT("%s: error ZCC0040: Error loading compositions from database. Please make sure the file is ZRCola.zrc compatible.\n"), filename.c_str());
|
_ftprintf(stderr, wxT("%s: error ZCC0040: Error loading compositions from database. Please make sure the file is ZRCola.zrc compatible.\n"), m_filename.c_str());
|
||||||
LogErrors();
|
LogErrors();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -182,20 +236,60 @@ bool ZRCola::DBSource::GetTranslation(const ATL::CComPtr<ADORecordset>& rs, ZRCo
|
|||||||
{
|
{
|
||||||
wxASSERT_MSG(rs, wxT("recordset is empty"));
|
wxASSERT_MSG(rs, wxT("recordset is empty"));
|
||||||
|
|
||||||
CComPtr<ADOFields> flds;
|
ATL::CComPtr<ADOFields> flds;
|
||||||
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
|
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
|
||||||
|
|
||||||
{
|
{
|
||||||
CComPtr<ADOField> f;
|
ATL::CComPtr<ADOField> f;
|
||||||
wxVERIFY(SUCCEEDED(flds->get_Item(CComVariant(L"komb"), &f)));
|
wxVERIFY(SUCCEEDED(flds->get_Item(CComVariant(L"komb"), &f)));
|
||||||
wxCHECK(GetUnicodeString(f, t.str), false);
|
wxCHECK(GetUnicodeString(f, t.str), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
CComPtr<ADOField> f;
|
ATL::CComPtr<ADOField> f;
|
||||||
wxVERIFY(SUCCEEDED(flds->get_Item(CComVariant(L"znak"), &f)));
|
wxVERIFY(SUCCEEDED(flds->get_Item(CComVariant(L"znak"), &f)));
|
||||||
wxCHECK(GetUnicodeCharacter(f, t.chr), false);
|
wxCHECK(GetUnicodeCharacter(f, t.chr), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ZRCola::DBSource::SelectKeySequences(ATL::CComPtr<ADORecordset> &rs) const
|
||||||
|
{
|
||||||
|
// Create a new recordset.
|
||||||
|
if (rs) rs.Release();
|
||||||
|
wxCHECK(SUCCEEDED(::CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_ALL, IID_IADORecordset, (LPVOID*)&rs)), false);
|
||||||
|
|
||||||
|
// Open it.
|
||||||
|
if (FAILED(rs->Open(ATL::CComVariant(L"SELECT [Znak], [tipka] FROM [wrd_KeyCodes]"), ATL::CComVariant(m_db), adOpenStatic, adLockReadOnly, adCmdText))) {
|
||||||
|
_ftprintf(stderr, wxT("%s: error ZCC0050: Error loading key sequences from database. Please make sure the file is ZRCola.zrc compatible.\n"), m_filename.c_str());
|
||||||
|
LogErrors();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ZRCola::DBSource::GetKeySequence(const ATL::CComPtr<ADORecordset>& rs, ZRCola::DBSource::keyseq& ks) const
|
||||||
|
{
|
||||||
|
wxASSERT_MSG(rs, wxT("recordset is empty"));
|
||||||
|
|
||||||
|
ATL::CComPtr<ADOFields> flds;
|
||||||
|
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
|
||||||
|
|
||||||
|
{
|
||||||
|
ATL::CComPtr<ADOField> f;
|
||||||
|
wxVERIFY(SUCCEEDED(flds->get_Item(CComVariant(L"Znak"), &f)));
|
||||||
|
wxCHECK(GetUnicodeCharacter(f, ks.chr), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
ATL::CComPtr<ADOField> f;
|
||||||
|
wxVERIFY(SUCCEEDED(flds->get_Item(CComVariant(L"tipka"), &f)));
|
||||||
|
wxCHECK(GetKeySequence(f, ks.seq), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <atlbase.h>
|
#include <atlbase.h>
|
||||||
#include <adoint.h>
|
#include <adoint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
namespace ZRCola {
|
namespace ZRCola {
|
||||||
@ -40,6 +41,27 @@ namespace ZRCola {
|
|||||||
std::wstring str; ///< Decomposed string
|
std::wstring str; ///< Decomposed string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Key sequence
|
||||||
|
///
|
||||||
|
class keyseq {
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
/// Key code
|
||||||
|
///
|
||||||
|
struct keycode {
|
||||||
|
wchar_t key; ///< Key
|
||||||
|
bool shift; ///< Shift modifier
|
||||||
|
bool ctrl; ///< Ctrl modifier
|
||||||
|
bool alt; ///< Alt modifier
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
wchar_t chr; ///< Character
|
||||||
|
std::vector<keycode> seq; ///< Key sequence
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DBSource();
|
DBSource();
|
||||||
virtual ~DBSource();
|
virtual ~DBSource();
|
||||||
@ -93,19 +115,6 @@ namespace ZRCola {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Gets encoded Unicode string from ZRCola.zrc database
|
|
||||||
///
|
|
||||||
/// \param[in] f Data field
|
|
||||||
/// \param[out] str Output string
|
|
||||||
///
|
|
||||||
/// \returns
|
|
||||||
/// - true when successful
|
|
||||||
/// - false otherwise
|
|
||||||
///
|
|
||||||
bool GetUnicodeString(const CComPtr<ADOField>& f, std::wstring& str) const;
|
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Gets encoded Unicode character from ZRCola.zrc database
|
/// Gets encoded Unicode character from ZRCola.zrc database
|
||||||
///
|
///
|
||||||
@ -116,7 +125,33 @@ namespace ZRCola {
|
|||||||
/// - true when successful
|
/// - true when successful
|
||||||
/// - false otherwise
|
/// - false otherwise
|
||||||
///
|
///
|
||||||
bool GetUnicodeCharacter(const CComPtr<ADOField>& f, wchar_t& chr) const;
|
bool GetUnicodeCharacter(const ATL::CComPtr<ADOField>& f, wchar_t& chr) const;
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Gets encoded Unicode string from ZRCola.zrc database
|
||||||
|
///
|
||||||
|
/// \param[in] f Data field
|
||||||
|
/// \param[out] str Output string
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true when successful
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
bool GetUnicodeString(const ATL::CComPtr<ADOField>& f, std::wstring& str) const;
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Gets encoded key sequence from ZRCola.zrc database
|
||||||
|
///
|
||||||
|
/// \param[in] f Data field
|
||||||
|
/// \param[out] seq Output sequence
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true when successful
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
bool GetKeySequence(const ATL::CComPtr<ADOField>& f, std::vector<keyseq::keycode>& seq) const;
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -143,8 +178,34 @@ namespace ZRCola {
|
|||||||
///
|
///
|
||||||
bool GetTranslation(const ATL::CComPtr<ADORecordset>& rs, translation& t) const;
|
bool GetTranslation(const ATL::CComPtr<ADORecordset>& rs, translation& t) const;
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns key sequences
|
||||||
|
///
|
||||||
|
/// \param[out] rs Recordset with results
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true when query succeeds
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
bool SelectKeySequences(ATL::CComPtr<ADORecordset>& rs) const;
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns key sequence data
|
||||||
|
///
|
||||||
|
/// \param[in] rs Recordset with results
|
||||||
|
/// \param[out] ks Key sequence
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - true when succeeded
|
||||||
|
/// - false otherwise
|
||||||
|
///
|
||||||
|
bool GetKeySequence(const ATL::CComPtr<ADORecordset>& rs, keyseq& ks) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::basic_string<TCHAR> filename; ///< the database filename
|
std::basic_string<TCHAR> m_filename; ///< Database filename
|
||||||
ATL::CComPtr<ADOConnection> m_db; ///< the database
|
ATL::CComPtr<ADOConnection> m_db; ///< Database
|
||||||
|
_locale_t m_locale; ///< Database locale
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -24,18 +24,18 @@
|
|||||||
/// Writes translation database to a stream
|
/// Writes translation database to a stream
|
||||||
///
|
///
|
||||||
/// \param[in] stream Output stream
|
/// \param[in] stream Output stream
|
||||||
/// \param[in] t_db Translation database
|
/// \param[in] db Translation database
|
||||||
///
|
///
|
||||||
/// \returns The stream \p stream
|
/// \returns The stream \p stream
|
||||||
///
|
///
|
||||||
inline std::ostream& operator <<(std::ostream& stream, const ZRCola::translation_db &t_db)
|
inline std::ostream& operator <<(std::ostream& stream, const ZRCola::translation_db &db)
|
||||||
{
|
{
|
||||||
assert(t_db.idxComp.size() == t_db.idxDecomp.size());
|
assert(db.idxComp.size() == db.idxDecomp.size());
|
||||||
|
|
||||||
unsigned __int32 count;
|
unsigned __int32 count;
|
||||||
|
|
||||||
// Write index count.
|
// Write index count.
|
||||||
std::vector<unsigned __int32>::size_type trans_count = t_db.idxComp.size();
|
std::vector<unsigned __int32>::size_type trans_count = db.idxComp.size();
|
||||||
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
|
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
|
||||||
// 4G check
|
// 4G check
|
||||||
if (trans_count > 0xffffffff) {
|
if (trans_count > 0xffffffff) {
|
||||||
@ -49,14 +49,14 @@ inline std::ostream& operator <<(std::ostream& stream, const ZRCola::translation
|
|||||||
|
|
||||||
// Write composition index.
|
// Write composition index.
|
||||||
if (stream.fail()) return stream;
|
if (stream.fail()) return stream;
|
||||||
stream.write((const char*)t_db.idxComp.data(), sizeof(unsigned __int32)*count);
|
stream.write((const char*)db.idxComp.data(), sizeof(unsigned __int32)*count);
|
||||||
|
|
||||||
// Write decomposition index.
|
// Write decomposition index.
|
||||||
if (stream.fail()) return stream;
|
if (stream.fail()) return stream;
|
||||||
stream.write((const char*)t_db.idxDecomp.data(), sizeof(unsigned __int32)*count);
|
stream.write((const char*)db.idxDecomp.data(), sizeof(unsigned __int32)*count);
|
||||||
|
|
||||||
// Write data count.
|
// Write data count.
|
||||||
std::vector<wchar_t>::size_type data_count = t_db.data.size();
|
std::vector<unsigned __int16>::size_type data_count = db.data.size();
|
||||||
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
|
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
|
||||||
// 4G check
|
// 4G check
|
||||||
if (data_count > 0xffffffff) {
|
if (data_count > 0xffffffff) {
|
||||||
@ -70,7 +70,63 @@ inline std::ostream& operator <<(std::ostream& stream, const ZRCola::translation
|
|||||||
|
|
||||||
// Write data.
|
// Write data.
|
||||||
if (stream.fail()) return stream;
|
if (stream.fail()) return stream;
|
||||||
stream.write((const char*)t_db.data.data(), sizeof(wchar_t)*count);
|
stream.write((const char*)db.data.data(), sizeof(unsigned __int16)*count);
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Writes key sequence database to a stream
|
||||||
|
///
|
||||||
|
/// \param[in] stream Output stream
|
||||||
|
/// \param[in] db Key sequence database
|
||||||
|
///
|
||||||
|
/// \returns The stream \p stream
|
||||||
|
///
|
||||||
|
inline std::ostream& operator <<(std::ostream& stream, const ZRCola::keyseq_db &db)
|
||||||
|
{
|
||||||
|
assert(db.idxChr.size() == db.idxKey.size());
|
||||||
|
|
||||||
|
unsigned __int32 count;
|
||||||
|
|
||||||
|
// Write index count.
|
||||||
|
std::vector<unsigned __int32>::size_type ks_count = db.idxChr.size();
|
||||||
|
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
|
||||||
|
// 4G check
|
||||||
|
if (ks_count > 0xffffffff) {
|
||||||
|
stream.setstate(std::ios_base::failbit);
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (stream.fail()) return stream;
|
||||||
|
count = (unsigned __int32)ks_count;
|
||||||
|
stream.write((const char*)&count, sizeof(count));
|
||||||
|
|
||||||
|
// Write character index.
|
||||||
|
if (stream.fail()) return stream;
|
||||||
|
stream.write((const char*)db.idxChr.data(), sizeof(unsigned __int32)*count);
|
||||||
|
|
||||||
|
// Write key index.
|
||||||
|
if (stream.fail()) return stream;
|
||||||
|
stream.write((const char*)db.idxKey.data(), sizeof(unsigned __int32)*count);
|
||||||
|
|
||||||
|
// Write data count.
|
||||||
|
std::vector<unsigned __int16>::size_type data_count = db.data.size();
|
||||||
|
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
|
||||||
|
// 4G check
|
||||||
|
if (data_count > 0xffffffff) {
|
||||||
|
stream.setstate(std::ios_base::failbit);
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (stream.fail()) return stream;
|
||||||
|
count = (unsigned __int32)data_count;
|
||||||
|
stream.write((const char*)&count, sizeof(count));
|
||||||
|
|
||||||
|
// Write data.
|
||||||
|
if (stream.fail()) return stream;
|
||||||
|
stream.write((const char*)db.data.data(), sizeof(unsigned __int16)*count);
|
||||||
|
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
@ -93,17 +149,42 @@ inline std::ostream& operator <<(std::ostream& stream, const ZRCola::translation
|
|||||||
/// The function does not treat \\0 characters as terminators for performance reasons.
|
/// The function does not treat \\0 characters as terminators for performance reasons.
|
||||||
/// Therefore \p count_a and \p count_b must represent exact string lengths.
|
/// Therefore \p count_a and \p count_b must represent exact string lengths.
|
||||||
///
|
///
|
||||||
static inline int CompareBinary(const wchar_t *str_a, size_t count_a, const wchar_t *str_b, size_t count_b)
|
static inline int CompareSequence(const wchar_t *str_a, size_t count_a, const wchar_t *str_b, size_t count_b)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; ; i++) {
|
for (size_t i = 0; ; i++) {
|
||||||
if (i >= count_a && i >= count_b) break;
|
if (i >= count_a && i >= count_b) return 0;
|
||||||
else if (i >= count_a && i < count_b) return -1;
|
else if (i >= count_a && i < count_b) return -1;
|
||||||
else if (i < count_a && i >= count_b) return +1;
|
else if (i < count_a && i >= count_b) return +1;
|
||||||
else if (str_a[i] < str_b[i]) return -1;
|
else if (str_a[i] < str_b[i]) return -1;
|
||||||
else if (str_a[i] > str_b[i]) return +1;
|
else if (str_a[i] > str_b[i]) return +1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
///
|
||||||
|
/// Compares two key sequences
|
||||||
|
///
|
||||||
|
/// \param[in] seq_a First key sequence
|
||||||
|
/// \param[in] count_a Number of keys in sequence \p seq_a
|
||||||
|
/// \param[in] seq_b Second key sequence
|
||||||
|
/// \param[in] count_b Number of keys in sequence \p seq_b
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - <0 when seq_a < seq_b
|
||||||
|
/// - =0 when seq_a == seq_b
|
||||||
|
/// - >0 when seq_a > seq_b
|
||||||
|
///
|
||||||
|
static inline int CompareSequence(const ZRCola::keyseq_db::keyseq::key_t *seq_a, size_t count_a, const ZRCola::keyseq_db::keyseq::key_t *seq_b, size_t count_b)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; ; i++) {
|
||||||
|
if (i >= count_a && i >= count_b) return 0;
|
||||||
|
else if (i >= count_a && i < count_b) return -1;
|
||||||
|
else if (i < count_a && i >= count_b) return +1;
|
||||||
|
else if (seq_a[i].key < seq_b[i].key ) return -1;
|
||||||
|
else if (seq_a[i].key > seq_b[i].key ) return +1;
|
||||||
|
else if (seq_a[i].modifiers < seq_b[i].modifiers) return -1;
|
||||||
|
else if (seq_a[i].modifiers > seq_b[i].modifiers) return +1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -122,10 +203,10 @@ static inline int CompareBinary(const wchar_t *str_a, size_t count_a, const wcha
|
|||||||
static int __cdecl CompareCompositionIndex(void *data, const void *a, const void *b)
|
static int __cdecl CompareCompositionIndex(void *data, const void *a, const void *b)
|
||||||
{
|
{
|
||||||
const ZRCola::translation_db::translation
|
const ZRCola::translation_db::translation
|
||||||
&trans_a = (const ZRCola::translation_db::translation&)((const wchar_t*)data)[*(const unsigned __int32*)a],
|
&trans_a = (const ZRCola::translation_db::translation&)((const unsigned __int16*)data)[*(const unsigned __int32*)a],
|
||||||
&trans_b = (const ZRCola::translation_db::translation&)((const wchar_t*)data)[*(const unsigned __int32*)b];
|
&trans_b = (const ZRCola::translation_db::translation&)((const unsigned __int16*)data)[*(const unsigned __int32*)b];
|
||||||
|
|
||||||
int r = CompareBinary(trans_a.str, trans_a.str_len, trans_b.str, trans_b.str_len);
|
int r = CompareSequence(trans_a.str, trans_a.str_len, trans_b.str, trans_b.str_len);
|
||||||
if (r != 0) return r;
|
if (r != 0) return r;
|
||||||
|
|
||||||
if (trans_a.chr < trans_b.chr) return -1;
|
if (trans_a.chr < trans_b.chr) return -1;
|
||||||
@ -150,13 +231,66 @@ static int __cdecl CompareCompositionIndex(void *data, const void *a, const void
|
|||||||
static int __cdecl CompareDecompositionIndex(void *data, const void *a, const void *b)
|
static int __cdecl CompareDecompositionIndex(void *data, const void *a, const void *b)
|
||||||
{
|
{
|
||||||
const ZRCola::translation_db::translation
|
const ZRCola::translation_db::translation
|
||||||
&trans_a = (const ZRCola::translation_db::translation&)((const wchar_t*)data)[*(const unsigned __int32*)a],
|
&trans_a = (const ZRCola::translation_db::translation&)((const unsigned __int16*)data)[*(const unsigned __int32*)a],
|
||||||
&trans_b = (const ZRCola::translation_db::translation&)((const wchar_t*)data)[*(const unsigned __int32*)b];
|
&trans_b = (const ZRCola::translation_db::translation&)((const unsigned __int16*)data)[*(const unsigned __int32*)b];
|
||||||
|
|
||||||
if (trans_a.chr < trans_b.chr) return -1;
|
if (trans_a.chr < trans_b.chr) return -1;
|
||||||
else if (trans_a.chr > trans_b.chr) return +1;
|
else if (trans_a.chr > trans_b.chr) return +1;
|
||||||
|
|
||||||
return CompareBinary(trans_a.str, trans_a.str_len, trans_b.str, trans_b.str_len);
|
return CompareSequence(trans_a.str, trans_a.str_len, trans_b.str, trans_b.str_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Function to use in \c qsort_s for key sequence index sorting
|
||||||
|
///
|
||||||
|
/// \param[in] data Pointer to key sequence data
|
||||||
|
/// \param[in] a Pointer to first key sequence index element
|
||||||
|
/// \param[in] b Pointer to second key sequence index element
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - <0 when a < b
|
||||||
|
/// - =0 when a == b
|
||||||
|
/// - >0 when a > b
|
||||||
|
///
|
||||||
|
static int __cdecl CompareKeySequenceChar(void *data, const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const ZRCola::keyseq_db::keyseq
|
||||||
|
&ks_a = (const ZRCola::keyseq_db::keyseq&)((const unsigned __int16*)data)[*(const unsigned __int32*)a],
|
||||||
|
&ks_b = (const ZRCola::keyseq_db::keyseq&)((const unsigned __int16*)data)[*(const unsigned __int32*)b];
|
||||||
|
|
||||||
|
if (ks_a.chr < ks_b.chr) return -1;
|
||||||
|
else if (ks_a.chr > ks_b.chr) return +1;
|
||||||
|
|
||||||
|
return CompareSequence(ks_a.seq, ks_a.seq_len, ks_b.seq, ks_b.seq_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Function to use in \c qsort_s for key sequence index sorting
|
||||||
|
///
|
||||||
|
/// \param[in] data Pointer to key sequence data
|
||||||
|
/// \param[in] a Pointer to first key sequence index element
|
||||||
|
/// \param[in] b Pointer to second key sequence index element
|
||||||
|
///
|
||||||
|
/// \returns
|
||||||
|
/// - <0 when a < b
|
||||||
|
/// - =0 when a == b
|
||||||
|
/// - >0 when a > b
|
||||||
|
///
|
||||||
|
static int __cdecl CompareKeySequenceKey(void *data, const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const ZRCola::keyseq_db::keyseq
|
||||||
|
&ks_a = (const ZRCola::keyseq_db::keyseq&)((const unsigned __int16*)data)[*(const unsigned __int32*)a],
|
||||||
|
&ks_b = (const ZRCola::keyseq_db::keyseq&)((const unsigned __int16*)data)[*(const unsigned __int32*)b];
|
||||||
|
|
||||||
|
int r = CompareSequence(ks_a.seq, ks_a.seq_len, ks_b.seq, ks_b.seq_len);
|
||||||
|
if (r != 0) return r;
|
||||||
|
|
||||||
|
if (ks_a.chr < ks_b.chr) return -1;
|
||||||
|
else if (ks_a.chr > ks_b.chr) return +1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -239,31 +373,30 @@ int _tmain(int argc, _TCHAR *argv[])
|
|||||||
// Get translations.
|
// Get translations.
|
||||||
ATL::CComPtr<ADORecordset> rs;
|
ATL::CComPtr<ADORecordset> rs;
|
||||||
if (src.SelectTranslations(rs)) {
|
if (src.SelectTranslations(rs)) {
|
||||||
size_t trans_count = src.GetRecordsetCount(rs);
|
size_t count = src.GetRecordsetCount(rs);
|
||||||
if (trans_count < 0xffffffff) { // 4G check (-1 is reserved for error condition)
|
if (count < 0xffffffff) { // 4G check (-1 is reserved for error condition)
|
||||||
ZRCola::DBSource::translation trans;
|
ZRCola::DBSource::translation trans;
|
||||||
ZRCola::translation_db t_db;
|
ZRCola::translation_db db;
|
||||||
|
|
||||||
// Preallocate memory.
|
// Preallocate memory.
|
||||||
t_db.idxComp .reserve(trans_count);
|
db.idxComp .reserve(count);
|
||||||
t_db.idxDecomp.reserve(trans_count);
|
db.idxDecomp.reserve(count);
|
||||||
t_db.data .reserve(trans_count*4);
|
db.data .reserve(count*4);
|
||||||
|
|
||||||
// Parse translations and build index and data.
|
// Parse translations and build index and data.
|
||||||
while (!ZRCola::DBSource::IsEOF(rs)) {
|
while (!ZRCola::DBSource::IsEOF(rs)) {
|
||||||
// Read translation from the database.
|
// Read translation from the database.
|
||||||
if (src.GetTranslation(rs, trans)) {
|
if (src.GetTranslation(rs, trans)) {
|
||||||
// Add translation to index and data.
|
// Add translation to index and data.
|
||||||
unsigned __int32 ti;
|
unsigned __int32 idx = db.data.size();
|
||||||
ti = t_db.data.size();
|
db.data.push_back(trans.chr);
|
||||||
t_db.data.push_back(trans.chr);
|
|
||||||
std::wstring::size_type n = trans.str.length();
|
std::wstring::size_type n = trans.str.length();
|
||||||
wxASSERT_MSG(n <= 0xffff, wxT("transformation string too long"));
|
wxASSERT_MSG(n <= 0xffff, wxT("transformation string too long"));
|
||||||
t_db.data.push_back((wchar_t)n);
|
db.data.push_back((unsigned __int16)n);
|
||||||
for (std::wstring::size_type i = 0; i < n; i++)
|
for (std::wstring::size_type i = 0; i < n; i++)
|
||||||
t_db.data.push_back(trans.str[i]);
|
db.data.push_back(trans.str[i]);
|
||||||
t_db.idxComp .push_back(ti);
|
db.idxComp .push_back(idx);
|
||||||
t_db.idxDecomp.push_back(ti);
|
db.idxDecomp.push_back(idx);
|
||||||
} else
|
} else
|
||||||
has_errors = true;
|
has_errors = true;
|
||||||
|
|
||||||
@ -271,11 +404,11 @@ int _tmain(int argc, _TCHAR *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sort indices.
|
// Sort indices.
|
||||||
qsort_s(t_db.idxComp .data(), trans_count, sizeof(unsigned __int32), CompareCompositionIndex , t_db.data.data());
|
qsort_s(db.idxComp .data(), count, sizeof(unsigned __int32), CompareCompositionIndex , db.data.data());
|
||||||
qsort_s(t_db.idxDecomp.data(), trans_count, sizeof(unsigned __int32), CompareDecompositionIndex, t_db.data.data());
|
qsort_s(db.idxDecomp.data(), count, sizeof(unsigned __int32), CompareDecompositionIndex, db.data.data());
|
||||||
|
|
||||||
// Write translations to file.
|
// Write translations to file.
|
||||||
dst << ZRCola::translation_rec(t_db);
|
dst << ZRCola::translation_rec(db);
|
||||||
} else {
|
} else {
|
||||||
_ftprintf(stderr, wxT("%s: error ZCC0004: Error getting translation count from database or too many translations.\n"), (LPCTSTR)filenameIn.c_str());
|
_ftprintf(stderr, wxT("%s: error ZCC0004: Error getting translation count from database or too many translations.\n"), (LPCTSTR)filenameIn.c_str());
|
||||||
has_errors = true;
|
has_errors = true;
|
||||||
@ -286,10 +419,67 @@ int _tmain(int argc, _TCHAR *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
// Get key sequences.
|
||||||
|
ATL::CComPtr<ADORecordset> rs;
|
||||||
|
if (src.SelectKeySequences(rs)) {
|
||||||
|
size_t count = src.GetRecordsetCount(rs);
|
||||||
|
if (count < 0xffffffff) { // 4G check (-1 is reserved for error condition)
|
||||||
|
ZRCola::DBSource::keyseq ks;
|
||||||
|
ZRCola::keyseq_db db;
|
||||||
|
|
||||||
|
// Preallocate memory.
|
||||||
|
db.idxChr.reserve(count);
|
||||||
|
db.idxKey.reserve(count);
|
||||||
|
db.data .reserve(count*4);
|
||||||
|
|
||||||
|
// Parse translations and build index and data.
|
||||||
|
while (!ZRCola::DBSource::IsEOF(rs)) {
|
||||||
|
// Read translation from the database.
|
||||||
|
if (src.GetKeySequence(rs, ks)) {
|
||||||
|
// Add translation to index and data.
|
||||||
|
unsigned __int32 idx = db.data.size();
|
||||||
|
db.data.push_back(ks.chr);
|
||||||
|
std::vector<ZRCola::DBSource::keyseq::keycode>::size_type n = ks.seq.size();
|
||||||
|
wxASSERT_MSG(n <= 0xffff, wxT("key sequence too long"));
|
||||||
|
db.data.push_back((unsigned __int16)n);
|
||||||
|
for (std::vector<ZRCola::DBSource::keyseq::keycode>::size_type i = 0; i < n; i++) {
|
||||||
|
const ZRCola::DBSource::keyseq::keycode &kc = ks.seq[i];
|
||||||
|
db.data.push_back(kc.key);
|
||||||
|
db.data.push_back(
|
||||||
|
(kc.shift ? ZRCola::keyseq_db::keyseq::SHIFT : 0) |
|
||||||
|
(kc.ctrl ? ZRCola::keyseq_db::keyseq::CTRL : 0) |
|
||||||
|
(kc.alt ? ZRCola::keyseq_db::keyseq::ALT : 0));
|
||||||
|
}
|
||||||
|
db.idxChr.push_back(idx);
|
||||||
|
db.idxKey.push_back(idx);
|
||||||
|
} else
|
||||||
|
has_errors = true;
|
||||||
|
|
||||||
|
wxVERIFY(SUCCEEDED(rs->MoveNext()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort indices.
|
||||||
|
qsort_s(db.idxChr.data(), count, sizeof(unsigned __int32), CompareKeySequenceChar, db.data.data());
|
||||||
|
qsort_s(db.idxKey.data(), count, sizeof(unsigned __int32), CompareKeySequenceKey , db.data.data());
|
||||||
|
|
||||||
|
// Write translations to file.
|
||||||
|
dst << ZRCola::keyseq_rec(db);
|
||||||
|
} else {
|
||||||
|
_ftprintf(stderr, wxT("%s: error ZCC0006: Error getting key sequence count from database or too many key sequences.\n"), (LPCTSTR)filenameIn.c_str());
|
||||||
|
has_errors = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_ftprintf(stderr, wxT("%s: error ZCC0005: Error getting key sequences from database. Please make sure the file is ZRCola.zrc compatible.\n"), (LPCTSTR)filenameIn.c_str());
|
||||||
|
has_errors = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stdex::idrec::close<ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>(dst, dst_start);
|
stdex::idrec::close<ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>(dst, dst_start);
|
||||||
|
|
||||||
if (dst.fail()) {
|
if (dst.fail()) {
|
||||||
_ftprintf(stderr, wxT("%s: error ZCC0005: Writing to output file failed.\n"), (LPCTSTR)filenameOut.c_str());
|
_ftprintf(stderr, wxT("%s: error ZCC0007: Writing to output file failed.\n"), (LPCTSTR)filenameOut.c_str());
|
||||||
has_errors = true;
|
has_errors = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "dbsource.h"
|
#include "dbsource.h"
|
||||||
|
|
||||||
#include <zrcola/translate.h>
|
#include <zrcola/translate.h>
|
||||||
|
#include <zrcolaui/keyboard.h>
|
||||||
|
|
||||||
#include <wx/app.h>
|
#include <wx/app.h>
|
||||||
#include <wx/cmdline.h>
|
#include <wx/cmdline.h>
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PreprocessorDefinitions>LIBZRCOLAUI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>LIBZRCOLAUI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>..\..\stdex\include;..\..\libZRCola\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\src\keyboard.cpp" />
|
||||||
<ClCompile Include="..\src\stdafx.cpp">
|
<ClCompile Include="..\src\stdafx.cpp">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||||
@ -28,6 +29,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\include\zrcolaui\common.h" />
|
<ClInclude Include="..\include\zrcolaui\common.h" />
|
||||||
|
<ClInclude Include="..\include\zrcolaui\keyboard.h" />
|
||||||
<ClInclude Include="..\src\stdafx.h" />
|
<ClInclude Include="..\src\stdafx.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -18,6 +18,9 @@
|
|||||||
<ClCompile Include="..\src\stdafx.cpp">
|
<ClCompile Include="..\src\stdafx.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\keyboard.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\src\stdafx.h">
|
<ClInclude Include="..\src\stdafx.h">
|
||||||
@ -26,6 +29,9 @@
|
|||||||
<ClInclude Include="..\include\zrcolaui\common.h">
|
<ClInclude Include="..\include\zrcolaui\common.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\include\zrcolaui\keyboard.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="..\res\libZRColaUI.rc">
|
<ResourceCompile Include="..\res\libZRColaUI.rc">
|
||||||
|
@ -29,11 +29,3 @@
|
|||||||
#define ZRCOLAUI_API __declspec(dllimport)
|
#define ZRCOLAUI_API __declspec(dllimport)
|
||||||
#endif
|
#endif
|
||||||
#define ZRCOLA_NOVTABLE __declspec(novtable)
|
#define ZRCOLA_NOVTABLE __declspec(novtable)
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable: 4251)
|
|
||||||
|
|
||||||
|
|
||||||
namespace ZRCola {
|
|
||||||
};
|
|
||||||
|
|
||||||
#pragma warning(pop)
|
|
||||||
|
113
lib/libZRColaUI/include/zrcolaui/keyboard.h
Normal file
113
lib/libZRColaUI/include/zrcolaui/keyboard.h
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015-2016 Amebis
|
||||||
|
|
||||||
|
This file is part of ZRCola.
|
||||||
|
|
||||||
|
ZRCola is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
ZRCola 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
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with ZRCola. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include <zrcola/common.h>
|
||||||
|
|
||||||
|
#include <stdex/idrec.h>
|
||||||
|
#include <istream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4251)
|
||||||
|
|
||||||
|
|
||||||
|
namespace ZRCola {
|
||||||
|
///
|
||||||
|
/// Key sequence database
|
||||||
|
///
|
||||||
|
class ZRCOLAUI_API keyseq_db {
|
||||||
|
public:
|
||||||
|
#pragma pack(push)
|
||||||
|
#pragma pack(2)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4200)
|
||||||
|
///
|
||||||
|
/// Key sequence data
|
||||||
|
///
|
||||||
|
struct keyseq {
|
||||||
|
enum modifiers_t {
|
||||||
|
SHIFT = 1<<0, ///< SHIFT key was pressed
|
||||||
|
CTRL = 1<<1, ///< CTRL key was pressed
|
||||||
|
ALT = 1<<2, ///< ALT key was pressed
|
||||||
|
};
|
||||||
|
|
||||||
|
wchar_t chr; ///< Character
|
||||||
|
unsigned __int16 seq_len; ///< \c seq length
|
||||||
|
struct key_t {
|
||||||
|
wchar_t key; ///< Key
|
||||||
|
unsigned __int16 modifiers; ///< Modifiers (bitwise combination of SHIFT, CTRL and ALT)
|
||||||
|
} seq[]; ///< Key sequence
|
||||||
|
};
|
||||||
|
#pragma warning(pop)
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
std::vector<unsigned __int32> idxChr; ///< Character index
|
||||||
|
std::vector<unsigned __int32> idxKey; ///< Key index
|
||||||
|
std::vector<unsigned __int16> data; ///< Key sequences data
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef ZRCOLAUI_API stdex::idrec::record<keyseq_db, recordid_t, recordsize_t, ZRCOLA_RECORD_ALIGN> keyseq_rec;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const ZRCola::recordid_t stdex::idrec::record<ZRCola::keyseq_db, ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>::id = *(ZRCola::recordid_t*)"KEY";
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Reads key sequence database from a stream
|
||||||
|
///
|
||||||
|
/// \param[in] stream Input stream
|
||||||
|
/// \param[out] db Key sequence database
|
||||||
|
///
|
||||||
|
/// \returns The stream \p stream
|
||||||
|
///
|
||||||
|
inline std::istream& operator >>(_In_ std::istream& stream, _Out_ ZRCola::keyseq_db &db)
|
||||||
|
{
|
||||||
|
unsigned __int32 count;
|
||||||
|
|
||||||
|
// Read index count.
|
||||||
|
stream.read((char*)&count, sizeof(count));
|
||||||
|
if (!stream.good()) return stream;
|
||||||
|
|
||||||
|
// Read character index.
|
||||||
|
db.idxChr.resize(count);
|
||||||
|
stream.read((char*)db.idxChr.data(), sizeof(unsigned __int32)*count);
|
||||||
|
if (!stream.good()) return stream;
|
||||||
|
|
||||||
|
// Read key index.
|
||||||
|
db.idxKey.resize(count);
|
||||||
|
stream.read((char*)db.idxKey.data(), sizeof(unsigned __int32)*count);
|
||||||
|
if (!stream.good()) return stream;
|
||||||
|
|
||||||
|
// Read data count.
|
||||||
|
stream.read((char*)&count, sizeof(count));
|
||||||
|
if (!stream.good()) return stream;
|
||||||
|
|
||||||
|
// Read data.
|
||||||
|
db.data.resize(count);
|
||||||
|
stream.read((char*)db.data.data(), sizeof(unsigned __int16)*count);
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning(pop)
|
20
lib/libZRColaUI/src/keyboard.cpp
Normal file
20
lib/libZRColaUI/src/keyboard.cpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015-2016 Amebis
|
||||||
|
|
||||||
|
This file is part of ZRCola.
|
||||||
|
|
||||||
|
ZRCola is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
ZRCola 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
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with ZRCola. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
@ -20,3 +20,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../../../include/zrcola.h"
|
#include "../../../include/zrcola.h"
|
||||||
|
#include "../include/zrcolaui/keyboard.h"
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user