Compare commits

..

248 Commits

Author SHA1 Message Date
Simon Rozman
0e96b03be1 Set version to 2.5.4
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-12-07 14:30:09 +01:00
Simon Rozman
0c8c772bcd Simplify ZRCola to Unicode combining character transliteration
The ZRCola >> Unicode transliteration translates ZRCola combining
characters into Unicode combining characters now, rather than
translating exact ZRCola characters only.

Signed-off-by: Simon Rozman <simon@rozman.si>
2021-12-07 14:27:10 +01:00
Simon Rozman
55b57c8d7b Sync Copyright
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-12-07 13:03:29 +01:00
Simon Rozman
204565dd60 Hardcode MSIBUILD_OUTPUT_DIR and MSIBUILD_ROOT
KISS!!!

Signed-off-by: Simon Rozman <simon@rozman.si>
2021-12-01 13:22:43 +01:00
Simon Rozman
a7058daf69 Open-code CAB.mak
All other MSI compilations are open-coded but this one.

Signed-off-by: Simon Rozman <simon@rozman.si>
2021-12-01 13:22:43 +01:00
Simon Rozman
f8e701a572 Hardcode output folder name
KISS!!!

Signed-off-by: Simon Rozman <simon@rozman.si>
2021-12-01 10:09:25 +01:00
Simon Rozman
a0cc1221d2 Introduce PDB packaging
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-12-01 10:05:58 +01:00
Simon Rozman
ce76950b2d Redirect output files to the output folder
Thou linker can locate the output .lib file of referenced projects
wherever .lib is just fine, this helps us to gather all .pdb files in
the output folder.

Signed-off-by: Simon Rozman <simon@rozman.si>
2021-12-01 08:49:10 +01:00
Simon Rozman
0d112cd90b Switch to SPDX license notice
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-12-01 08:48:49 +01:00
Simon Rozman
e930d96090 Cleanup project files
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-12-01 08:48:49 +01:00
Simon Rozman
8dc229d0d6 Set version to 2.5.3
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-26 16:51:19 +01:00
Simon Rozman
3bda60b340 Make composed text font customizable
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-26 16:51:19 +01:00
Simon Rozman
ed49b3227e Update Russian Translations
Author: Janoš Ježovnik <janos.jezovnik@zrc-sazu.si>
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-26 14:45:16 +01:00
Simon Rozman
274534a34c Replace <, >, Up and Down with ←, →, ↑ and ↓
Transifex has issues with "<" and ">".

Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-19 14:30:16 +01:00
Simon Rozman
453b78cbb6 Resolve charset .idtx/.idt confusion
NMake inline files are always created using ACP. The "1252" in the .idtx
header has no effect on this. However, we must encode the .idt files
using correct charset/codepage regardless the ACP being used on the
building machine.

Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-19 14:20:02 +01:00
Simon Rozman
467fff294c Makefile: Convert to UTF-16
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-19 14:17:51 +01:00
Simon Rozman
5bb48d899d Unify and localize PUA Warning
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-18 15:49:54 +01:00
Simon Rozman
feb68ce463 Make ZRCola translation first followed by transliterations
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-18 15:32:44 +01:00
Simon Rozman
f6b3b4568a Move revised ZRCola=>Unicode transliteration into the database
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-18 12:05:39 +01:00
Simon Rozman
11924089d3 Updater: bump
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-15 11:54:32 +01:00
Simon Rozman
1a8884fcab Unify Windows.h inclusion
Windows.h must be included first and must be included with care
regarding WinSock.h and WinSock2.h affair.

Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-15 11:54:32 +01:00
Simon Rozman
fc7f9da219 Delay restoring the auto-saved state
Restoring auto-saved state triggers source/destination sync which breaks
in the early stage when wxZRColaComposerPanel is still in its
constructor. The sync uses the application's m_mainWnd to get its
settings, but the application doesn't have the m_mainWnd set yet.

Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-12 15:35:43 +01:00
Simon Rozman
980e5c6b2c Silence Code Analysis warnings about unscoped enums
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-10 11:33:20 +01:00
Simon Rozman
2e68a27d18 Set version to 2.5.2
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-10 09:42:45 +01:00
Simon Rozman
c16ec014dd MSIBuild: bump
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-10 09:42:45 +01:00
Simon Rozman
c9f059726e Readme: Fix typos
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-10 09:18:44 +01:00
Simon Rozman
e173ed8aa2 Upgrade code signing to SHA-256
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-10 09:18:44 +01:00
Simon Rozman
e54e827a07 Import revised Unicode Composed mapping
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-11-10 08:57:37 +01:00
Simon Rozman
3d1a12c335 ZRColaCompile: Generate additional Unicode Composing permutations
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-04-09 15:34:32 +02:00
Simon Rozman
e97971ffb0 ZRColaCompile: Fix command line
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-04-09 15:34:32 +02:00
Simon Rozman
4995ea5a08 ZRColaCompile: Evaluate Unicode Combining against Times New Roman font
The ZRCola font doesn't stack multiple Unicode Combining characters
properly.

Signed-off-by: Simon Rozman <simon@rozman.si>
2021-04-09 15:34:08 +02:00
Simon Rozman
dbf3354a1a Set version to 2.5.1
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-04-02 16:12:50 +02:00
Simon Rozman
0891f44f33 Updater: bump 2021-04-02 16:12:49 +02:00
Simon Rozman
771dd9f1f7 MSICA: bump
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-04-02 16:12:49 +02:00
Simon Rozman
c4f2726256 Build Unicode Combining Characters evaluation CSV with ZRColaCompile
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-04-02 15:40:17 +02:00
Simon Rozman
bc4b6b30d1 Cleanup 2021-04-02 15:40:17 +02:00
Simon Rozman
34e409ef2f UI: Introduce PUA warning
Private-Use-Area characters are not correctly rendered unless ZRCola
font is used. The PUA characters are now displayed in blue.

This commit also required to upgrade (de)composition text box to use
RichEdit control.

Signed-off-by: Simon Rozman <simon@rozman.si>
2021-04-02 15:40:17 +02:00
Simon Rozman
e43a5a0ef0 Add support for ZRCola Composed to Unicode transliteration
The initial support compares characters in ZRCola font Private-Use-Area
to the characters obtained using Unicode combining characters. Those
which match sufficiently are arranged into a new transliteration.

As the ZRCola Composed to Unicode transliteration requires to be applied
_after_ ZRCola composition but UI applies additional transliterations
_before_ ZRCola composition, the ZRCola composition was reintroduced as
one of the transliterations. This allows configuring a custom
transliteration sequence.

Signed-off-by: Simon Rozman <simon@rozman.si>
2021-04-02 15:39:24 +02:00
Simon Rozman
ddc8b00416 UI: Swap translation drop-down and ZRCola (de)composition button
The order of controls now reflect the order transformations are applied
to the text.

Signed-off-by: Simon Rozman <simon@rozman.si>
2021-04-02 12:58:25 +02:00
Simon Rozman
9f128a96d1 UI: Update ZRCola.fbp
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-04-02 12:58:13 +02:00
Simon Rozman
74e95b95b5 Cleanup 2021-04-02 12:58:12 +02:00
Simon Rozman
f3bb513545 Cleanup
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-03-30 12:03:29 +02:00
Simon Rozman
72f8b179d7 Introduce Unicode Combining Characters evaluation script
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-03-25 14:43:46 +01:00
Simon Rozman
fa2fb03cf8 MSIBuild: Bump
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-03-25 08:39:37 +01:00
Simon Rozman
12c2889ea3 Copyright: Bump year
Signed-off-by: Simon Rozman <simon@rozman.si>
2021-03-25 08:36:00 +01:00
Simon Rozman
2fce6f06bc Set version to 2.5
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-11-19 12:43:09 +01:00
Simon Rozman
89a33bc0ea Publish MSIs to <version> and _latest folders on the download server
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-11-19 12:30:25 +01:00
Simon Rozman
445e0663e1 Add copyright colophon to .h files
Resource Compiler has an issue with the first line of an UTF-8 .h file.
The workaround is not to begin UTF-8 .h files with anything important.
A blank line would do or a comment.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-11-19 11:21:39 +01:00
Simon Rozman
b837c5204c Add copyright colophon to .rc files
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-11-19 11:10:33 +01:00
Simon Rozman
4dd9461c48 Add UTF-8 BOM markers to documentation
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-11-19 11:00:17 +01:00
Simon Rozman
c7e29b1862 Add UTF-8 BOM markers
MSVC needs them to use correct charset when Language for non-Unicode
programs is set to Windows-1252 or anything different than UTF-8.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-11-19 10:59:54 +01:00
Simon Rozman
42daea5b5e Bump WinStd
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-11-19 10:00:46 +01:00
Simon Rozman
41ad9cd134 Specify .wsf files encoding
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-11-19 09:58:04 +01:00
Simon Rozman
435316eb79 Bump sub-modules
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-08-20 12:18:29 +02:00
Simon Rozman
aa7a8fa484 Re-add UTF-8 BOM markers where required
C files containing non-ASCII characters in strings require UTF-8 BOM for
the MSVC to encode them correctly to the UTF-16 string. (Or switch the
computer we are building on to use UTF-8 for non-Unicode programs.)

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-03-15 00:13:28 +01:00
Simon Rozman
59493b998e Enable Windows 10 ARM64 support
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-03-14 23:57:41 +01:00
Simon Rozman
0b586aa141 Upgrade to current MSIBuild
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-03-03 14:44:32 +01:00
Simon Rozman
04ffd649ec Clean-up
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-03-03 13:49:51 +01:00
Simon Rozman
0970997ab7 Publish updates to the new catalog file and switch to SHA-256 (phase 2)
Version 2.4 switched to the catalog-0001.xml file. The new catalog file
is using SHA-256 hashes and signatures.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 13:48:10 +01:00
Simon Rozman
1434c9a2d3 Change UpgradeCode and mark to perform major update from 2.4
Changing the component GUIDs and keeping the same file paths rendered
minor updating broken.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 13:32:48 +01:00
Simon Rozman
9ebdafa272 Reapply "Unify component GUIDs across platforms"
This reverts commit f0f3ce75d0.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 13:32:48 +01:00
Simon Rozman
ea76dc27b4 Reapply "Unify component GUIDs across languages"
This reverts commit 41c8cc01ed.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 13:32:48 +01:00
Simon Rozman
7d39d4756c Preset version to 2.4.1
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 13:32:48 +01:00
Simon Rozman
a6e337a2a1 Switch to new catalog update file and switch to SHA-256 (phase 1)
Versions 2.2 and 2.3 require to update to 2.4 first (to fix Active Setup
issue which works for minor updates only), before updating to 2.5
(requires major update).

The 2.5 and beyond updates will have to be visible to 2.4 version only.
Therefore, we switch the Updater in 2.4 to a new catalog file. While the
2.4 update itself needs to be published to the existing catalog file to
instruct pre-2.4 versions to update to 2.4.

In other words:
- include\UpdaterCfg.h is about checking for future releases
- Makefile publish is about upgrading the past releases

This is also an excellent opportunity to phase out SHA-1.

Updater will treat all hashes as SHA-256 when checking for updates in
the new catalog - the future releases.

While we keep hashing and signing the old catalog file using SHA-1 - for
past releases.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 13:32:48 +01:00
Simon Rozman
0e1a347b5f Preset version to 2.4
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 09:54:48 +01:00
Simon Rozman
e28a146a39 Sub-module update
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 08:53:45 +01:00
Simon Rozman
dfedfc419e Strip excessive custom action identifier prefixes
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 08:53:45 +01:00
Simon Rozman
9f9e5addcc Fix the Active Setup StubPath issue affected products
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 08:53:45 +01:00
Simon Rozman
f0f3ce75d0 Revert "Unify component GUIDs across platforms"
This reverts commit 2363016a76.

Due to Active Setup StubPath bug in already deployed MSI packages we can
fix automatically using minor update only, we cannot change the
component GUIDs just yet.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 08:53:44 +01:00
Simon Rozman
41c8cc01ed Revert "Unify component GUIDs across languages"
This reverts commit f8f20f3667.

Due to Active Setup StubPath bug in already deployed MSI packages we can
fix automatically using minor update only, we cannot change the
component GUIDs just yet.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 08:53:44 +01:00
Simon Rozman
64ef4f5921 Preset version to 2.3.2
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-25 08:53:44 +01:00
Simon Rozman
d6be99ed59 Stop hiding catalog-0000.xml file
The hidden files cannot be downloaded (404) even when addressed
directly.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-24 09:44:31 +01:00
Simon Rozman
c00e9cbe1f Update legacy publish path
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-15 19:16:38 +01:00
Simon Rozman
867ab0f149 Fix upgrading from previous version
As the language and platform-dependent component GUIDs changed and we
wish to retain the original destination folders and filenames the
RemoveExistingProducts custom action is now invoked differently
according to the version of the product we are upgrading.

When we are upgrading an old package with legacy component GUIDs, we're
uninstalling it before installing the new one.

When we will be upgrading a modern package with platform/language
dependent component GUIDs, we will remove the leftover components after
installing the new one.

This should deliver compatible upgrades of existing versions while
providing optimal upgrading in the future.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-15 19:08:00 +01:00
Simon Rozman
ebdbb84a29 Enable recommended code analysis and address warnings
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-13 13:18:11 +01:00
Simon Rozman
62702a0194 Remove excessive UTF-8 BOM
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-11 15:42:11 +01:00
Simon Rozman
b3702ed237 Extend copyright year
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-11 15:38:57 +01:00
Simon Rozman
d3af51adf8 Remove building of unused executables
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-11 14:54:09 +01:00
Simon Rozman
2363016a76 Unify component GUIDs across platforms
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-11 14:54:09 +01:00
Simon Rozman
f8f20f3667 Unify component GUIDs across languages
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-11 14:54:09 +01:00
Simon Rozman
c2b96dbcc1 Automate language-dependent folder property names
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-11 14:54:09 +01:00
Simon Rozman
90a53fb139 Unify upgrade GUID across platforms
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-11 11:46:26 +01:00
Simon Rozman
ac2c225540 Add missing MSIBUILD_LANG_GUID and MSIBUILD_PLAT_GUID properties
Updated version of wxExtend sub-module requires them.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-11 11:46:05 +01:00
Simon Rozman
4a0bf118bf Bump stdex
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-10 15:17:22 +01:00
Simon Rozman
2e04726dd7 Update font and database
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-10 15:05:07 +01:00
Simon Rozman
9c8ca4d7b1 Make enum wxHexDecodeMode scoped
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-10 14:59:24 +01:00
Simon Rozman
0800f813ff Rename stdafx.h to pch.h
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-10 14:10:29 +01:00
Simon Rozman
dffc4bf9af Unify platform designations
.sln uses the same as .vcxproj files

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-02-10 14:03:44 +01:00
Simon Rozman
91d5c77e02 Clean Makefile
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-12-04 10:20:08 +01:00
Simon Rozman
94cbed643d Move distribution to CDN server
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-12-04 10:18:01 +01:00
Simon Rozman
be687497e8 Bump MSICA, WinStd and wxExtend
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-12-04 10:07:00 +01:00
Simon Rozman
495b490dc2 Remove UTF-8 BOM
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-12-04 10:07:00 +01:00
Simon Rozman
f54c048b74 Preset version to 2.3.1
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-12-04 10:07:00 +01:00
Simon Rozman
81741eec8f Update font and database
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-09-23 11:07:42 +02:00
Simon Rozman
ab065edda4 Update sub-modules
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-09-23 09:58:59 +02:00
Simon Rozman
6799a1f8a6 Preset version to 2.3
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-09-23 09:58:58 +02:00
Simon Rozman
84973a57d6 Set version to 2.2
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-08-09 15:01:06 +02:00
Simon Rozman
3b64c576fa Update database
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 15:04:58 +02:00
Simon Rozman
0b777b89c2 Report error if database file don't open successfully
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-20 14:27:45 +02:00
Simon Rozman
b6567582e5 Enable function-level linking to allow LTCG
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-19 12:05:05 +02:00
Simon Rozman
8f1b412c1f Switch to Visual Studio 2019
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-19 11:51:33 +02:00
Simon Rozman
79ec7c51ba Fix UninstallFonts Makefile target
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-19 11:44:20 +02:00
Simon Rozman
33aa840e50 Update translations
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-06-19 10:22:58 +02:00
Simon Rozman
63ff924b76 Update font and database
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-04-15 11:43:43 +02:00
Simon Rozman
c790fff673 Remove auto-added translations from POT file
POT files should not contain any translations at all. Transifex is
picky.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-04-01 19:40:54 +02:00
Simon Rozman
99283e806a Preset version to 2.1.4.
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-04-01 19:35:49 +02:00
Simon Rozman
893dbf5783 Update year to 2019
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-04-01 14:50:04 +02:00
Simon Rozman
64e3735b12 Make character selection dialog non-modal
This allows direct focusing in (de)compose text control even when the
character selection dialog is open.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-04-01 14:49:56 +02:00
Simon Rozman
c598fe4fe0 Invert order of translations and (de)composition
Example: This allows a to be translated into ά, as a is first
translated to α and finally ZRCola composed into ά. Otherwise we'd need
to include all accented character translations in transliteration
tables.

Signed-off-by: Simon Rozman <simon@rozman.si>
2019-04-01 14:49:49 +02:00
Simon Rozman
4393b02323 Fix decomposition
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-04-01 14:49:41 +02:00
Simon Rozman
0dba3d4652 Update sub-module
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-04-01 14:49:33 +02:00
Simon Rozman
c9231078a6 Preset version to 2.1.3
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-04-01 14:49:24 +02:00
Simon Rozman
d98987ec5f Upgrade to latest WinStd library
Signed-off-by: Simon Rozman <simon@rozman.si>
2019-04-01 14:48:40 +02:00
Simon Rozman
4900202d7e Trigger per-user setup on logon 2019-04-01 14:48:31 +02:00
Simon Rozman
a3c73e1c4d Preset version to 2.1.2 2018-11-19 12:07:10 +01:00
Simon Rozman
a8436ee3d7 Silence the missing shcore.dll warning on Windows 7 2018-11-06 09:33:17 +01:00
Simon Rozman
c8ea746474 Preset version to 2.1.1 2018-11-06 09:24:50 +01:00
Simon Rozman
039dae11bc Set version to 2.1 2018-10-09 14:00:02 +02:00
Simon Rozman
ce11c7f4d4 Do not restore placement and sizing when GUI changes 2018-09-25 13:45:06 +02:00
Simon Rozman
ea5049172d Revise main window minimization/hiding/restoring 2018-09-25 12:04:02 +02:00
Simon Rozman
1feebdbbf8 Pre-set version to 2.1-beta7 2018-09-25 12:02:39 +02:00
Simon Rozman
39708ad4cb Set m_taskBarIcon to NULL after deleted 2018-09-25 12:00:04 +02:00
Simon Rozman
e0e8401482 Update translations 2018-09-25 11:02:15 +02:00
Simon Rozman
a5099d7424 Add Cyrillic >> Latin translations back 2018-09-25 10:37:25 +02:00
Simon Rozman
c6d567edfd Resolve warning popup when GetDpiForWindow() is not available 2018-09-19 12:59:03 +02:00
Simon Rozman
3d104d4292 Swap composed and decomposed letters on ZRCola (de)compose icon
...to match the natural order of the decomposed and composed panels in
GUI.
2018-09-19 12:41:09 +02:00
Simon Rozman
07706db14e Switch to Transifex project for localization 2018-09-19 12:15:40 +02:00
Simon Rozman
10e53e431a Update translation templates 2018-09-19 09:10:34 +02:00
Simon Rozman
5e751eb23e Make (de)composition a separate translation set 2018-09-18 11:23:30 +02:00
Simon Rozman
30b2eb270b Update fonts 2018-09-17 15:06:41 +02:00
Simon Rozman
ed98e1d588 Update sub-module 2018-09-17 15:04:35 +02:00
Simon Rozman
6c3b84b448 Revert MSI URLs from HTTPS to HTTP
Updater doesn't handle HTTPS. Yet.
2018-09-17 09:40:02 +02:00
Simon Rozman
2d04361318 Add missing Updater public key to ZRCola.exe resources 2018-09-17 09:06:10 +02:00
Simon Rozman
2d82904b13 Check HTTP status 200 before parsing the response 2018-09-17 09:02:04 +02:00
Simon Rozman
640421be60 Make list of settings pages wider 2018-09-13 13:10:39 +02:00
Simon Rozman
75941da5a7 Fix window placement on DPI changes 2018-09-12 16:11:02 +02:00
Simon Rozman
974d6bd827 Honor monitor layout and DPI changes when persisting window placement 2018-09-11 15:32:13 +02:00
Simon Rozman
16dc9aff96 Add high DPI support 2018-09-10 12:38:40 +02:00
Simon Rozman
18f36e7fde Add missing translation sequence dialog name 2018-09-10 10:02:27 +02:00
Simon Rozman
5d0ea994d7 Update wxFormBuilder 2018-09-10 09:45:36 +02:00
Simon Rozman
e86847f364 Introduce preliminary ARM64 support 2018-09-10 09:41:50 +02:00
Simon Rozman
c295fcfc12 Update documentation 2018-09-08 01:37:01 +02:00
Simon Rozman
9f0c831fb5 Split Makefile into multiple reusable .mak files 2018-09-08 01:32:00 +02:00
Simon Rozman
ddae64ca6d Extend copyright year 2018-09-07 23:57:59 +02:00
Simon Rozman
bc48240e0a Upgrade to Visual Studio 2017 and wxWidgets 3.1.2 static 2018-09-07 23:41:58 +02:00
Simon Rozman
6a3fbc063c Fix down-casting 2018-09-07 20:30:01 +02:00
Simon Rozman
3672c8e87e Distinguish variables with same names
...to resolve C4457 warnings.
2018-09-07 20:17:35 +02:00
Simon Rozman
dcabe36369 Remove MFC dependency 2018-09-07 19:40:28 +02:00
Simon Rozman
4b59582568 Add missing #include <algorithm> 2018-09-07 19:37:22 +02:00
Simon Rozman
692a37651d Fix printf() parameters 2018-09-07 19:36:42 +02:00
Simon Rozman
59d06ae3dc Make explicit int to unsigned __int6 conversion 2018-09-07 19:36:10 +02:00
Simon Rozman
4226774e21 Silence ADO .h warnings 2018-09-07 19:34:56 +02:00
Simon Rozman
3831012af9 Distinguish variables with same names
...to resolve C4457 warnings.
2018-09-07 19:32:54 +02:00
Simon Rozman
073311be78 Simplify property sheet inclusion 2018-09-07 18:02:30 +02:00
Simon Rozman
6636bf4211 Fix intermediate/output folder creation on nmake register 2018-09-03 13:08:53 +02:00
Simon Rozman
7f0e2cca04 Switch to wxWidgets 3.1.1 2018-09-03 13:08:14 +02:00
Simon Rozman
3976831d98 Update sub-modules 2018-09-03 10:42:43 +02:00
Simon Rozman
a22bbcb407 Use local wxWidget DLLs 2018-09-03 10:32:04 +02:00
Simon Rozman
aafa984d7c Fix output path for Updater operations 2018-09-03 10:31:52 +02:00
Simon Rozman
707f57d6ae Update wxExtend sub-module 2018-09-01 06:49:29 +02:00
Simon Rozman
ef2d61cac1 Update sub-modules 2018-08-31 14:28:01 +02:00
Simon Rozman
7edf4f452e Update submodules 2018-08-24 14:51:25 +02:00
Simon Rozman
a3c6313f57 Register en_US language in nmake register
When "Language" setting is absent in registry, the initialization of
wxWidget localization raises asserts.
2018-08-24 14:49:08 +02:00
Simon Rozman
ab319af0b8 Update Amebis URL 2018-07-05 09:28:41 +02:00
Simon Rozman
14de0cbd23 Use absolute devenv.com path 2018-06-01 13:34:29 +02:00
Simon Rozman
7bd5441c31 Update MSIBuild sub-module to latest version 2018-06-01 13:33:08 +02:00
Simon Rozman
8358d3bf35 Update sub-module 2017-12-22 13:08:41 +01:00
Simon Rozman
8f5cd8cae7 Extend copyright to 2017 2017-12-22 10:32:55 +01:00
Simon Rozman
d301b6feed Document localization 2017-12-19 14:21:46 +01:00
Simon Rozman
cc4baa3214 Preset version to 2.1-beta6 2017-12-19 14:18:14 +01:00
Simon Rozman
61d3369631 Set version to 2.1-beta5 2017-12-19 12:23:28 +01:00
Simon Rozman
a40d021404 Update sub-modules 2017-12-19 12:10:38 +01:00
Simon Rozman
bb4331d6f6 Update wxWidgets to 3.0.3 2017-12-19 10:39:15 +01:00
Simon Rozman
9d8c7d87ed Update documentation 2017-12-19 09:11:47 +01:00
Simon Rozman
c0da04dcf4 Update submodule 2017-12-19 09:10:53 +01:00
Simon Rozman
44f00f0c40 Update to new wxFormBuilder 2017-12-18 12:02:26 +01:00
Simon Rozman
48945e15d6 Increase transliteration selector width 2017-12-18 11:15:15 +01:00
Simon Rozman
d0e367b881 Add translitarations 2017-12-18 10:49:06 +01:00
Simon Rozman
72e8e4893e Update font and database 2017-12-18 08:37:46 +01:00
Simon Rozman
5502206810 Update translations 2017-12-18 08:36:28 +01:00
Simon Rozman
35f6b33f54 Update sub-modules 2017-12-18 08:23:19 +01:00
Simon Rozman
c5c505e32e Version set to 2.1-beta4 2017-07-13 15:00:00 +02:00
Simon Rozman
9ca82f02f8 Decomposition (inverse-translation) fixed 2017-07-13 14:50:27 +02:00
Simon Rozman
9ff3f8c2ab Version set to 2.1-beta3 2017-07-12 16:01:45 +02:00
Simon Rozman
0e50a733de Normalization more flexible allowing mixing of modifiers (as long as the modifiers of a same class remain in the same order) 2017-07-12 15:57:48 +02:00
Simon Rozman
7fbcbd17fb Sub-module update 2017-07-12 14:13:27 +02:00
Simon Rozman
593392782a Version set to 2.1-beta2 2017-06-01 20:04:39 +02:00
Simon Rozman
e19a98a249 Translation management extended and moved from settings dialog to Translate toolbar 2017-06-01 20:02:43 +02:00
Simon Rozman
a66128b8ca Incorrect data type fixed 2017-06-01 19:59:09 +02:00
Simon Rozman
6121f7ee12 Translation sequences loaded from database 2017-06-01 15:16:24 +02:00
Simon Rozman
d9527fe70f Predefined translation sequences added to ZRCola.zrcdb database 2017-06-01 13:28:18 +02:00
Simon Rozman
937c263d56 Sub-module update 2017-05-30 12:55:45 +02:00
Simon Rozman
6487507570 Adaptation to database changes 2017-05-10 09:45:21 +02:00
Simon Rozman
84fa35c9be Clean-up 2017-05-10 09:44:06 +02:00
Simon Rozman
b8be10390b Database update 2017-05-09 13:06:05 +02:00
Simon Rozman
de6d890ac1 Secondary translation permutations added to support normalization 2017-05-09 12:08:34 +02:00
Simon Rozman
31b6f1a3e8 Recursively inverse translated translations ranks updated 2017-05-08 14:52:30 +02:00
Simon Rozman
4c6839e9fe com_translation class extended to support normalization 2017-05-08 14:44:53 +02:00
Simon Rozman
397cfe71dd Duplicate transformations (differing by rank only) removed from database 2017-05-08 14:33:33 +02:00
Simon Rozman
1834543564 Rearranged transformation sort order in database 2017-05-08 13:39:19 +02:00
Simon Rozman
8f4f20f2b4 Internal classes upgraded to support future normalization 2017-05-08 13:33:40 +02:00
Simon Rozman
9bba0ca557 com_translation now stand-alone class for clearer code 2017-05-08 12:40:01 +02:00
Simon Rozman
435b5c4a10 Duplicate error number resolved 2017-05-03 13:30:06 +02:00
Simon Rozman
bc5058f168 Database update 2017-05-03 13:01:29 +02:00
Simon Rozman
5ba870158e Decomposition syntax validation temporary removed 2017-05-03 12:36:15 +02:00
Simon Rozman
a6693673a5 Preliminary decomposition syntax validation introduced 2017-04-28 19:37:14 +02:00
Simon Rozman
ba55173f28 Sub-module update 2017-04-28 19:34:56 +02:00
Simon Rozman
12a053a495 Database update 2017-04-28 19:34:47 +02:00
Simon Rozman
8da5f88e0d MSICA has its own copy of WinStd and MSICALib libraries to allow stand-alone configuration (i.e. static RTL) 2017-04-24 23:07:06 +02:00
Simon Rozman
5a4a20a873 Sub-module update 2017-04-24 22:07:15 +02:00
Simon Rozman
7e50ba5974 Sub-module update 2017-04-24 21:59:48 +02:00
Simon Rozman
91fd26a51d Sub-module update 2017-04-18 14:47:54 +02:00
Simon Rozman
1ea5e52208 Sub-module update 2017-04-18 14:44:13 +02:00
Simon Rozman
2a18117b17 Sub-module update 2017-04-18 14:05:58 +02:00
Simon Rozman
b7bef14746 Copyright extended to 2017 2017-04-18 14:05:45 +02:00
Simon Rozman
4aacc4abc5 Version set to 2.1-beta1 2017-04-03 12:38:54 +02:00
Simon Rozman
2f6c789fdf Support for multiple transformations 2017-04-03 12:36:14 +02:00
Simon Rozman
57ceeadbe7 Clean-up 2017-04-03 12:34:18 +02:00
Simon Rozman
3b297c8427 Missing translations added 2017-04-03 12:16:46 +02:00
Simon Rozman
92374e57a8 Loading of recent character list simplified by using wxStringTokenizer 2017-03-31 14:02:37 +02:00
Simon Rozman
ace7551281 Main frame no longer deletes child dialogues in destructor, causing after-death wxPersist saving of deleted dialogue states later. 2017-03-31 13:44:47 +02:00
Simon Rozman
15e5f2d9e2 Character select dialog saves history in legacy format too now 2017-03-31 13:17:25 +02:00
Simon Rozman
08397415c4 Clean-up 2017-03-30 14:54:15 +02:00
Simon Rozman
6dff6eed4f Translation set database and other translation sets added 2017-03-30 13:08:20 +02:00
Simon Rozman
acbae76737 Clean-up 2017-03-30 10:57:31 +02:00
Simon Rozman
cc4a150501 Translation set ID data-type introduced 2017-03-30 10:23:08 +02:00
Simon Rozman
186dbee443 Multiple translation sets support 2017-03-30 09:49:22 +02:00
Simon Rozman
716dde0a84 Clean-up 2017-03-29 09:46:33 +02:00
Simon Rozman
155642a3f9 "Composition" and "Decomposition" renamed to more general terms "Translation" and "Inverse translation" to extend its use for transliteration 2017-03-27 14:10:43 +02:00
Simon Rozman
7cb0317544 Translation update 2017-03-27 14:06:16 +02:00
Simon Rozman
87a2828ce0 Translation rank split to composed and decomposed character rank allowing asymmetric ranking 2017-03-27 12:39:36 +02:00
Simon Rozman
806aa550a5 Characters are represented as UTF-16 sequences instead of a single UTF-16 character 2017-03-21 09:09:07 +01:00
Simon Rozman
ca306345c2 Composed and decomposed strings of the ZRCola::translation_db::translation protected 2017-03-16 10:21:29 +01:00
Simon Rozman
03ff056898 ZRCola::translation_db::translation::com_start marked as const now 2017-03-16 09:44:43 +01:00
Simon Rozman
9f083bb521 Character-Language table extended to support multi-UTF-16 characters 2017-03-14 14:14:39 +01:00
Simon Rozman
a224454b3c ZRCola::translation::CompareString() >> ZRCola::CompareString() 2017-03-14 13:23:20 +01:00
Simon Rozman
bd0fdba435 Composed characters extended to support multiple UTF-16 character 2017-03-14 12:54:46 +01:00
Simon Rozman
87814981db ZRCola::translation_db::Compose fixed to honor inputMax==-1 correctly 2017-03-14 10:51:56 +01:00
Simon Rozman
acf86e2ce0 Reverted to SHA1 Authenticode signatures for Windows XP compatibility 2017-03-14 09:44:31 +01:00
Simon Rozman
1016d5f738 ZRCola tutorial is now displayed only if ZRCola feature was installed 2017-03-14 09:23:53 +01:00
Simon Rozman
4d53785af7 wxWidget RTL dependencies fixed 2017-03-14 09:00:16 +01:00
Simon Rozman
8e2a3860e3 Changed to RFC3161 time-stamping and forced SHA1 digest to support Vista 2017-03-10 13:49:07 +01:00
Simon Rozman
0c2e666d0f Russian translation update 2017-03-10 13:36:48 +01:00
Simon Rozman
d6075327ef Copy (de)composed and return feature introduced 2017-01-13 13:56:51 +01:00
Simon Rozman
14e665fdf2 Sub-module update 2017-01-13 13:55:18 +01:00
Simon Rozman
55e2ee8c4d Folder options added 2017-01-12 10:10:08 +01:00
Simon Rozman
f444355d6d 00ZRCOla fonts replaced with ZRCOla 2017-01-12 10:09:54 +01:00
Simon Rozman
feb3c7c150 Unicode apostrophe changed to ASCII version for simplicity 2017-01-03 11:52:36 +01:00
184 changed files with 31626 additions and 16127 deletions

5
.gitignore vendored
View File

@@ -1,6 +1,3 @@
/*.opensdf
/*.sdf
/*.suo
/ipch
/.vs
*.user
temp

View File

@@ -1,17 +1,18 @@
# Localization of ZRCola
# Localization of ZRCola
In order to get ZRCola experience in your language the following resources should be translated:
1. [ZRCola](https://poeditor.com/join/project/NTidhEPdDM)
2. [ZRCola-zrcdb](https://poeditor.com/join/project/QBuYsTwk0d)
3. [libZRColaUI](https://poeditor.com/join/project/vrnIvk5IOM)
4. [Updater](https://poeditor.com/join/project/oDK4ktH3ZV)
5. [wxExtend](https://poeditor.com/join/project/YmsdlC3CBv)
1. [ZRCola Application](https://www.transifex.com/amebis/zrcola/app/)
2. [ZRCola Database](https://www.transifex.com/amebis/zrcola/database/)
3. [ZRCola Core](https://www.transifex.com/amebis/zrcola/core/)
4. [Updater](https://www.transifex.com/amebis/updater/updater/) and [Updater UpdCheck](https://www.transifex.com/amebis/updater/updcheck/)
5. [wxExtend](https://www.transifex.com/amebis/wxextend/wxextend/)
6. Setup
- [MSIBuildUI](https://poeditor.com/join/project/ikxWBlq1o5)
- [MSIBuildCore](https://poeditor.com/join/project/RSCSsz9fXi)
- [MSICALib](https://poeditor.com/join/project/cKP0wwBrHU)
- [MSICA](https://poeditor.com/join/project/gCNPagUQvn)
- [ZRCola Setup](https://www.transifex.com/amebis/zrcola/setup/)
- [MSIBuild UI](https://www.transifex.com/amebis/msibuild/ui/)
- [MSIBuild Core](https://www.transifex.com/amebis/msibuild/core/)
- [MSICALib](https://www.transifex.com/amebis/msicalib/msicalib/)
- [MSICA](https://www.transifex.com/amebis/msica/msica/)
## General Guidelines

5
MSI/MSM/.gitignore vendored
View File

@@ -1,5 +0,0 @@
/*.log
/Microsoft_VC100_CRT_x64.msm
/Microsoft_VC100_CRT_x86.msm
/Microsoft_VC100_DebugCRT_x64.msm
/Microsoft_VC100_DebugCRT_x86.msm

View File

@@ -1,2 +0,0 @@
Win\System64\msvcp100.dll
Win\System64\msvcr100.dll

View File

@@ -1,24 +0,0 @@
#
# Copyright 1991-2017 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/>.
#
[splosno]
jezik=0
deli=featZRCola featUpdCheck
[parametri]

View File

@@ -1,2 +0,0 @@
Win\System\msvcp100.dll
Win\System\msvcr100.dll

View File

@@ -1,24 +0,0 @@
#
# Copyright 1991-2017 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/>.
#
[splosno]
jezik=0
deli=featZRCola featUpdCheck
[parametri]

View File

@@ -1,2 +0,0 @@
Win\System64\msvcp100d.dll
Win\System64\msvcr100d.dll

View File

@@ -1,24 +0,0 @@
#
# Copyright 1991-2017 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/>.
#
[splosno]
jezik=0
deli=featZRCola featUpdCheck
[parametri]

View File

@@ -1,2 +0,0 @@
Win\System\msvcp100d.dll
Win\System\msvcr100d.dll

View File

@@ -1,24 +0,0 @@
#
# Copyright 1991-2017 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/>.
#
[splosno]
jezik=0
deli=featZRCola featUpdCheck
[parametri]

Binary file not shown.

View File

@@ -1,21 +1,5 @@
#
# Copyright 1991-2017 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/>.
#
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright © 1991-2021 Amebis
!INCLUDE "..\..\include\MSIBuildCfg.mak"
!INCLUDE "..\MSIBuild\Makefile"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,9 +0,0 @@
/*-1.idt
/*-2.idt
/*-2.idtx
/*.Binary-1
/*.Binary-2
/*.Icon-1
/*.Icon-2
/*.lst
/*.msm

View File

@@ -1,94 +0,0 @@
#
# Copyright 1991-2017 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 "..\..\..\include\MSIBuildCfg.mak"
# Note: When changing WXWIDGETS_VER or WXWIDGETS_COMPILER, the DLL filenames will change.
# Then, you MUST change the component GUIDs as well.
WXWIDGETS_VER=311
WXWIDGETS_COMPILER=_vc100
!IF "$(PLAT)" == "x64"
WXWIDGETS_PLAT=_x64
!ELSE
WXWIDGETS_PLAT=
!ENDIF
!IF "$(CFG)" == "Debug"
WXWIDGETS_CFG=ud
!ELSE
WXWIDGETS_CFG=u
!ENDIF
######################################################################
# Component
All :: "$(LANG).$(PLAT).$(CFG).Component-1.idt"
"$(LANG).$(PLAT).$(CFG).Component-1.idt" : "Makefile" "..\..\..\include\MSIBuildCfg.mak"
-if exist $@ del /f /q $@
move /y << $@ > NUL
Component ComponentId Directory_ Attributes Condition KeyPath
s$(MSIBUILD_LENGTH_ID) S38 s$(MSIBUILD_LENGTH_ID) i2 S255 S$(MSIBUILD_LENGTH_ID)
Component Component
!IF "$(PLAT)" == "Win32"
compwxbase.dll.Win32 {4C7F5A16-5B74-47D5-A405-57C7BD96F090} ZRCOLABINDIR 0 filewxbase.dll.Win32
compwxbase_net.dll.Win32 {00534942-B21F-4401-BFE4-C7677F4BE3E5} ZRCOLABINDIR 0 filewxbase_net.dll.Win32
compwxbase_xml.dll.Win32 {71E30748-DD22-4D8B-B26F-60C5150D9AAE} ZRCOLABINDIR 0 filewxbase_xml.dll.Win32
compwxmsw_core.dll.Win32 {FB8D46B9-86DC-4590-8F0A-8294F6A45E6A} ZRCOLABINDIR 0 filewxwxmsw_core.dll.Win32
compwxmsw_adv.dll.Win32 {7B7DB31D-1760-493A-BBE9-35237A6EF9E0} ZRCOLABINDIR 0 filewxmsw_adv.dll.Win32
compwxmsw_aui.dll.Win32 {49CF9864-63B6-4F43-8EC7-7294B966B419} ZRCOLABINDIR 0 filewxmsw_aui.dll.Win32
!ENDIF
!IF "$(PLAT)" == "x64"
compwxbase.dll.x64 {905D8859-BFD2-410A-81DB-93231088C066} ZRCOLABINDIR 256 filewxbase.dll.x64
compwxbase_net.dll.x64 {8A0A49C8-DAEB-4983-8E8D-9DE30AE1D0B6} ZRCOLABINDIR 256 filewxbase_net.dll.x64
compwxbase_xml.dll.x64 {24A5F181-EFE7-4542-8AAB-1D21DB74E954} ZRCOLABINDIR 256 filewxbase_xml.dll.x64
compwxmsw_core.dll.x64 {F5B3F6E6-4FFB-4A79-A794-202D6F93F716} ZRCOLABINDIR 256 filewxwxmsw_core.dll.x64
compwxmsw_adv.dll.x64 {D7722FB9-59BB-498F-93C3-78451471A023} ZRCOLABINDIR 256 filewxmsw_adv.dll.x64
compwxmsw_aui.dll.x64 {FB703979-0E3D-458E-82DD-DAC33329FA9D} ZRCOLABINDIR 256 filewxmsw_aui.dll.x64
!ENDIF
<<NOKEEP
######################################################################
# File
All :: "$(LANG).$(PLAT).$(CFG).File-1.idt"
"$(LANG).$(PLAT).$(CFG).File-1.idt" : "Makefile" "..\..\..\include\MSIBuildCfg.mak"
-if exist $@ del /f /q $@
move /y << $@ > NUL
File Component_ FileName FileSize Version Language Attributes Sequence
s$(MSIBUILD_LENGTH_ID) s$(MSIBUILD_LENGTH_ID) l255 i4 S$(MSIBUILD_LENGTH_ID) S20 I2 i2
File File
filewxbase.dll.$(PLAT) compwxbase.dll.$(PLAT) WXBASE~1.DLL|wxbase$(WXWIDGETS_VER)$(WXWIDGETS_CFG)$(WXWIDGETS_COMPILER)$(WXWIDGETS_PLAT).dll 0 0 512 1
filewxbase_net.dll.$(PLAT) compwxbase_net.dll.$(PLAT) WXBASE~2.DLL|wxbase$(WXWIDGETS_VER)$(WXWIDGETS_CFG)_net$(WXWIDGETS_COMPILER)$(WXWIDGETS_PLAT).dll 0 0 512 1
filewxbase_xml.dll.$(PLAT) compwxbase_xml.dll.$(PLAT) WXBASE~3.DLL|wxbase$(WXWIDGETS_VER)$(WXWIDGETS_CFG)_xml$(WXWIDGETS_COMPILER)$(WXWIDGETS_PLAT).dll 0 0 512 1
filewxwxmsw_core.dll.$(PLAT) compwxmsw_core.dll.$(PLAT) WXMSW3~1.DLL|wxmsw$(WXWIDGETS_VER)$(WXWIDGETS_CFG)_core$(WXWIDGETS_COMPILER)$(WXWIDGETS_PLAT).dll 0 0 512 1
filewxmsw_adv.dll.$(PLAT) compwxmsw_adv.dll.$(PLAT) WXMSW3~2.DLL|wxmsw$(WXWIDGETS_VER)$(WXWIDGETS_CFG)_adv$(WXWIDGETS_COMPILER)$(WXWIDGETS_PLAT).dll 0 0 512 1
filewxmsw_aui.dll.$(PLAT) compwxmsw_aui.dll.$(PLAT) WXMSW3~3.DLL|wxmsw$(WXWIDGETS_VER)$(WXWIDGETS_CFG)_aui$(WXWIDGETS_COMPILER)$(WXWIDGETS_PLAT).dll 0 0 512 1
<<NOKEEP
######################################################################
# Build MSM module!
######################################################################
!INCLUDE "..\..\MSIBuild\MSM.mak"

Binary file not shown.

BIN
Makefile

Binary file not shown.

BIN
MakefileLang.mak Normal file

Binary file not shown.

BIN
MakefileLangPlat.mak Normal file

Binary file not shown.

BIN
MakefileLangPlatCfg.mak Normal file

Binary file not shown.

BIN
MakefilePlat.mak Normal file

Binary file not shown.

BIN
MakefilePlatCfg.mak Normal file

Binary file not shown.

View File

@@ -1,4 +1,4 @@
# ZRCola
# ZRCola
A Microsoft Windows application for composing texts using a wide range of Slavic (and general) letters from or beyond Unicode.
@@ -6,30 +6,47 @@ A Microsoft Windows application for composing texts using a wide range of Slavic
http://zrcola.zrc-sazu.si/en/
## Binaries for Download
https://www.amebis.si/prenos/ZRCola/
https://prenos.amebis.si/ZRCola/
## Building
### Building Environment Requirements
- Microsoft Windows Vista or later
- Microsoft Visual Studio 2010 SP1
- Microsoft Visual Studio 2017
- _sed.exe_ and _grep.exe_
- Command line utilities from Microsoft Windows SDK Bin folder: distributed with Visual Studio, add Bin folder to path manually.
- Additional command line utilities from project's bin folder: add bin folder to path. The source code is provided on request.
- wxWidgets 3.1.1 - set `WXWIN` environment variable to the folder where wxWidgets include and lib files are located. Official binary builds are required.
### wxWidgets
ZRCola is using wxWidgets static libraries. You have to compile static libraries yourself.
#### Compiling wxWidgets Win32 static libraries
1. Start _x86 Native Tools Command Prompt for VS 2017_
2. Change working folder to `build\msw`
3. Run: `nmake /f makefile.vc /ls RUNTIME_LIBS=static SHARED=0 COMPILER_VERSION=141`
4. Run: `nmake /f makefile.vc /ls RUNTIME_LIBS=static SHARED=0 COMPILER_VERSION=141 BUILD=release`
#### Compiling wxWidgets x64 static libraries
1. Start _x64 Native Tools Command Prompt for VS 2017_
2. Change working folder to `build\msw`
3. Run: `nmake /f makefile.vc /ls RUNTIME_LIBS=static SHARED=0 COMPILER_VERSION=141 TARGET_CPU=X64`
4. Run: `nmake /f makefile.vc /ls RUNTIME_LIBS=static SHARED=0 COMPILER_VERSION=141 TARGET_CPU=X64 BUILD=release`
#### Specifying wxWidgets path
ZRCola compilation references wxWidgets libraries using `WXWIN` environment variable. Please set it to wxWidgets folder (e.g. `C:\SDK\wxWidgets`).
### Digital Signing of Build Outputs
In order to have the build process digitally sign output files, one should provide the following:
1. A signing certificate installed in the current user's certificate store.
2. The following variables in the environment:
- `ManifestCertificateThumbprint` - set the value to certificate's SHA1 thumbprint (hexadecimal, without spaces, i.e. `bc0d8da45f9eeefcbe4e334e1fc262804df88d7e`).
- `ManifestTimestampUrl` - set the value to URL used to perform timestamp signature (i.e. `http://timestamp.verisign.com/scripts/timstamp.dll`). In order to perform timestamp signing successfully, the computer running the build should be online and able to access this URL.
- `ManifestCertificateThumbprint` - set the value to certificate's SHA1 thumbprint (hexadecimal, without spaces, e.g. `f61b973226c502a732d24f41aa85e192b009e7c0`).
- `ManifestTimestampRFC3161Url` - set the value to URL used to perform RFC3161 timestamp signature (e.g. `http://time.certum.pl`). In order to perform timestamp signing successfully, the computer running the build should be online and able to access this URL.
Please note that only Release builds are configured for timestamp signing. Debug configurations do not attempt to timestamp sign the resulting DLL and EXE files in order to speed up the building process and enable offline building.
### Building
Use Microsoft NMAKE to build the project. The resulting files can be found in output subfolder.
Use Microsoft NMAKE to build the project. The resulting files can be found in output subfolder. Open _x64 Native Tools Command Prompt for VS 2017_ for building.
- `nmake Clean` Delete all intermediate and output files.
- `nmake Setup` Build a release version of project and release MSI setup files.
@@ -37,7 +54,7 @@ Use Microsoft NMAKE to build the project. The resulting files can be found in ou
- `nmake Register` Build a debug version of project, install fonts (reboot required), and Start Menu shortcuts. For development purposes only!
- `nmake Unregister` Remove Start Menu shortcuts, and fonts. For development purposes only!
The `/ls` flag can be appended to the commands above to reduce NMAKE's verbosity. You can combine multiple targets (i.e. nmake Unregister Clean). Please, see NMAKE reference for further reading.
The `/ls` flag can be appended to the commands above to reduce NMAKE's verbosity. You can combine multiple targets (e.g. nmake Unregister Clean). Please, see NMAKE reference for further reading.
## Translating ZRCola
Instructions how to translate ZRCola to your language can be found [here](LOCALIZATION.md).

Submodule Updater updated: c160d4b9eb...0ba186c984

View File

@@ -1,11 +1,13 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29728.190
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZRCola", "ZRCola\ZRCola.vcxproj", "{CD9E4170-92DD-440E-980C-D15F62032249}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{6D85AD6A-69D6-40EB-BF0C-7495479DDCE5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxExtend", "lib\wxExtend\build\wxExtendDll-10.0.vcxproj", "{A3A36689-AC35-4026-93DA-A3BA0C0E767C}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxExtend", "lib\wxExtend\build\wxExtendLib.vcxproj", "{D3E29951-D9F5-486D-A167-20AE8E90B1FA}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CFEBC17E-C840-4507-BDE6-1EF5B52DDCC5}"
ProjectSection(SolutionItems) = preProject
@@ -16,72 +18,102 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libZRCola", "lib\libZRCola\
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libZRColaUI", "lib\libZRColaUI\build\libZRColaUI.vcxproj", "{C0A84BD2-3870-4CD6-B281-0AB322E3C579}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stdex", "lib\stdex\build\stdex-10.0.vcxproj", "{518777CC-0A59-4415-A12A-82751ED75343}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stdex", "lib\stdex\build\stdex.vcxproj", "{518777CC-0A59-4415-A12A-82751ED75343}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Updater", "Updater\Updater\build\Updater.vcxproj", "{990D8CF9-4457-4DC0-AA18-4968EF434741}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinStd", "lib\WinStd\build\WinStd-10.0.vcxproj", "{47399D91-7EB9-41DE-B521-514BA5DB0C43}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinStd", "lib\WinStd\build\WinStd.vcxproj", "{47399D91-7EB9-41DE-B521-514BA5DB0C43}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|ARM64 = Release|ARM64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CD9E4170-92DD-440E-980C-D15F62032249}.Debug|ARM64.ActiveCfg = Debug|ARM64
{CD9E4170-92DD-440E-980C-D15F62032249}.Debug|ARM64.Build.0 = Debug|ARM64
{CD9E4170-92DD-440E-980C-D15F62032249}.Debug|Win32.ActiveCfg = Debug|Win32
{CD9E4170-92DD-440E-980C-D15F62032249}.Debug|Win32.Build.0 = Debug|Win32
{CD9E4170-92DD-440E-980C-D15F62032249}.Debug|x64.ActiveCfg = Debug|x64
{CD9E4170-92DD-440E-980C-D15F62032249}.Debug|x64.Build.0 = Debug|x64
{CD9E4170-92DD-440E-980C-D15F62032249}.Release|ARM64.ActiveCfg = Release|ARM64
{CD9E4170-92DD-440E-980C-D15F62032249}.Release|ARM64.Build.0 = Release|ARM64
{CD9E4170-92DD-440E-980C-D15F62032249}.Release|Win32.ActiveCfg = Release|Win32
{CD9E4170-92DD-440E-980C-D15F62032249}.Release|Win32.Build.0 = Release|Win32
{CD9E4170-92DD-440E-980C-D15F62032249}.Release|x64.ActiveCfg = Release|x64
{CD9E4170-92DD-440E-980C-D15F62032249}.Release|x64.Build.0 = Release|x64
{A3A36689-AC35-4026-93DA-A3BA0C0E767C}.Debug|Win32.ActiveCfg = Debug|Win32
{A3A36689-AC35-4026-93DA-A3BA0C0E767C}.Debug|Win32.Build.0 = Debug|Win32
{A3A36689-AC35-4026-93DA-A3BA0C0E767C}.Debug|x64.ActiveCfg = Debug|x64
{A3A36689-AC35-4026-93DA-A3BA0C0E767C}.Debug|x64.Build.0 = Debug|x64
{A3A36689-AC35-4026-93DA-A3BA0C0E767C}.Release|Win32.ActiveCfg = Release|Win32
{A3A36689-AC35-4026-93DA-A3BA0C0E767C}.Release|Win32.Build.0 = Release|Win32
{A3A36689-AC35-4026-93DA-A3BA0C0E767C}.Release|x64.ActiveCfg = Release|x64
{A3A36689-AC35-4026-93DA-A3BA0C0E767C}.Release|x64.Build.0 = Release|x64
{D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Debug|ARM64.ActiveCfg = Debug|ARM64
{D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Debug|ARM64.Build.0 = Debug|ARM64
{D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Debug|Win32.ActiveCfg = Debug|Win32
{D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Debug|Win32.Build.0 = Debug|Win32
{D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Debug|x64.ActiveCfg = Debug|x64
{D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Debug|x64.Build.0 = Debug|x64
{D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|ARM64.ActiveCfg = Release|ARM64
{D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|ARM64.Build.0 = Release|ARM64
{D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|Win32.ActiveCfg = Release|Win32
{D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|Win32.Build.0 = Release|Win32
{D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|x64.ActiveCfg = Release|x64
{D3E29951-D9F5-486D-A167-20AE8E90B1FA}.Release|x64.Build.0 = Release|x64
{3C61929E-7289-4101-8D0A-DA22D6E1AEA8}.Debug|ARM64.ActiveCfg = Debug|ARM64
{3C61929E-7289-4101-8D0A-DA22D6E1AEA8}.Debug|ARM64.Build.0 = Debug|ARM64
{3C61929E-7289-4101-8D0A-DA22D6E1AEA8}.Debug|Win32.ActiveCfg = Debug|Win32
{3C61929E-7289-4101-8D0A-DA22D6E1AEA8}.Debug|Win32.Build.0 = Debug|Win32
{3C61929E-7289-4101-8D0A-DA22D6E1AEA8}.Debug|x64.ActiveCfg = Debug|x64
{3C61929E-7289-4101-8D0A-DA22D6E1AEA8}.Debug|x64.Build.0 = Debug|x64
{3C61929E-7289-4101-8D0A-DA22D6E1AEA8}.Release|ARM64.ActiveCfg = Release|ARM64
{3C61929E-7289-4101-8D0A-DA22D6E1AEA8}.Release|ARM64.Build.0 = Release|ARM64
{3C61929E-7289-4101-8D0A-DA22D6E1AEA8}.Release|Win32.ActiveCfg = Release|Win32
{3C61929E-7289-4101-8D0A-DA22D6E1AEA8}.Release|Win32.Build.0 = Release|Win32
{3C61929E-7289-4101-8D0A-DA22D6E1AEA8}.Release|x64.ActiveCfg = Release|x64
{3C61929E-7289-4101-8D0A-DA22D6E1AEA8}.Release|x64.Build.0 = Release|x64
{C0A84BD2-3870-4CD6-B281-0AB322E3C579}.Debug|ARM64.ActiveCfg = Debug|ARM64
{C0A84BD2-3870-4CD6-B281-0AB322E3C579}.Debug|ARM64.Build.0 = Debug|ARM64
{C0A84BD2-3870-4CD6-B281-0AB322E3C579}.Debug|Win32.ActiveCfg = Debug|Win32
{C0A84BD2-3870-4CD6-B281-0AB322E3C579}.Debug|Win32.Build.0 = Debug|Win32
{C0A84BD2-3870-4CD6-B281-0AB322E3C579}.Debug|x64.ActiveCfg = Debug|x64
{C0A84BD2-3870-4CD6-B281-0AB322E3C579}.Debug|x64.Build.0 = Debug|x64
{C0A84BD2-3870-4CD6-B281-0AB322E3C579}.Release|ARM64.ActiveCfg = Release|ARM64
{C0A84BD2-3870-4CD6-B281-0AB322E3C579}.Release|ARM64.Build.0 = Release|ARM64
{C0A84BD2-3870-4CD6-B281-0AB322E3C579}.Release|Win32.ActiveCfg = Release|Win32
{C0A84BD2-3870-4CD6-B281-0AB322E3C579}.Release|Win32.Build.0 = Release|Win32
{C0A84BD2-3870-4CD6-B281-0AB322E3C579}.Release|x64.ActiveCfg = Release|x64
{C0A84BD2-3870-4CD6-B281-0AB322E3C579}.Release|x64.Build.0 = Release|x64
{518777CC-0A59-4415-A12A-82751ED75343}.Debug|ARM64.ActiveCfg = Debug|ARM64
{518777CC-0A59-4415-A12A-82751ED75343}.Debug|ARM64.Build.0 = Debug|ARM64
{518777CC-0A59-4415-A12A-82751ED75343}.Debug|Win32.ActiveCfg = Debug|Win32
{518777CC-0A59-4415-A12A-82751ED75343}.Debug|Win32.Build.0 = Debug|Win32
{518777CC-0A59-4415-A12A-82751ED75343}.Debug|x64.ActiveCfg = Debug|x64
{518777CC-0A59-4415-A12A-82751ED75343}.Debug|x64.Build.0 = Debug|x64
{518777CC-0A59-4415-A12A-82751ED75343}.Release|ARM64.ActiveCfg = Release|ARM64
{518777CC-0A59-4415-A12A-82751ED75343}.Release|ARM64.Build.0 = Release|ARM64
{518777CC-0A59-4415-A12A-82751ED75343}.Release|Win32.ActiveCfg = Release|Win32
{518777CC-0A59-4415-A12A-82751ED75343}.Release|Win32.Build.0 = Release|Win32
{518777CC-0A59-4415-A12A-82751ED75343}.Release|x64.ActiveCfg = Release|x64
{518777CC-0A59-4415-A12A-82751ED75343}.Release|x64.Build.0 = Release|x64
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Debug|ARM64.ActiveCfg = Debug|ARM64
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Debug|ARM64.Build.0 = Debug|ARM64
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Debug|Win32.ActiveCfg = Debug|Win32
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Debug|Win32.Build.0 = Debug|Win32
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Debug|x64.ActiveCfg = Debug|x64
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Debug|x64.Build.0 = Debug|x64
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Release|ARM64.ActiveCfg = Release|ARM64
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Release|ARM64.Build.0 = Release|ARM64
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Release|Win32.ActiveCfg = Release|Win32
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Release|Win32.Build.0 = Release|Win32
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Release|x64.ActiveCfg = Release|x64
{990D8CF9-4457-4DC0-AA18-4968EF434741}.Release|x64.Build.0 = Release|x64
{47399D91-7EB9-41DE-B521-514BA5DB0C43}.Debug|ARM64.ActiveCfg = Debug|ARM64
{47399D91-7EB9-41DE-B521-514BA5DB0C43}.Debug|ARM64.Build.0 = Debug|ARM64
{47399D91-7EB9-41DE-B521-514BA5DB0C43}.Debug|Win32.ActiveCfg = Debug|Win32
{47399D91-7EB9-41DE-B521-514BA5DB0C43}.Debug|Win32.Build.0 = Debug|Win32
{47399D91-7EB9-41DE-B521-514BA5DB0C43}.Debug|x64.ActiveCfg = Debug|x64
{47399D91-7EB9-41DE-B521-514BA5DB0C43}.Debug|x64.Build.0 = Debug|x64
{47399D91-7EB9-41DE-B521-514BA5DB0C43}.Release|ARM64.ActiveCfg = Release|ARM64
{47399D91-7EB9-41DE-B521-514BA5DB0C43}.Release|ARM64.Build.0 = Release|ARM64
{47399D91-7EB9-41DE-B521-514BA5DB0C43}.Release|Win32.ActiveCfg = Release|Win32
{47399D91-7EB9-41DE-B521-514BA5DB0C43}.Release|Win32.Build.0 = Release|Win32
{47399D91-7EB9-41DE-B521-514BA5DB0C43}.Release|x64.ActiveCfg = Release|x64
@@ -91,11 +123,14 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{A3A36689-AC35-4026-93DA-A3BA0C0E767C} = {6D85AD6A-69D6-40EB-BF0C-7495479DDCE5}
{D3E29951-D9F5-486D-A167-20AE8E90B1FA} = {6D85AD6A-69D6-40EB-BF0C-7495479DDCE5}
{3C61929E-7289-4101-8D0A-DA22D6E1AEA8} = {6D85AD6A-69D6-40EB-BF0C-7495479DDCE5}
{C0A84BD2-3870-4CD6-B281-0AB322E3C579} = {6D85AD6A-69D6-40EB-BF0C-7495479DDCE5}
{518777CC-0A59-4415-A12A-82751ED75343} = {6D85AD6A-69D6-40EB-BF0C-7495479DDCE5}
{990D8CF9-4457-4DC0-AA18-4968EF434741} = {6D85AD6A-69D6-40EB-BF0C-7495479DDCE5}
{47399D91-7EB9-41DE-B521-514BA5DB0C43} = {6D85AD6A-69D6-40EB-BF0C-7495479DDCE5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EECB5329-0607-4D77-8BC0-48BD8C08BEF9}
EndGlobalSection
EndGlobal

Binary file not shown.

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>..\output\$(Platform).$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\lib\wxExtend\include;..\Updater\Updater\include;..\lib\stdex\include;..\lib\WinStd\include;..\lib\libZRCola\include;..\lib\libZRColaUI\include</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

Binary file not shown.

View File

@@ -1,6 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
@@ -9,6 +13,10 @@
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
@@ -23,62 +31,45 @@
<RootNamespace>ZRCola</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)'=='Debug'">
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)'=='Release'">
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PropertyGroup Label="Configuration" Condition="'$(Platform)'=='ARM64'">
<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\Win32.props" />
<Import Project="..\include\Debug.props" />
<Import Project="ZRCola.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\x64.props" />
<Import Project="..\include\Debug.props" />
<Import Project="ZRCola.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\Win32.props" />
<Import Project="..\include\Release.props" />
<Import Project="ZRCola.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\x64.props" />
<Import Project="..\include\Release.props" />
<Import Project="ZRCola.props" />
<Import Project="..\include\$(Platform).props" />
<Import Project="..\include\$(Configuration).props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>..\output\$(Platform).$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\lib\wxExtend\include;..\Updater\Updater\include;..\lib\stdex\include;..\lib\WinStd\include;..\lib\libZRCola\include;..\lib\libZRColaUI\include</AdditionalIncludeDirectories>
</ClCompile>
<Manifest>
<EnableDpiAwareness>true</EnableDpiAwareness>
</Manifest>
<ResourceCompile>
<AdditionalIncludeDirectories>..\Updater\Updater\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="zrcolaabout.cpp" />
<ClCompile Include="zrcolaapp.cpp" />
@@ -91,10 +82,11 @@
<ClCompile Include="zrcolagui.cpp" />
<ClCompile Include="zrcolakeyhndlr.cpp" />
<ClCompile Include="zrcolasettings.cpp" />
<ClCompile Include="zrcolatranseq.cpp" />
<ClCompile Include="zrcolaupdater.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="zrcolaabout.h" />
<ClInclude Include="zrcolaapp.h" />
<ClInclude Include="zrcolachrcatpnl.h" />
@@ -106,6 +98,7 @@
<ClInclude Include="zrcolagui.h" />
<ClInclude Include="zrcolakeyhndlr.h" />
<ClInclude Include="zrcolasettings.h" />
<ClInclude Include="zrcolatranseq.h" />
<ClInclude Include="zrcolaupdater.h" />
</ItemGroup>
<ItemGroup>
@@ -115,11 +108,11 @@
<ProjectReference Include="..\lib\libZRCola\build\libZRCola.vcxproj">
<Project>{3c61929e-7289-4101-8d0a-da22d6e1aea8}</Project>
</ProjectReference>
<ProjectReference Include="..\lib\WinStd\build\WinStd-10.0.vcxproj">
<ProjectReference Include="..\lib\WinStd\build\WinStd.vcxproj">
<Project>{47399d91-7eb9-41de-b521-514ba5db0c43}</Project>
</ProjectReference>
<ProjectReference Include="..\lib\wxExtend\build\wxExtendDll-10.0.vcxproj">
<Project>{a3a36689-ac35-4026-93da-a3ba0c0e767c}</Project>
<ProjectReference Include="..\lib\wxExtend\build\wxExtendLib.vcxproj">
<Project>{D3E29951-D9F5-486D-A167-20AE8E90B1FA}</Project>
</ProjectReference>
<ProjectReference Include="..\Updater\Updater\build\Updater.vcxproj">
<Project>{990d8cf9-4457-4dc0-aa18-4968ef434741}</Project>
@@ -128,6 +121,8 @@
<ItemGroup>
<None Include="locale\ZRCola.pot" />
<None Include="res\char_select.ico" />
<None Include="res\copy_composed_and_return.ico" />
<None Include="res\copy_decomposed_and_return.ico" />
<None Include="res\edit_copy.ico" />
<None Include="res\edit_cut.ico" />
<None Include="res\edit_paste.ico" />
@@ -137,7 +132,9 @@
<None Include="res\send_composed.ico" />
<None Include="res\send_decomposed.ico" />
<None Include="res\zrcola.ico" />
<None Include="ZRCola.fbp" />
<None Include="res\ZRCola.fbp">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ZRCola.rc" />
@@ -147,6 +144,9 @@
<POCompile Include="locale\ru_RU.po" />
<POCompile Include="locale\sl_SI.po" />
</ItemGroup>
<ItemGroup>
<Image Include="res\composition.ico" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\include\xgettext.targets" />

View File

@@ -19,7 +19,7 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="zrcolaapp.cpp">
@@ -58,9 +58,12 @@
<ClCompile Include="zrcolachrreq.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="zrcolatranseq.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="zrcolaapp.h">
@@ -99,6 +102,9 @@
<ClInclude Include="zrcolachrreq.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="zrcolatranseq.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="res\zrcola.ico">
@@ -122,7 +128,7 @@
<None Include="res\edit_paste.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="ZRCola.fbp">
<None Include="res\ZRCola.fbp">
<Filter>Resource Files</Filter>
</None>
<None Include="res\char_select.ico">
@@ -137,6 +143,12 @@
<None Include="res\navigate_forward.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="res\copy_composed_and_return.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="res\copy_decomposed_and_return.ico">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ZRCola.rc">
@@ -154,4 +166,9 @@
<Filter>Resource Files\Localization</Filter>
</POCompile>
</ItemGroup>
<ItemGroup>
<Image Include="res\composition.ico">
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

6
ZRCola/pch.cpp Normal file
View File

@@ -0,0 +1,6 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#include "pch.h"

View File

@@ -1,61 +1,56 @@
/*
Copyright 2015-2017 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 "../include/version.h"
#include "zrcolaabout.h"
#include "zrcolaapp.h"
#include "zrcolachrcatpnl.h"
#include "zrcolachrgrid.h"
#include "zrcolachrreq.h"
#include "zrcolacomppnl.h"
#include "zrcolafrm.h"
#include "zrcolakeyhndlr.h"
#include "zrcolasettings.h"
#include "zrcolaupdater.h"
#include <Updater/chkthread.h>
#include <wxex/common.h>
#include <wxex/url.h>
#include <wxex/persist/auimanager.h>
#include <wx/ffile.h>
#include <wx/msgdlg.h>
#include <wx/persist.h>
#include <wx/persist/toplevel.h>
#include <wx/utils.h>
#include <wx/valtext.h>
#include <wx/socket.h>
#include <WinStd/MSI.h>
#include <fstream>
#include <string>
#include <utility>
#include <vector>
#include <stdex/idrec.h>
#if defined(__WXMSW__)
#include <Msi.h>
#include <ShObjIdl.h>
#include <ShlGuid.h>
#endif
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#pragma once
#include "../include/version.h"
#include "zrcolaabout.h"
#include "zrcolaapp.h"
#include "zrcolachrcatpnl.h"
#include "zrcolachrgrid.h"
#include "zrcolachrreq.h"
#include "zrcolacomppnl.h"
#include "zrcolafrm.h"
#include "zrcolakeyhndlr.h"
#include "zrcolasettings.h"
#include "zrcolatranseq.h"
#include "zrcolaupdater.h"
#include <Updater/chkthread.h>
#include <wxex/common.h>
#include <wxex/url.h>
#include <wxex/persist/auimanager.h>
#include <wxex/persist/toplevel.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include <wx/clipbrd.h>
#include <wx/dcclient.h>
#include <wx/ffile.h>
#include <wx/fontdlg.h>
#include <wx/msgdlg.h>
#include <wx/persist.h>
#include <wx/persist/toplevel.h>
#include <wx/socket.h>
#include <wx/tokenzr.h>
#include <wx/utils.h>
#include <wx/valtext.h>
#pragma warning(pop)
#include <WinStd/MSI.h>
#include <fstream>
#include <string>
#include <utility>
#include <vector>
#include <stdex/idrec.h>
#if defined(__WXMSW__)
#include <Msi.h>
#include <ShObjIdl.h>
#include <ShlGuid.h>
#endif

File diff suppressed because it is too large Load Diff

BIN
ZRCola/res/composition.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

2070
ZRCola/res/composition.pdf Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

File diff suppressed because one or more lines are too long

View File

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View File

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

BIN
ZRCola/res/warn_pua.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

1690
ZRCola/res/warn_pua.pdf Normal file

File diff suppressed because one or more lines are too long

1274
ZRCola/res/zrcolagui.cpp Normal file

File diff suppressed because it is too large Load Diff

423
ZRCola/res/zrcolagui.h Normal file
View File

@@ -0,0 +1,423 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/cshelp.h>
#include <wx/intl.h>
class wxZRColaCharGrid;
#include <wx/string.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/menu.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/aui/aui.h>
#include <wx/aui/auibar.h>
#include <wx/choice.h>
#include <wx/fontpicker.h>
class wxZRColaCharacterCatalogPanel;
class wxZRColaComposerPanel;
#include <wx/statusbr.h>
#include <wx/frame.h>
#include <wx/textctrl.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <wx/panel.h>
#include <wx/splitter.h>
#include <wx/timer.h>
#include <wx/grid.h>
#include <wx/checkbox.h>
#include <wx/srchctrl.h>
#include <wx/hyperlink.h>
#include <wx/checklst.h>
#include <wx/stattext.h>
#include <wx/button.h>
#include <wx/dialog.h>
#include <wx/radiobut.h>
#include <wx/listbox.h>
#include <wx/listbook.h>
#include <wx/listctrl.h>
#include <wx/statbmp.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaFrameBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaFrameBase : public wxFrame
{
private:
protected:
enum
{
wxID_CHARACTER_SELECTOR = 1000,
wxID_SEND_DESTINATION,
wxID_COPY_DESTINATION_AND_RETURN,
wxID_SEND_SOURCE,
wxID_COPY_SOURCE_AND_RETURN,
wxID_SEND_ABORT,
wxID_COMPOSITION,
wxID_FONT_DESTINATION,
wxID_WARN_PUA,
wxID_SETTINGS,
wxID_TOOLBAR_EDIT,
wxID_TOOLBAR_TRANSLATE,
wxID_TOOLBAR_DESTINATION,
wxID_PANEL_CHRGRPS,
wxID_HELP_INSTRUCTIONS,
wxID_HELP_SHORTCUTS,
wxID_HELP_REQCHAR,
wxID_HELP_UPDATE
};
wxMenuBar* m_menubar;
wxMenu* m_menuProgram;
wxMenu* m_menuEdit;
wxMenuItem* m_menuItemComposition;
wxMenu* m_menuTranslationSeq;
wxMenuItem* m_menuItemWarnPUA;
wxMenu* m_menuView;
wxMenu* m_menuHelp;
wxAuiToolBar* m_toolbarEdit;
wxAuiToolBarItem* m_toolEditCut;
wxAuiToolBarItem* m_toolEditCopy;
wxAuiToolBarItem* m_toolEditPaste;
wxAuiToolBar* m_toolbarTranslate;
wxAuiToolBarItem* m_toolCharSelect;
wxAuiToolBarItem* m_toolSendDestination;
wxAuiToolBarItem* m_toolSendSource;
wxAuiToolBarItem* m_toolComposition;
wxChoice* m_toolTranslationSeq;
wxAuiToolBar* m_toolbarDestination;
wxFontPickerCtrl* m_fontpickerDestination;
wxAuiToolBarItem* m_toolWarnPUA;
wxZRColaCharacterCatalogPanel* m_panelChrCat;
wxStatusBar* m_statusBar;
// Virtual event handlers, overide them in your derived class
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnIconize( wxIconizeEvent& event ) { event.Skip(); }
virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); }
virtual void OnTranslationSeqChoice( wxCommandEvent& event ) { event.Skip(); }
virtual void OnFontDestinationChanged( wxFontPickerEvent& event ) { event.Skip(); }
public:
wxZRColaComposerPanel* m_panel;
wxZRColaFrameBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("ZRCola"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 660,450 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL, const wxString& name = wxT("ZRCola") );
wxAuiManager m_mgr;
~wxZRColaFrameBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaComposerPanelBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaComposerPanelBase : public wxPanel
{
private:
protected:
enum
{
wxID_TIMER_SAVE = 1000
};
wxSplitterWindow* m_splitterSource;
wxPanel* m_panelSourceEdit;
wxPanel* m_panelSourceHex;
wxTextCtrl* m_sourceHex;
wxSplitterWindow* m_splitterDestination;
wxPanel* m_panelDestinationEdit;
wxPanel* m_panelDestinationHex;
wxTextCtrl* m_destinationHex;
wxTimer m_timerSave;
// Virtual event handlers, overide them in your derived class
virtual void OnSourcePaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnSourceText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSourceHexPaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnDestinationPaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnDestinationText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnDestinationHexPaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnSaveTimer( wxTimerEvent& event ) { event.Skip(); }
public:
wxTextCtrl* m_source;
wxTextCtrl* m_destination;
wxZRColaComposerPanelBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxT("ZRColaComposerPanel") );
~wxZRColaComposerPanelBase();
void m_splitterSourceOnIdle( wxIdleEvent& )
{
m_splitterSource->SetSashPosition( -5 );
m_splitterSource->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaComposerPanelBase::m_splitterSourceOnIdle ), NULL, this );
}
void m_splitterDestinationOnIdle( wxIdleEvent& )
{
m_splitterDestination->SetSashPosition( -5 );
m_splitterDestination->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaComposerPanelBase::m_splitterDestinationOnIdle ), NULL, this );
}
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaCharacterCatalogPanelBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaCharacterCatalogPanelBase : public wxPanel
{
private:
protected:
wxChoice* m_choice;
wxZRColaCharGrid* m_grid;
wxCheckBox* m_show_all;
// Virtual event handlers, overide them in your derived class
virtual void OnChoice( wxCommandEvent& event ) { event.Skip(); }
virtual void OnGridClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnGridKeyDown( wxKeyEvent& event ) { event.Skip(); }
virtual void OnShowAll( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaCharacterCatalogPanelBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxT("ZRColaCharacterCatalog") );
~wxZRColaCharacterCatalogPanelBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaCharSelectBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaCharSelectBase : public wxDialog
{
private:
protected:
wxSearchCtrl* m_search;
wxHyperlinkCtrl* m_search_more;
wxPanel* m_search_panel;
wxCheckListBox* m_categories;
wxHyperlinkCtrl* m_categoriesAll;
wxHyperlinkCtrl* m_categoriesNone;
wxHyperlinkCtrl* m_categoriesInvert;
wxZRColaCharGrid* m_gridResults;
wxZRColaCharGrid* m_gridRecent;
wxStaticText* m_labelUnicode;
wxTextCtrl* m_unicode;
wxTextCtrl* m_shortcut;
wxGrid* m_gridPreview;
wxTextCtrl* m_description;
wxTextCtrl* m_tags;
wxTextCtrl* m_category;
wxHyperlinkCtrl* m_navigateBack;
wxHyperlinkCtrl* m_navigateForward;
wxZRColaCharGrid* m_gridRelated;
wxButton* m_buttonInsert;
// Virtual event handlers, overide them in your derived class
virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); }
virtual void OnSearchText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSearchMore( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnCategoriesToggle( wxCommandEvent& event ) { event.Skip(); }
virtual void OnCategoriesAll( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnCategoriesNone( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnCategoriesInvert( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnResultCellDClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnResultSelectCell( wxGridEvent& event ) { event.Skip(); }
virtual void OnResultsKeyDown( wxKeyEvent& event ) { event.Skip(); }
virtual void OnRecentCellDClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnRecentSelectCell( wxGridEvent& event ) { event.Skip(); }
virtual void OnRecentKeyDown( wxKeyEvent& event ) { event.Skip(); }
virtual void OnUnicodeText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnPreviewKeyDown( wxKeyEvent& event ) { event.Skip(); }
virtual void OnNavigateBack( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnNavigateForward( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnRelatedSelectCell( wxGridEvent& event ) { event.Skip(); }
virtual void OnInsert( wxCommandEvent& event ) { event.Skip(); }
virtual void OnInsertUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
public:
wxZRColaCharSelectBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Character Search"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaCharSelect") );
~wxZRColaCharSelectBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaSettingsBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaSettingsBase : public wxDialog
{
private:
protected:
wxListbook* m_listbook;
wxPanel* m_panelLanguage;
wxStaticText* m_langLabel;
wxRadioButton* m_langAuto;
wxRadioButton* m_langManual;
wxListBox* m_languages;
wxPanel* m_panelAutoStart;
wxStaticText* m_autoStartLabel;
wxCheckBox* m_autoStart;
wxStdDialogButtonSizer* m_sdbSizerButtons;
wxButton* m_sdbSizerButtonsOK;
wxButton* m_sdbSizerButtonsApply;
wxButton* m_sdbSizerButtonsCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
virtual void OnLanguageUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnApplyButtonClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOKButtonClick( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaSettingsBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaSettings") );
~wxZRColaSettingsBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaAboutBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaAboutBase : public wxDialog
{
private:
protected:
wxStaticBitmap* m_bitmapIcon;
wxStaticText* m_staticTextZRCola;
wxStaticText* m_staticTextVersion;
wxStaticText* m_staticTextColophone;
wxStaticText* m_staticTextCopyright;
wxHyperlinkCtrl* m_hyperlink;
wxStaticText* m_staticTextDeclaration;
wxTextCtrl* m_declaration;
wxStdDialogButtonSizer* m_sdbSizerButtons;
wxButton* m_sdbSizerButtonsOK;
public:
wxZRColaAboutBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About ZRCola"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaAbout") );
~wxZRColaAboutBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaUpdaterBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaUpdaterBase : public wxDialog
{
private:
protected:
wxTextCtrl* m_log;
wxButton* m_buttonUpdate;
wxButton* m_buttonClose;
// Virtual event handlers, overide them in your derived class
virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); }
virtual void OnUpdate( wxCommandEvent& event ) { event.Skip(); }
virtual void OnClose( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaUpdaterBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Product Update"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaUpdater") );
~wxZRColaUpdaterBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaCharRequestBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaCharRequestBase : public wxDialog
{
private:
protected:
wxStaticText* m_characterLbl;
wxTextCtrl* m_character;
wxStaticText* m_characterNote;
wxStaticText* m_contextLbl;
wxTextCtrl* m_context;
wxStaticText* m_note;
wxStdDialogButtonSizer* m_sdbSizerButtons;
wxButton* m_sdbSizerButtonsOK;
wxButton* m_sdbSizerButtonsCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnOKButtonClick( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaCharRequestBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Request a New Character"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaCharRequest") );
~wxZRColaCharRequestBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaTranslationSeqBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaTranslationSeqBase : public wxDialog
{
private:
protected:
wxStaticText* m_transLbl;
wxStaticText* m_availableLbl;
wxListBox* m_available;
wxButton* m_add;
wxButton* m_remove;
wxStaticText* m_selectedLbl;
wxListBox* m_selected;
wxButton* m_selectedUp;
wxButton* m_selectedDown;
wxStdDialogButtonSizer* m_sdbSizerButtons;
wxButton* m_sdbSizerButtonsOK;
wxButton* m_sdbSizerButtonsCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
virtual void OnUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnAvailableChar( wxKeyEvent& event ) { event.Skip(); }
virtual void OnAvailableDClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnAdd( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRemove( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSelectedChar( wxKeyEvent& event ) { event.Skip(); }
virtual void OnSelectedDClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSelectedUp( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSelectedDown( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOKButtonClick( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaTranslationSeqBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Custom Translation Sequence"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaTranslationSeq") );
~wxZRColaTranslationSeqBase();
};

View File

@@ -1,20 +0,0 @@
/*
Copyright 2015-2017 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"

View File

@@ -1,23 +1,9 @@
/*
Copyright 2015-2017 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/>.
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#include "stdafx.h"
#include "pch.h"
//////////////////////////////////////////////////////////////////////////

View File

@@ -1,20 +1,6 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
///
@@ -25,7 +11,11 @@ class wxZRColaAbout;
#pragma once
#include <wxex/common.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include "zrcolagui.h"
#pragma warning(pop)
///

View File

@@ -1,23 +1,9 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#include "stdafx.h"
#include "pch.h"
#if defined(__WXMSW__)
#pragma comment(lib, "msi.lib")
#endif
@@ -27,11 +13,13 @@
// ZRColaApp
//////////////////////////////////////////////////////////////////////////
#pragma warning(suppress: 28251) // wxWidgets implement WinMain without code analysis annotations.
wxIMPLEMENT_APP(ZRColaApp);
ZRColaApp::ZRColaApp() :
m_mainWnd(NULL),
#pragma warning(suppress: 26812) // wxLanguage is unscoped
m_lang_ui(wxLANGUAGE_DEFAULT),
wxApp()
{
@@ -102,6 +90,18 @@ bool ZRColaApp::OnInit()
wxFAIL_MSG(wxT("Error reading translation data from ZRCola.zrcdb."));
m_t_db.clear();
}
} else if (id == ZRCola::transet_rec::id) {
dat >> ZRCola::transet_rec(m_ts_db);
if (!dat.good()) {
wxFAIL_MSG(wxT("Error reading translation set data from ZRCola.zrcdb."));
m_ts_db.clear();
}
} else if (id == ZRCola::transeq_rec::id) {
dat >> ZRCola::transeq_rec(m_tsq_db);
if (!dat.good()) {
wxFAIL_MSG(wxT("Error reading translation sequence data from ZRCola.zrcdb."));
m_tsq_db.clear();
}
} else if (id == ZRCola::langchar_rec::id) {
dat >> ZRCola::langchar_rec(m_lc_db);
if (!dat.good()) {
@@ -153,13 +153,14 @@ bool ZRColaApp::OnInit()
}
} else
wxFAIL_MSG(wxT("ZRCola.zrcdb is not a valid ZRCola database."));
}
} else
wxFAIL_MSG(wxT("ZRCola.zrcdb not found or cannot be opened."));
// Initialize sockets. Otherwise Updater thread will not work.
wxSocketBase::Initialize();
m_mainWnd = new wxZRColaFrame();
wxPersistentRegisterAndRestore<wxZRColaFrame>(m_mainWnd);
m_mainWnd->m_panel->RestoreFromStateFile();
m_mainWnd->Show();
return true;

View File

@@ -1,20 +1,6 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
///
@@ -27,9 +13,13 @@ class ZRColaApp;
#include "zrcolafrm.h"
#include <WinStd/Win.h>
#include <wxex/common.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include <wx/app.h>
#include <wx/config.h>
#include <wx/intl.h>
#pragma warning(pop)
#include <zrcola/character.h>
#include <zrcola/language.h>
#include <zrcola/translate.h>
@@ -73,6 +63,8 @@ public:
public:
ZRCola::translation_db m_t_db; ///< Translation database
ZRCola::transet_db m_ts_db; ///< Translation set database
ZRCola::transeq_db m_tsq_db; ///< Translation sequence database
ZRCola::langchar_db m_lc_db; ///< Language character database
ZRCola::language_db m_lang_db; ///< Language database
ZRCola::keyseq_db m_ks_db; ///< Key sequence database
@@ -88,7 +80,7 @@ public:
protected:
#ifdef __WXMSW__
winstd::win_handle m_running; ///< Global Win32 event to determine if another instance of ZRCola is already running
winstd::win_handle<NULL> m_running; ///< Global Win32 event to determine if another instance of ZRCola is already running
#endif
};

View File

@@ -1,23 +1,9 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#include "stdafx.h"
#include "pch.h"
//////////////////////////////////////////////////////////////////////////
@@ -25,11 +11,13 @@
//////////////////////////////////////////////////////////////////////////
BEGIN_EVENT_TABLE(wxZRColaCharacterCatalogPanel, wxZRColaCharacterCatalogPanelBase)
EVT_MENU(wxZRColaCharacterCatalogPanel::wxID_FOCUS_DECOMPOSED, wxZRColaCharacterCatalogPanel::OnFocusDecomposed)
EVT_MENU(wxZRColaCharacterCatalogPanel::wxID_FOCUS_SOURCE, wxZRColaCharacterCatalogPanel::OnFocusSource)
END_EVENT_TABLE()
wxZRColaCharacterCatalogPanel::wxZRColaCharacterCatalogPanel(wxWindow* parent) : wxZRColaCharacterCatalogPanelBase(parent)
wxZRColaCharacterCatalogPanel::wxZRColaCharacterCatalogPanel(wxWindow* parent) :
m_cg_id(0),
wxZRColaCharacterCatalogPanelBase(parent)
{
std::fstream dat((LPCTSTR)dynamic_cast<ZRColaApp*>(wxTheApp)->GetDatabaseFilePath(), std::ios_base::in | std::ios_base::binary);
if (dat.good()) {
@@ -42,26 +30,27 @@ wxZRColaCharacterCatalogPanel::wxZRColaCharacterCatalogPanel(wxWindow* parent) :
dat >> rec;
if (!dat.good()) {
wxFAIL_MSG(wxT("Error reading character group data from ZRCola.zrcdb."));
m_cg_db.idxRnk.clear();
m_cg_db.data .clear();
m_cg_db.idxRank.clear();
m_cg_db.data .clear();
}
} else
wxFAIL_MSG(wxT("ZRCola.zrcdb has no character group data."));
}
} else
wxFAIL_MSG(wxT("ZRCola.zrcdb is not a valid ZRCola database."));
}
} else
wxFAIL_MSG(wxT("ZRCola.zrcdb not found or cannot be opened."));
if (!m_cg_db.idxRnk.empty()) {
if (!m_cg_db.idxRank.empty()) {
// Populate character group list.
for (size_t i = 0, n = m_cg_db.idxRnk.size(); i < n; i++) {
const ZRCola::chrgrp_db::chrgrp &cg = m_cg_db.idxRnk[i];
for (size_t i = 0, n = m_cg_db.idxRank.size(); i < n; i++) {
const ZRCola::chrgrp_db::chrgrp &cg = m_cg_db.idxRank[i];
wxString
label(cg.data, cg.name_len),
label(cg.name(), cg.name_len()),
label_tran2(wxGetTranslation(label, wxT("ZRCola-zrcdb")));
m_choice->Insert(label_tran2, i);
m_choice->Insert(label_tran2, (unsigned int)i);
}
m_cg_id = m_cg_db.idxRnk[0].id;
m_cg_id = m_cg_db.idxRank[0].grp;
m_choice->Select(0);
Update();
@@ -70,7 +59,7 @@ wxZRColaCharacterCatalogPanel::wxZRColaCharacterCatalogPanel(wxWindow* parent) :
// Register frame specific hotkey(s).
{
wxAcceleratorEntry entries[1];
entries[0].Set(wxACCEL_NORMAL, WXK_ESCAPE, wxID_FOCUS_DECOMPOSED);
entries[0].Set(wxACCEL_NORMAL, WXK_ESCAPE, wxID_FOCUS_SOURCE);
SetAcceleratorTable(wxAcceleratorTable(_countof(entries), entries));
}
}
@@ -83,10 +72,10 @@ wxZRColaCharacterCatalogPanel::~wxZRColaCharacterCatalogPanel()
void wxZRColaCharacterCatalogPanel::OnChoice(wxCommandEvent& event)
{
const ZRCola::chrgrp_db::chrgrp &cg = m_cg_db.idxRnk[event.GetSelection()];
const ZRCola::chrgrp_db::chrgrp &cg = m_cg_db.idxRank[event.GetSelection()];
if (m_cg_id != cg.id) {
m_cg_id = cg.id;
if (m_cg_id != cg.grp) {
m_cg_id = cg.grp;
Update();
}
@@ -98,8 +87,8 @@ void wxZRColaCharacterCatalogPanel::OnGridClick(wxGridEvent& event)
{
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
if (app->m_mainWnd) {
app->m_mainWnd->m_panel->m_decomposed->WriteText(m_grid->GetCellValue(event.GetRow(), event.GetCol()));
app->m_mainWnd->m_panel->m_decomposed->SetFocus();
app->m_mainWnd->m_panel->m_source->WriteText(m_grid->GetCellValue(event.GetRow(), event.GetCol()));
app->m_mainWnd->m_panel->m_source->SetFocus();
}
event.Skip();
@@ -113,8 +102,8 @@ void wxZRColaCharacterCatalogPanel::OnGridKeyDown(wxKeyEvent& event)
case WXK_NUMPAD_ENTER:
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
if (app->m_mainWnd) {
app->m_mainWnd->m_panel->m_decomposed->WriteText(m_grid->GetCellValue(m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol()));
app->m_mainWnd->m_panel->m_decomposed->SetFocus();
app->m_mainWnd->m_panel->m_source->WriteText(m_grid->GetCellValue(m_grid->GetGridCursorRow(), m_grid->GetGridCursorCol()));
app->m_mainWnd->m_panel->m_source->SetFocus();
event.StopPropagation();
return;
@@ -135,11 +124,11 @@ void wxZRColaCharacterCatalogPanel::OnShowAll(wxCommandEvent& event)
}
void wxZRColaCharacterCatalogPanel::OnFocusDecomposed(wxCommandEvent& event)
void wxZRColaCharacterCatalogPanel::OnFocusSource(wxCommandEvent& event)
{
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
if (app->m_mainWnd) {
app->m_mainWnd->m_panel->m_decomposed->SetFocus();
app->m_mainWnd->m_panel->m_source->SetFocus();
event.StopPropagation();
return;
@@ -151,21 +140,23 @@ void wxZRColaCharacterCatalogPanel::OnFocusDecomposed(wxCommandEvent& event)
void wxZRColaCharacterCatalogPanel::Update()
{
const ZRCola::chrgrp_db::chrgrp &cg = m_cg_db.idxRnk[m_choice->GetSelection()];
const ZRCola::chrgrp_db::chrgrp &cg = m_cg_db.idxRank[m_choice->GetSelection()];
if (m_show_all->GetValue()) {
m_grid->SetCharacters(
wxString(cg.get_chars(), cg.char_len),
wxArrayShort((const short*)cg.get_char_shown(), (const short*)cg.get_char_shown() + (cg.char_len + 15)/16));
wxString(cg.chrlst(), cg.chrlst_end()),
wxArrayShort(reinterpret_cast<const short*>(cg.chrshow()), reinterpret_cast<const short*>(cg.chrshow_end())));
} else {
// Select frequently used characters only.
const wchar_t *src = cg.get_chars();
const unsigned __int16 *shown = cg.get_char_shown();
wxString chars;
for (unsigned __int16 i = 0, j = 0; i < cg.char_len; j++) {
for (unsigned __int16 k = 0, mask = shown[j]; k < 16 && i < cg.char_len; k++, mask >>= 1, i++) {
const wchar_t *src = cg.chrlst();
const unsigned __int16 *shown = cg.chrshow();
wxArrayString chars;
for (size_t i = 0, i_end = cg.chrlst_len(), j = 0; i < i_end; j++) {
for (unsigned __int16 k = 0, mask = shown[j]; k < 16 && i < i_end; k++, mask >>= 1) {
size_t len = wcsnlen(src + i, i_end - i);
if (mask & 1)
chars += src[i];
chars.Add(wxString(src + i, len));
i += len + 1;
}
}
m_grid->SetCharacters(chars);
@@ -208,12 +199,12 @@ bool wxPersistentZRColaCharacterCatalogPanel::Restore()
// Restore selected character group.
int cg_id;
if (RestoreValue(wxT("charGroup"), &cg_id)) {
for (size_t i = 0, n = wnd->m_cg_db.idxRnk.size(); i < n; i++) {
const ZRCola::chrgrp_db::chrgrp &cg = wnd->m_cg_db.idxRnk[i];
if (cg.id == cg_id) {
if (wnd->m_cg_id != cg.id) {
wnd->m_cg_id = cg.id;
wnd->m_choice->Select(i);
for (size_t i = 0, n = wnd->m_cg_db.idxRank.size(); i < n; i++) {
const ZRCola::chrgrp_db::chrgrp &cg = wnd->m_cg_db.idxRank[i];
if (cg.grp == cg_id) {
if (wnd->m_cg_id != cg.grp) {
wnd->m_cg_id = cg.grp;
wnd->m_choice->Select((int)i);
update = true;
}

View File

@@ -1,20 +1,6 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
///
@@ -25,9 +11,16 @@ class wxZRColaCharacterCatalogPanel;
#pragma once
#include <wxex/common.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include "zrcolagui.h"
#pragma warning(pop)
#include <zrcolaui/chargroup.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include <wx/persist/window.h>
#pragma warning(pop)
///
@@ -38,7 +31,7 @@ class wxZRColaCharacterCatalogPanel : public wxZRColaCharacterCatalogPanelBase
public:
enum
{
wxID_FOCUS_DECOMPOSED = 6000,
wxID_FOCUS_SOURCE = 6000,
};
wxZRColaCharacterCatalogPanel(wxWindow* parent);
@@ -51,7 +44,7 @@ protected:
virtual void OnGridClick(wxGridEvent& event);
virtual void OnGridKeyDown(wxKeyEvent& event);
virtual void OnShowAll(wxCommandEvent& event);
void OnFocusDecomposed(wxCommandEvent& event);
void OnFocusSource(wxCommandEvent& event);
DECLARE_EVENT_TABLE()
void Update();

View File

@@ -1,23 +1,9 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#include "stdafx.h"
#include "pch.h"
//////////////////////////////////////////////////////////////////////////
@@ -41,7 +27,7 @@ wxZRColaCharGrid::wxZRColaCharGrid(wxWindow *parent, wxWindowID id, const wxPoin
{
Init();
SetDefaultRowSize(wxZRColaCharacterGridRowHeight);
SetDefaultRowSize(FromDIP(wxZRColaCharacterGridRowHeight));
// Create timer for saving the state.
m_timerToolTip.SetOwner(this, wxID_TOOLTIP_TIMER);
@@ -68,6 +54,24 @@ void wxZRColaCharGrid::Init()
void wxZRColaCharGrid::SetCharacters(const wxString &chars)
{
m_chars.Clear();
const wxCStrData chr = chars.GetData();
for (size_t i = 0, i_end = chars.Length(), i_next; i < i_end; i = i_next + 1) {
i_next = i + _tcsnlen(chr + i, i_end - i);
m_chars.Add(wxString(chr + i, chr + i_next));
};
m_relevance.Clear();
m_regenerate = true;
// Invoke OnSize(), which will populate the grid.
wxSizeEvent e(GetSize(), m_windowId);
e.SetEventObject(this);
HandleWindowEvent(e);
}
void wxZRColaCharGrid::SetCharacters(const wxArrayString &chars)
{
m_chars = chars;
m_relevance.Clear();
@@ -82,7 +86,12 @@ void wxZRColaCharGrid::SetCharacters(const wxString &chars)
void wxZRColaCharGrid::SetCharacters(const wxString &chars, const wxArrayShort &relevance)
{
m_chars = chars;
m_chars.Clear();
const wxCStrData chr = chars.GetData();
for (size_t i = 0, i_end = chars.Length(), i_next; i < i_end; i = i_next + 1) {
i_next = i + _tcsnlen(chr + i, i_end - i);
m_chars.Add(wxString(chr + i, chr + i_next));
};
m_relevance = relevance;
m_regenerate = true;
@@ -95,22 +104,23 @@ void wxZRColaCharGrid::SetCharacters(const wxString &chars, const wxArrayShort &
wxString wxZRColaCharGrid::GetToolTipText(int idx)
{
wxASSERT_MSG(idx < (int)m_chars.Length(), wxT("index out of bounds"));
wxASSERT_MSG(idx < (int)m_chars.GetCount(), wxT("index out of bounds"));
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
const auto &chr = m_chars[idx];
// See if this character has a key sequence registered.
char ks[sizeof(ZRCola::keyseq_db::keyseq)] = {};
((ZRCola::keyseq_db::keyseq*)ks)->chr = m_chars[idx];
std::unique_ptr<ZRCola::keyseq_db::keyseq> ks((ZRCola::keyseq_db::keyseq*)new char[sizeof(ZRCola::keyseq_db::keyseq) + sizeof(wchar_t)*chr.length()]);
ks->ZRCola::keyseq_db::keyseq::keyseq(NULL, 0, chr.data(), chr.length());
ZRCola::keyseq_db::indexKey::size_type start;
if (app->m_ks_db.idxChr.find(*(ZRCola::keyseq_db::keyseq*)ks, start)) {
if (app->m_ks_db.idxChr.find(*ks, start)) {
ZRCola::keyseq_db::keyseq &seq = app->m_ks_db.idxChr[start];
wxString ks_str;
if (ZRCola::keyseq_db::GetSequenceAsText(seq.seq, seq.seq_len, ks_str))
return wxString::Format(wxT("U+%04X (%s)"), (int)m_chars[idx], ks_str.c_str());
if (ZRCola::keyseq_db::GetSequenceAsText(seq.seq(), seq.seq_len(), ks_str))
return wxString::Format(wxT("U+%s (%s)"), ZRCola::GetUnicodeDump(chr.data(), chr.length(), _T("+")).c_str(), ks_str.c_str());
}
return wxString::Format(wxT("U+%04X"), (int)m_chars[idx]);
return wxString::Format(wxT("U+%s"), ZRCola::GetUnicodeDump(chr.data(), chr.length(), _T("+")).c_str());
}
@@ -126,17 +136,19 @@ void wxZRColaCharGrid::OnSize(wxSizeEvent& event)
// Calculate initial estimate of columns and rows.
wxSize size(event.GetSize());
size_t
char_len = m_chars.Length();
char_count = m_chars.GetCount();
int
width = size.GetWidth() - m_rowLabelWidth - m_extraWidth,
cols = std::max<int>(width / wxZRColaCharacterGridColumnWidth, 1),
rows = std::max<int>((char_len + cols - 1) / cols, 1);
col_width = FromDIP(wxZRColaCharacterGridColumnWidth),
row_height = FromDIP(wxZRColaCharacterGridRowHeight),
width = size.GetWidth() - m_rowLabelWidth - m_extraWidth,
cols = std::max<int>(width / col_width, 1),
rows = std::max<int>((int)((char_count + cols - 1) / cols), 1);
if (m_colLabelHeight + rows*wxZRColaCharacterGridRowHeight + m_extraHeight > size.GetHeight()) {
if (m_colLabelHeight + rows*row_height + m_extraHeight > size.GetHeight()) {
// Vertical scrollbar will be shown. Adjust the width and recalculate layout to avoid horizontal scrollbar.
width = std::max<int>(width - wxSystemSettings::GetMetric(wxSYS_VSCROLL_X, this), 0);
cols = std::max<int>(width / wxZRColaCharacterGridColumnWidth, 1);
rows = std::max<int>((char_len + cols - 1) / cols, 1);
cols = std::max<int>(width / col_width, 1);
rows = std::max<int>((int)((char_count + cols - 1) / cols), 1);
}
BeginBatch();
@@ -146,14 +158,14 @@ void wxZRColaCharGrid::OnSize(wxSizeEvent& event)
wxGridStringTable *table = new wxGridStringTable(rows, cols);
for (int r = 0, i = 0; r < rows; r++)
for (int c = 0; c < cols; c++, i++)
table->SetValue(r, c, i < (int)char_len ? wxString(1, m_chars[i]) : wxEmptyString);
table->SetValue(r, c, i < (int)char_count ? m_chars[i] : wxEmptyString);
SetTable(table, true);
if (!m_relevance.IsEmpty()) {
const wxColour colour_def;
const wxColour colour_irr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT);
for (int r = 0, i = 0; r < rows; r++)
for (int c = 0; c < cols; c++, i++)
SetCellBackgroundColour(r, c, i >= (int)char_len || ((unsigned short)(m_relevance[i/16]) & (1<<(i%16))) ? colour_def : colour_irr);
SetCellBackgroundColour(r, c, i >= (int)char_count || ((unsigned short)(m_relevance[i/16]) & (1<<(i%16))) ? colour_def : colour_irr);
} else {
for (int r = 0, i = 0; r < rows; r++)
for (int c = 0; c < cols; c++, i++)
@@ -163,7 +175,7 @@ void wxZRColaCharGrid::OnSize(wxSizeEvent& event)
}
for (int c = 0; c < cols; c++)
SetColSize(c, wxZRColaCharacterGridColumnWidth);
SetColSize(c, col_width);
//// Set column widths to stretch to full width.
//for (int c = 0, x_l = 0; c < cols; c++) {
@@ -216,8 +228,8 @@ void wxZRColaCharGrid::OnMotion(wxMouseEvent& event)
if (col == wxNOT_FOUND || row == wxNOT_FOUND )
return;
size_t toolTipIdx = row*m_numCols + col;
if (toolTipIdx >= m_chars.Length()) {
size_t toolTipIdx = (size_t)row*m_numCols + col;
if (toolTipIdx >= m_chars.GetCount()) {
// Index out of range.
m_toolTipIdx = (size_t)-1;
m_timerToolTip.Stop();
@@ -228,7 +240,7 @@ void wxZRColaCharGrid::OnMotion(wxMouseEvent& event)
wxWindow *gridWnd = GetGridWindow();
if (gridWnd->GetToolTip()) {
// The tooltip is already shown. Update it immediately.
gridWnd->SetToolTip(GetToolTipText(m_toolTipIdx));
gridWnd->SetToolTip(GetToolTipText((int)m_toolTipIdx));
} else {
// This must be our initial entry. Schedule tooltip display after 1s.
m_timerToolTip.Start(1000, true);
@@ -241,8 +253,8 @@ void wxZRColaCharGrid::OnTooltipTimer(wxTimerEvent& event)
{
event.Skip();
if (m_toolTipIdx >= m_chars.Length())
if (m_toolTipIdx >= m_chars.GetCount())
return;
GetGridWindow()->SetToolTip(GetToolTipText(m_toolTipIdx));
GetGridWindow()->SetToolTip(GetToolTipText((int)m_toolTipIdx));
}

View File

@@ -1,20 +1,6 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
///
@@ -25,7 +11,11 @@ class wxZRColaCharGrid;
#pragma once
#include <wxex/common.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include <wx/grid.h>
#pragma warning(pop)
///
@@ -54,14 +44,21 @@ public:
///
/// Sets new array of characters to display
///
/// \param[in] chars The string containing characters to display
/// \param[in] chars The string containing characters to display (zero delimited)
///
void SetCharacters(const wxString &chars);
///
/// Sets new array of characters to display
///
/// \param[in] chars The string containing characters to display
/// \param[in] chars The array of characters to display
///
void SetCharacters(const wxArrayString &chars);
///
/// Sets new array of characters to display
///
/// \param[in] chars The string containing characters to display (zero delimited)
/// \param[in] relevance Bit-array of \p chars relevance (1=more relevant, 0=less relevant)
///
void SetCharacters(const wxString &chars, const wxArrayShort &relevance);
@@ -71,7 +68,7 @@ public:
///
/// \returns The string containing displayed characters
///
inline wxString GetCharacters() const
inline const wxArrayString& GetCharacters() const
{
return m_chars;
}
@@ -83,10 +80,14 @@ public:
///
/// \returns Grid coordinates of selected character or (-1, -1) if character not found.
///
inline wxGridCellCoords GetCharacterCoords(wchar_t c) const
inline wxGridCellCoords GetCharacterCoords(const wxString &c) const
{
int i = m_chars.Find(c);
return i != wxNOT_FOUND ? wxGridCellCoords(i / m_numCols, i % m_numCols) : wxGridCellCoords(-1, -1);
for (size_t i = 0, n = m_chars.GetCount(); ; i++) {
if (i >= n)
return wxGridCellCoords(-1, -1);
else if (m_chars[i] == c)
return wxGridCellCoords((int)(i / m_numCols), i % m_numCols);
}
}
protected:
@@ -102,7 +103,7 @@ private:
void Init(); // common part of all ctors
protected:
wxString m_chars; ///< Array of Unicode characters to display in the grid
wxArrayString m_chars; ///< Array of Unicode characters to display in the grid
wxArrayShort m_relevance; ///< Bit-array of `m_chars` relevance
private:

View File

@@ -1,23 +1,9 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#include "stdafx.h"
#include "pch.h"
//////////////////////////////////////////////////////////////////////////
@@ -71,14 +57,18 @@ void wxZRColaCharRequest::OnOKButtonClick(wxCommandEvent& event)
// wxPersistentZRColaCharRequest
//////////////////////////////////////////////////////////////////////////
wxPersistentZRColaCharRequest::wxPersistentZRColaCharRequest(wxZRColaCharRequest *wnd) : wxPersistentDialog(wnd)
const int wxPersistentZRColaCharRequest::s_guiLevel = 1;
wxPersistentZRColaCharRequest::wxPersistentZRColaCharRequest(wxZRColaCharRequest *wnd) : wxPersistentTLWEx(wnd)
{
}
void wxPersistentZRColaCharRequest::Save() const
{
wxPersistentDialog::Save();
SaveValue(wxT("guiLevel"), s_guiLevel);
wxPersistentTLWEx::Save();
auto wnd = static_cast<const wxZRColaCharRequest*>(GetWindow()); // dynamic_cast is not reliable as we are typically called late in the wxTopLevelWindowMSW destructor.
@@ -97,5 +87,6 @@ bool wxPersistentZRColaCharRequest::Restore()
if (RestoreValue(wxT("context"), &str))
wnd->m_context->SetValue(str);
return wxPersistentDialog::Restore();
int guiLevel;
return RestoreValue(wxT("guiLevel"), &guiLevel) && guiLevel == s_guiLevel ? wxPersistentTLWEx::Restore() : true;
}

View File

@@ -1,32 +1,24 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
///
/// Forward declarations
///
class wxZRColaCharRequest;
class wxPersistentZRColaCharRequest;
#pragma once
#include <wxex/common.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include "zrcolagui.h"
#pragma warning(pop)
#include "zrcolakeyhndlr.h"
#include <wxex/persist/toplevel.h>
///
@@ -49,13 +41,16 @@ protected:
///
/// Supports saving/restoring wxZRColaCharRequest state
///
class wxPersistentZRColaCharRequest : public wxPersistentDialog
class wxPersistentZRColaCharRequest : public wxPersistentTLWEx
{
public:
wxPersistentZRColaCharRequest(wxZRColaCharRequest *wnd);
virtual void Save() const;
virtual bool Restore();
protected:
static const int s_guiLevel; ///< Persisted placements/sizing are considered incompatible between different GUI levels
};

View File

@@ -1,23 +1,177 @@
/*
Copyright 2015-2017 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/>.
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#include "stdafx.h"
#include "pch.h"
//////////////////////////////////////////////////////////////////////
// wxZRColaUTF16CharValidator
//////////////////////////////////////////////////////////////////////
wxIMPLEMENT_DYNAMIC_CLASS(wxZRColaUTF16CharValidator, wxValidator);
wxZRColaUTF16CharValidator::wxZRColaUTF16CharValidator(wchar_t *val) :
m_val(val),
wxValidator()
{
}
wxObject* wxZRColaUTF16CharValidator::Clone() const
{
return new wxZRColaUTF16CharValidator(*this);
}
bool wxZRColaUTF16CharValidator::Validate(wxWindow *parent)
{
wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl)));
wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow();
if (!ctrl->IsEnabled()) return true;
wxString val(ctrl->GetValue());
return Parse(val, 0, val.Length(), ctrl, parent);
}
bool wxZRColaUTF16CharValidator::TransferToWindow()
{
wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl)));
if (m_val)
((wxTextCtrl*)GetWindow())->SetValue(wxString::Format(wxT("%04X"), *m_val));
return true;
}
bool wxZRColaUTF16CharValidator::TransferFromWindow()
{
wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl)));
wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow();
wxString val(ctrl->GetValue());
return Parse(val, 0, val.Length(), ctrl, NULL, m_val);
}
bool wxZRColaUTF16CharValidator::Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, wchar_t *val_out)
{
const wxStringCharType *buf = val_in;
wchar_t chr = 0;
for (size_t i = i_start;;) {
if (i >= i_end) {
// End of Unicode found.
if (val_out) *val_out = chr;
return true;
} else if (i >= i_start + 4) {
// Maximum characters exceeded.
ctrl->SetFocus();
ctrl->SetSelection((int)i, (int)i_end);
wxMessageBox(_("Too many digits in Unicode."), _("Validation conflict"), wxOK | wxICON_EXCLAMATION, parent);
return false;
} else if (_T('0') <= buf[i] && buf[i] <= _T('9')) {
// Digit found.
chr = (chr << 4) | (buf[i] - _T('0'));
i++;
} else if (_T('A') <= buf[i] && buf[i] <= _T('F')) {
// Capital letter found.
chr = (chr << 4) | (buf[i] - _T('A') + 10);
i++;
} else if (_T('a') <= buf[i] && buf[i] <= _T('f')) {
// Lower letter found.
chr = (chr << 4) | (buf[i] - _T('a') + 10);
i++;
} else {
// Invalid character found.
ctrl->SetFocus();
ctrl->SetSelection((long)i, (long)(i + 1));
wxMessageBox(wxString::Format(_("Invalid character in Unicode found: %c"), buf[i]), _("Validation conflict"), wxOK | wxICON_EXCLAMATION, parent);
return false;
}
}
}
//////////////////////////////////////////////////////////////////////
// wxZRColaUnicodeDumpValidator
//////////////////////////////////////////////////////////////////////
wxIMPLEMENT_DYNAMIC_CLASS(wxZRColaUnicodeDumpValidator, wxValidator);
wxZRColaUnicodeDumpValidator::wxZRColaUnicodeDumpValidator(wxString *val) :
m_val(val),
wxValidator()
{
}
wxObject* wxZRColaUnicodeDumpValidator::Clone() const
{
return new wxZRColaUnicodeDumpValidator(*this);
}
bool wxZRColaUnicodeDumpValidator::Validate(wxWindow *parent)
{
wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl)));
wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow();
if (!ctrl->IsEnabled()) return true;
wxString val(ctrl->GetValue());
return Parse(val, 0, val.Length(), ctrl, parent);
}
bool wxZRColaUnicodeDumpValidator::TransferToWindow()
{
wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl)));
if (m_val)
((wxTextCtrl*)GetWindow())->SetValue(ZRCola::GetUnicodeDumpW(m_val->c_str(), m_val->length(), L"+"));
return true;
}
bool wxZRColaUnicodeDumpValidator::TransferFromWindow()
{
wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxTextCtrl)));
wxTextCtrl *ctrl = (wxTextCtrl*)GetWindow();
wxString val(ctrl->GetValue());
return Parse(val, 0, val.Length(), ctrl, NULL, m_val);
}
bool wxZRColaUnicodeDumpValidator::Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, wxString *val_out)
{
const wxStringCharType *buf = val_in;
wxString str;
for (size_t i = i_start;;) {
const wxStringCharType *buf_next;
wchar_t chr;
if ((buf_next = wmemchr(buf + i, L'+', i_end - i)) != NULL) {
// Unicode dump separator found.
if (!wxZRColaUTF16CharValidator::Parse(val_in, i, buf_next - buf, ctrl, parent, &chr))
return false;
str += chr;
i = buf_next - buf + 1;
} else if (wxZRColaUTF16CharValidator::Parse(val_in, i, i_end, ctrl, parent, &chr)) {
// The rest of the FQDN parsed succesfully.
if (chr) str += chr;
if (val_out) *val_out = str;
return true;
} else
return false;
}
}
//////////////////////////////////////////////////////////////////////////
@@ -30,11 +184,11 @@ wxDEFINE_EVENT(wxEVT_SEARCH_COMPLETE, wxThreadEvent);
wxZRColaCharSelect::wxZRColaCharSelect(wxWindow* parent) :
m_searchChanged(false),
m_unicodeChanged(false),
m_char(0),
m_searchThread(NULL),
wxZRColaCharSelectBase(parent)
{
// Set tag lookup locale.
#pragma warning(suppress: 26812) // wxLanguage is unscoped
wxLanguage language = dynamic_cast<ZRColaApp*>(wxTheApp)->m_lang_ui;
if (wxLANGUAGE_DEFAULT == language ||
wxLANGUAGE_ENGLISH <= language && language <= wxLANGUAGE_ENGLISH_ZIMBABWE) m_locale = MAKELCID(MAKELANGID(LANG_ENGLISH , SUBLANG_DEFAULT), SORT_DEFAULT);
@@ -46,15 +200,15 @@ wxZRColaCharSelect::wxZRColaCharSelect(wxWindow* parent) :
m_search_more->SetLabel(_(L"▸ Search Options"));
m_unicode->SetValidator(wxHexValidator<wchar_t>(&m_char, wxNUM_VAL_DEFAULT, 4));
m_unicode->SetValidator(wxZRColaUnicodeDumpValidator(&m_char));
// Fill categories.
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
for (size_t i = 0, n = app->m_cc_db.idxRnk.size(); i < n; i++) {
const auto &cc = app->m_cc_db.idxRnk[i];
int idx = m_categories->Insert(wxGetTranslation(wxString(cc.name, cc.name_len), wxT("ZRCola-zrcdb")), i);
for (size_t i = 0, n = app->m_cc_db.idxRank.size(); i < n; i++) {
const auto &cc = app->m_cc_db.idxRank[i];
int idx = m_categories->Insert(wxGetTranslation(wxString(cc.name(), cc.name_len()), wxT("ZRCola-zrcdb")), (unsigned int)i);
m_categories->Check(idx);
m_ccOrder.insert(std::make_pair(cc.id, idx));
m_ccOrder.insert(std::make_pair(cc.cat, idx));
}
ResetResults();
@@ -69,8 +223,10 @@ wxZRColaCharSelect::wxZRColaCharSelect(wxWindow* parent) :
wxZRColaCharSelect::~wxZRColaCharSelect()
{
if (m_searchThread)
if (m_searchThread) {
#pragma warning(suppress: 26812) // wxThreadError is unscoped.
m_searchThread->Delete();
}
Disconnect(wxID_ANY, wxEVT_SEARCH_COMPLETE, wxThreadEventHandler(wxZRColaCharSelect::OnSearchComplete), NULL, this);
}
@@ -84,24 +240,24 @@ void wxZRColaCharSelect::OnIdle(wxIdleEvent& event)
if (m_unicode->GetValidator()->TransferFromWindow()) {
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
m_gridPreview->SetCellValue(0, 0, wxString(1, m_char));
m_gridPreview->SetCellValue(0, 0, m_char);
char chr[sizeof(ZRCola::character_db::character)] = {};
((ZRCola::character_db::character*)chr)->chr = m_char;
size_t start;
if (app->m_chr_db.idxChr.find(*(ZRCola::character_db::character*)chr, start)) {
const auto &chr = app->m_chr_db.idxChr[start];
std::unique_ptr<ZRCola::character_db::character> ch((ZRCola::character_db::character*)new char[sizeof(ZRCola::character_db::character) + sizeof(wchar_t)*m_char.length()]);
ch->ZRCola::character_db::character::character(m_char.data(), m_char.length());
ZRCola::character_db::indexChr::size_type ch_start;
if (app->m_chr_db.idxChr.find(*ch, ch_start)) {
const auto &chr = app->m_chr_db.idxChr[ch_start];
// Update character description.
m_description->SetValue(wxString(chr.data, chr.desc_len));
m_description->SetValue(wxString(chr.desc(), chr.desc_len()));
{
// See if this character has a key sequence registered.
char ks[sizeof(ZRCola::keyseq_db::keyseq)] = {};
((ZRCola::keyseq_db::keyseq*)ks)->chr = m_char;
ZRCola::keyseq_db::indexKey::size_type start;
if (app->m_ks_db.idxChr.find(*(ZRCola::keyseq_db::keyseq*)ks, start)) {
ZRCola::keyseq_db::keyseq &seq = app->m_ks_db.idxChr[start];
std::unique_ptr<ZRCola::keyseq_db::keyseq> ks((ZRCola::keyseq_db::keyseq*)new char[sizeof(ZRCola::keyseq_db::keyseq) + sizeof(wchar_t)*m_char.length()]);
ks->ZRCola::keyseq_db::keyseq::keyseq(NULL, 0, m_char.data(), m_char.length());
ZRCola::keyseq_db::indexKey::size_type ks_start;
if (app->m_ks_db.idxChr.find(*ks, ks_start)) {
const auto &seq = app->m_ks_db.idxChr[ks_start];
wxString ks_str;
if (ZRCola::keyseq_db::GetSequenceAsText(seq.seq, seq.seq_len, ks_str))
if (ZRCola::keyseq_db::GetSequenceAsText(seq.seq(), seq.seq_len(), ks_str))
m_shortcut->SetValue(ks_str);
else
m_shortcut->SetValue(wxEmptyString);
@@ -109,18 +265,16 @@ void wxZRColaCharSelect::OnIdle(wxIdleEvent& event)
m_shortcut->SetValue(wxEmptyString);
}
{
char cc[sizeof(ZRCola::chrcat_db::chrcat)] = {};
((ZRCola::chrcat_db::chrcat*)cc)->id = chr.cat;
size_t start;
// Update character category.
if (app->m_cc_db.idxChrCat.find(*((ZRCola::chrcat_db::chrcat*)cc), start)) {
const auto &cat = app->m_cc_db.idxChrCat[start];
m_category->SetValue(wxGetTranslation(wxString(cat.name, cat.name_len), wxT("ZRCola-zrcdb")));
ZRCola::chrcat_db::indexChrCat::size_type cc_start;
if (app->m_cc_db.idxChrCat.find(ZRCola::chrcat_db::chrcat(chr.cat), cc_start)) {
const auto &cat = app->m_cc_db.idxChrCat[cc_start];
m_category->SetValue(wxGetTranslation(wxString(cat.name(), cat.name_len()), wxT("ZRCola-zrcdb")));
} else
m_category->SetValue(wxEmptyString);
}
// Update related characters.
m_gridRelated->SetCharacters(wxString(chr.data + chr.desc_len, chr.rel_len));
m_gridRelated->SetCharacters(wxString(chr.rel(), chr.rel_end()));
} else {
m_description->SetValue(wxEmptyString);
m_shortcut->SetValue(wxEmptyString);
@@ -130,28 +284,24 @@ void wxZRColaCharSelect::OnIdle(wxIdleEvent& event)
// Find character tags.
std::list<std::wstring> tag_names;
ZRCola::chrtag_db::chrtag ct = { m_char };
size_t end;
if (app->m_ct_db.idxChr.find(ct, start, end)) {
for (size_t i = start; i < end; i++) {
const ZRCola::chrtag_db::chrtag &ct = app->m_ct_db.idxChr[i];
std::unique_ptr<ZRCola::chrtag_db::chrtag> ct((ZRCola::chrtag_db::chrtag*)new char[sizeof(ZRCola::chrtag_db::chrtag) + sizeof(wchar_t)*m_char.length()]);
ct->ZRCola::chrtag_db::chrtag::chrtag(m_char.data(), m_char.length());
ZRCola::chrtag_db::indexChr::size_type ct_start, ct_end;
if (app->m_ct_db.idxChr.find(*ct, ct_start, ct_end)) {
for (auto i = ct_start; i < ct_end; i++) {
// Find tag names.
char tn[sizeof(ZRCola::tagname_db::tagname)] = {};
((ZRCola::tagname_db::tagname*)tn)->locale = m_locale;
((ZRCola::tagname_db::tagname*)tn)->tag = ct.tag;
size_t start, end;
if (app->m_tn_db.idxTag.find(*((ZRCola::tagname_db::tagname*)tn), start, end)) {
for (size_t i = start; i < end; i++) {
const ZRCola::tagname_db::tagname &tn = app->m_tn_db.idxTag[i];
ZRCola::tagname_db::indexTag::size_type tn_start, tn_end;
if (app->m_tn_db.idxTag.find(ZRCola::tagname_db::tagname(app->m_ct_db.idxChr[i].tag, m_locale), tn_start, tn_end)) {
for (auto j = tn_start; j < tn_end; j++) {
const auto &tn = app->m_tn_db.idxTag[j];
// Add tag name to the list (prevent duplicates).
for (auto name = tag_names.cbegin(), name_end = tag_names.cend();; ++name) {
if (name == name_end) {
// Add name to the list.
tag_names.push_back(std::wstring(tn.name, tn.name + tn.name_len));
tag_names.push_back(std::wstring(tn.name(), tn.name_end()));
break;
} else if (ZRCola::tagname_db::tagname::CompareName(m_locale, name->data(), (unsigned __int16)name->length(), tn.name, tn.name_len) == 0)
} else if (ZRCola::tagname_db::tagname::CompareName(m_locale, name->data(), (unsigned __int16)name->length(), tn.name(), tn.name_len()) == 0)
// Name is already on the list.
break;
}
@@ -191,10 +341,10 @@ void wxZRColaCharSelect::OnIdle(wxIdleEvent& event)
m_searchThread->m_search.assign(val.c_str(), val.Length());
// Select categories.
for (size_t i = 0, n = app->m_cc_db.idxRnk.size(); i < n; i++) {
const auto &cc = app->m_cc_db.idxRnk[i];
if (m_categories->IsChecked(i))
m_searchThread->m_cats.insert(cc.id);
for (size_t i = 0, n = app->m_cc_db.idxRank.size(); i < n; i++) {
const auto &cc = app->m_cc_db.idxRank[i];
if (m_categories->IsChecked((unsigned int)i))
m_searchThread->m_cats.insert(cc.cat);
}
if (m_searchThread->Run() != wxTHREAD_NO_ERROR) {
@@ -239,8 +389,8 @@ void wxZRColaCharSelect::OnCategoriesAll(wxHyperlinkEvent& event)
event.StopPropagation();
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
for (size_t i = 0, n = app->m_cc_db.idxRnk.size(); i < n; i++)
m_categories->Check(i, true);
for (size_t i = 0, n = app->m_cc_db.idxRank.size(); i < n; i++)
m_categories->Check((unsigned int)i, true);
m_searchChanged = true;
}
@@ -251,8 +401,8 @@ void wxZRColaCharSelect::OnCategoriesNone(wxHyperlinkEvent& event)
event.StopPropagation();
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
for (size_t i = 0, n = app->m_cc_db.idxRnk.size(); i < n; i++)
m_categories->Check(i, false);
for (size_t i = 0, n = app->m_cc_db.idxRank.size(); i < n; i++)
m_categories->Check((unsigned int)i, false);
m_searchChanged = true;
}
@@ -263,8 +413,8 @@ void wxZRColaCharSelect::OnCategoriesInvert(wxHyperlinkEvent& event)
event.StopPropagation();
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
for (size_t i = 0, n = app->m_cc_db.idxRnk.size(); i < n; i++)
m_categories->Check(i, !m_categories->IsChecked(i));
for (size_t i = 0, n = app->m_cc_db.idxRank.size(); i < n; i++)
m_categories->Check((unsigned int)i, !m_categories->IsChecked((unsigned int)i));
m_searchChanged = true;
}
@@ -284,10 +434,10 @@ void wxZRColaCharSelect::OnSearchComplete(wxThreadEvent& event)
if (m_searchThread) {
// Display results.
wxString chars;
wxArrayString chars;
chars.reserve(m_searchThread->m_hits.size());
for (auto i = m_searchThread->m_hits.cbegin(), i_end = m_searchThread->m_hits.cend(); i != i_end; ++i)
chars += i->second;
chars.Add(i->second);
m_gridResults->SetCharacters(chars);
m_searchThread->Delete();
@@ -304,7 +454,7 @@ void wxZRColaCharSelect::OnResultSelectCell(wxGridEvent& event)
wxString val(m_gridResults->GetCellValue(event.GetRow(), event.GetCol()));
if (!val.IsEmpty())
NavigateTo(val[0]);
NavigateTo(val);
}
@@ -314,9 +464,9 @@ void wxZRColaCharSelect::OnResultCellDClick(wxGridEvent& event)
wxString val(m_gridResults->GetCellValue(event.GetRow(), event.GetCol()));
if (!val.IsEmpty()) {
NavigateTo(val[0]);
NavigateTo(val);
wxCommandEvent e(wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK);
m_sdbSizerButtonsOK->GetEventHandler()->ProcessEvent(e);
m_buttonInsert->GetEventHandler()->ProcessEvent(e);
}
}
@@ -328,9 +478,9 @@ void wxZRColaCharSelect::OnResultsKeyDown(wxKeyEvent& event)
case WXK_NUMPAD_ENTER:
wxString val(m_gridResults->GetCellValue(m_gridResults->GetGridCursorRow(), m_gridResults->GetGridCursorCol()));
if (!val.IsEmpty()) {
NavigateTo(val[0]);
NavigateTo(val);
wxCommandEvent e(wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK);
m_sdbSizerButtonsOK->GetEventHandler()->ProcessEvent(e);
m_buttonInsert->GetEventHandler()->ProcessEvent(e);
event.StopPropagation();
return;
@@ -347,7 +497,7 @@ void wxZRColaCharSelect::OnRecentSelectCell(wxGridEvent& event)
wxString val(m_gridRecent->GetCellValue(event.GetRow(), event.GetCol()));
if (!val.IsEmpty())
NavigateTo(val[0]);
NavigateTo(val);
}
@@ -357,9 +507,9 @@ void wxZRColaCharSelect::OnRecentCellDClick(wxGridEvent& event)
wxString val(m_gridRecent->GetCellValue(event.GetRow(), event.GetCol()));
if (!val.IsEmpty()) {
NavigateTo(val[0]);
NavigateTo(val);
wxCommandEvent e(wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK);
m_sdbSizerButtonsOK->GetEventHandler()->ProcessEvent(e);
m_buttonInsert->GetEventHandler()->ProcessEvent(e);
}
}
@@ -371,9 +521,9 @@ void wxZRColaCharSelect::OnRecentKeyDown(wxKeyEvent& event)
case WXK_NUMPAD_ENTER:
wxString val(m_gridRecent->GetCellValue(m_gridRecent->GetGridCursorRow(), m_gridRecent->GetGridCursorCol()));
if (!val.IsEmpty()) {
NavigateTo(val[0]);
NavigateTo(val);
wxCommandEvent e(wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK);
m_sdbSizerButtonsOK->GetEventHandler()->ProcessEvent(e);
m_buttonInsert->GetEventHandler()->ProcessEvent(e);
event.StopPropagation();
return;
@@ -431,24 +581,38 @@ void wxZRColaCharSelect::OnRelatedSelectCell(wxGridEvent& event)
wxString val(m_gridRelated->GetCellValue(event.GetRow(), event.GetCol()));
if (!val.IsEmpty())
NavigateTo(val[0]);
NavigateTo(val);
}
void wxZRColaCharSelect::OnOKButtonClick(wxCommandEvent& event)
void wxZRColaCharSelect::OnInsertUpdateUI(wxUpdateUIEvent& event)
{
event.Enable(!m_char.empty());
}
void wxZRColaCharSelect::OnInsert(wxCommandEvent& event)
{
event.Skip();
wxString
recent(m_gridRecent->GetCharacters()),
val(1, m_char);
for (size_t i = 0, n = recent.Length(); i < n; i++) {
const wxStringCharType c = recent[i];
const wxArrayString &recent = m_gridRecent->GetCharacters();
wxArrayString val;
val.reserve(recent.GetCount() + 1);
val.Add(m_char);
for (size_t i = 0, n = recent.GetCount(); i < n; i++) {
const wxString &c = recent[i];
if (c != m_char)
val += c;
val.Add(c);
}
m_gridRecent->SetCharacters(val);
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
if (app->m_mainWnd) {
app->m_mainWnd->m_panel->m_source->WriteText(m_char);
app->m_mainWnd->m_panel->m_source->SetFocus();
}
m_gridRecent->SetCharacters(val);
Show(false);
}
@@ -457,13 +621,13 @@ void wxZRColaCharSelect::ResetResults()
// Fill the results.
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
size_t i, n = app->m_chr_db.idxChr.size();
wxString val;
wxArrayString val;
val.reserve(n);
for (i = 0; i < n; i++) {
const auto &chr = app->m_chr_db.idxChr[i];
auto idx = m_ccOrder.find(chr.cat);
if (idx == m_ccOrder.end() || m_categories->IsChecked(idx->second))
val += chr.chr;
val.Add(wxString(chr.chr(), chr.chr_len()));
}
m_gridResults->SetCharacters(val);
}
@@ -507,7 +671,7 @@ void wxZRColaCharSelect::NavigateBy(int offset)
}
void wxZRColaCharSelect::NavigateTo(wchar_t c)
void wxZRColaCharSelect::NavigateTo(const wxString &c)
{
if (m_char != c) {
// Update history state
@@ -548,7 +712,7 @@ wxZRColaCharSelect::SearchThread::SearchThread(wxZRColaCharSelect *parent) :
wxThread::ExitCode wxZRColaCharSelect::SearchThread::Entry()
{
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
std::map<wchar_t, ZRCola::charrank_t> hits;
std::map<std::wstring, ZRCola::charrank_t> hits;
if (TestDestroy()) return (wxThread::ExitCode)1;
@@ -561,7 +725,7 @@ wxThread::ExitCode wxZRColaCharSelect::SearchThread::Entry()
{
// Search by description and merge results.
std::map<wchar_t, ZRCola::charrank_t> hits_sub;
std::map<std::wstring, ZRCola::charrank_t> hits_sub;
if (!app->m_chr_db.Search(m_search.c_str(), m_cats, hits, hits_sub, TestDestroyS, this)) return (wxThread::ExitCode)1;
for (auto i = hits_sub.cbegin(), i_end = hits_sub.cend(); i != i_end; ++i) {
if (TestDestroy()) return (wxThread::ExitCode)1;
@@ -589,7 +753,7 @@ wxThread::ExitCode wxZRColaCharSelect::SearchThread::Entry()
if (i->second > rank_threshold)
m_hits.push_back(std::make_pair(i->second, i->first));
}
std::qsort(m_hits.data(), m_hits.size(), sizeof(std::pair<ZRCola::charrank_t, wchar_t>), CompareHits);
std::qsort(m_hits.data(), m_hits.size(), sizeof(std::pair<ZRCola::charrank_t, std::wstring>), CompareHits);
// Signal the event handler that this thread is going to be destroyed.
// NOTE: here we assume that using the m_parent pointer is safe,
@@ -625,25 +789,42 @@ bool __cdecl wxZRColaCharSelect::SearchThread::TestDestroyS(void *cookie)
// wxPersistentZRColaCharSelect
//////////////////////////////////////////////////////////////////////////
wxPersistentZRColaCharSelect::wxPersistentZRColaCharSelect(wxZRColaCharSelect *wnd) : wxPersistentDialog(wnd)
const int wxPersistentZRColaCharSelect::s_guiLevel = 1;
wxPersistentZRColaCharSelect::wxPersistentZRColaCharSelect(wxZRColaCharSelect *wnd) : wxPersistentTLWEx(wnd)
{
}
void wxPersistentZRColaCharSelect::Save() const
{
wxPersistentDialog::Save();
SaveValue(wxT("guiLevel"), s_guiLevel);
wxPersistentTLWEx::Save();
auto wnd = static_cast<const wxZRColaCharSelect*>(GetWindow()); // dynamic_cast is not reliable as we are typically called late in the wxTopLevelWindowMSW destructor.
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
SaveValue(wxT("recentChars"), wnd->m_gridRecent->GetCharacters());
wxString str, str2;
auto &recent = wnd->m_gridRecent->GetCharacters();
for (size_t i = 0, n = recent.GetCount(); i < n; i++) {
if (i) str2 += wxT('|');
auto &chr = recent[i];
for (size_t j = 0, m = chr.Length(); j < m; j++) {
if (j) str2 += wxT('+');
str2 += wxString::Format(wxT("%04X"), chr[j]);
}
if (chr.Length() == 1)
str += chr[0];
}
SaveValue(wxT("recentChars" ), str ); // Save in legacy format for backward compatibility.
SaveValue(wxT("recentChars2"), str2); // Save in native format
for (size_t i = 0, n = app->m_cc_db.idxRnk.size(); i < n; i++) {
const auto &cc = app->m_cc_db.idxRnk[i];
for (size_t i = 0, n = app->m_cc_db.idxRank.size(); i < n; i++) {
const auto &cc = app->m_cc_db.idxRank[i];
wxString name(wxT("category"));
name.Append(cc.id.data, _countof(cc.id.data));
SaveValue(name, wnd->m_categories->IsChecked(i));
name.Append(cc.cat.data, _countof(cc.cat.data));
SaveValue(name, wnd->m_categories->IsChecked((unsigned int)i));
}
SaveValue(wxT("searchPanel"), wnd->m_search_panel->IsShown());
@@ -655,17 +836,32 @@ bool wxPersistentZRColaCharSelect::Restore()
auto wnd = dynamic_cast<wxZRColaCharSelect*>(GetWindow());
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
wxString recent;
if (RestoreValue(wxT("recentChars"), &recent))
wnd->m_gridRecent->SetCharacters(recent);
wxString str;
if (RestoreValue(wxT("recentChars2"), &str)) {
// Native format found.
wxArrayString val;
for (wxStringTokenizer tok(str, wxT("|")); tok.HasMoreTokens(); ) {
wxString chr;
for (wxStringTokenizer tok_chr(tok.GetNextToken(), wxT("+")); tok_chr.HasMoreTokens(); )
chr += (wchar_t)_tcstoul(tok_chr.GetNextToken().c_str(), NULL, 16);
val.Add(chr);
}
wnd->m_gridRecent->SetCharacters(val);
} else if (RestoreValue(wxT("recentChars"), &str)) {
// Legacy value found.
wxArrayString val;
for (size_t i = 0, n = str.Length(); i < n; i++)
val.Add(wxString(1, str[i]));
wnd->m_gridRecent->SetCharacters(val);
}
for (size_t i = 0, n = app->m_cc_db.idxRnk.size(); i < n; i++) {
const auto &cc = app->m_cc_db.idxRnk[i];
for (size_t i = 0, n = app->m_cc_db.idxRank.size(); i < n; i++) {
const auto &cc = app->m_cc_db.idxRank[i];
wxString name(wxT("category"));
name.Append(cc.id.data, _countof(cc.id.data));
name.Append(cc.cat.data, _countof(cc.cat.data));
bool val;
if (RestoreValue(name, &val))
wnd->m_categories->Check(i, val);
wnd->m_categories->Check((unsigned int)i, val);
}
bool search_panel;
@@ -681,5 +877,6 @@ bool wxPersistentZRColaCharSelect::Restore()
wnd->ResetResults();
return wxPersistentDialog::Restore();
int guiLevel;
return RestoreValue(wxT("guiLevel"), &guiLevel) && guiLevel == s_guiLevel ? wxPersistentTLWEx::Restore() : true;
}

View File

@@ -1,20 +1,6 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
///
@@ -26,17 +12,115 @@ class wxPersistentZRColaCharSelect;
#pragma once
#include <wxex/common.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include "zrcolagui.h"
#pragma warning(pop)
#include <zrcola/character.h>
#include <wxex/valhex.h>
#include <wxex/persist/dialog.h>
#include <wxex/persist/toplevel.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include <wx/validate.h>
#include <wx/event.h>
#include <wx/thread.h>
#pragma warning(pop)
#include <list>
#include <map>
#include <string>
#include <vector>
///
/// Validator for Unicode character
///
class wxZRColaUTF16CharValidator : public wxValidator
{
public:
///
/// Construct the validator with a value to store data
///
wxZRColaUTF16CharValidator(wchar_t *val = NULL);
///
/// Copies this validator
///
virtual wxObject* Clone() const;
///
/// Validates the value
///
virtual bool Validate(wxWindow *parent);
///
/// Transfers the value to the window
///
virtual bool TransferToWindow();
///
/// Transfers the value from the window
///
virtual bool TransferFromWindow();
///
/// Parses FQDN value
///
static bool Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, wchar_t *val_out = NULL);
protected:
wchar_t *m_val; ///< Pointer to variable to receive control's parsed value
private:
wxDECLARE_DYNAMIC_CLASS(wxZRColaUTF16CharValidator);
wxDECLARE_NO_ASSIGN_CLASS(wxZRColaUTF16CharValidator);
};
///
/// Validator for Unicode dump
///
class wxZRColaUnicodeDumpValidator : public wxValidator
{
public:
///
/// Construct the validator with a value to store data
///
wxZRColaUnicodeDumpValidator(wxString *val = NULL);
///
/// Copies this validator
///
virtual wxObject* Clone() const;
///
/// Validates the value
///
virtual bool Validate(wxWindow *parent);
///
/// Transfers the value to the window
///
virtual bool TransferToWindow();
///
/// Transfers the value from the window
///
virtual bool TransferFromWindow();
///
/// Parses Unicode dump value
///
static bool Parse(const wxString &val_in, size_t i_start, size_t i_end, wxTextCtrl *ctrl, wxWindow *parent, wxString *val_out = NULL);
protected:
wxString *m_val; ///< Pointer to variable to receive control's parsed value
private:
wxDECLARE_DYNAMIC_CLASS(wxZRColaUnicodeDumpValidator);
wxDECLARE_NO_ASSIGN_CLASS(wxZRColaUnicodeDumpValidator);
};
wxDECLARE_EVENT(wxEVT_SEARCH_COMPLETE, wxThreadEvent);
@@ -72,14 +156,15 @@ protected:
virtual void OnUnicodeText(wxCommandEvent& event);
virtual void OnPreviewKeyDown(wxKeyEvent& event);
virtual void OnRelatedSelectCell(wxGridEvent& event);
virtual void OnOKButtonClick(wxCommandEvent& event);
virtual void OnInsertUpdateUI(wxUpdateUIEvent& event);
virtual void OnInsert(wxCommandEvent& event);
void ResetResults();
void NavigateBy(int offset);
void NavigateTo(wchar_t c);
void NavigateTo(const wxString &c);
public:
wchar_t m_char; ///< Currently selected character (0 when none)
wxString m_char; ///< Currently selected character (empty when none)
protected:
LCID m_locale; ///< Locale for tag lookup
@@ -104,7 +189,7 @@ protected:
public:
std::wstring m_search; ///< Search phrase
std::set<ZRCola::chrcatid_t> m_cats; ///< Search categories
std::vector<std::pair<ZRCola::charrank_t, wchar_t> > m_hits; ///< Search results
std::vector<std::pair<ZRCola::charrank_t, std::wstring> > m_hits; ///< Search results
protected:
wxZRColaCharSelect *m_parent; ///< Thread owner
@@ -116,7 +201,7 @@ protected:
///
struct NavigationState
{
wchar_t m_char;
std::wstring m_char;
struct {
wxGridCellCoords m_selected;
} m_related;
@@ -130,13 +215,16 @@ protected:
///
/// Supports saving/restoring wxZRColaCharSelect state
///
class wxPersistentZRColaCharSelect : public wxPersistentDialog
class wxPersistentZRColaCharSelect : public wxPersistentTLWEx
{
public:
wxPersistentZRColaCharSelect(wxZRColaCharSelect *wnd);
virtual void Save() const;
virtual bool Restore();
protected:
static const int s_guiLevel; ///< Persisted placements/sizing are considered incompatible between different GUI levels
};

View File

@@ -1,23 +1,14 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#include "stdafx.h"
#include "pch.h"
static inline bool is_pua(_In_ wchar_t c)
{
return L'\ue000' <= c && c <= L'\uf8ff';
}
//////////////////////////////////////////////////////////////////////////
@@ -25,42 +16,66 @@
//////////////////////////////////////////////////////////////////////////
wxZRColaComposerPanel::wxZRColaComposerPanel(wxWindow* parent) :
m_decomposedChanged(false),
m_composedChanged(false),
m_selDecomposed(0, 0),
m_selComposed(0, 0),
m_sourceChanged(false),
m_destinationChanged(false),
m_sourceRestyled(false),
m_destinationRestyled(false),
m_styleSource(*wxBLACK, *wxWHITE, wxFont(20, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("ZRCola"))),
m_styleDestination(*wxBLACK, *wxWHITE, wxFont(20, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("ZRCola"))),
m_styleDestinationPUA(*wxBLUE, *wxWHITE, wxFont(20, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("ZRCola"))),
m_selSource(0, 0),
m_selDestination(0, 0),
wxZRColaComposerPanelBase(parent)
{
m_decomposed->PushEventHandler(&m_keyhandler);
// RichEdit control has no inner margins by default.
m_source->SetMargins(FromDIP(wxPoint(5, 2)));
m_destination->SetMargins(FromDIP(wxPoint(5, 2)));
m_source->PushEventHandler(&m_keyhandler);
}
wxZRColaComposerPanel::~wxZRColaComposerPanel()
{
m_source->PopEventHandler();
// This is a controlled exit. Purge saved state.
wxString fileName(GetStateFileName());
if (wxFileExists(fileName))
wxRemoveFile(fileName);
}
void wxZRColaComposerPanel::RestoreFromStateFile()
{
// Restore the previously saved state (if exists).
wxString fileName(GetStateFileName());
if (wxFileExists(fileName)) {
wxFFile file(fileName, wxT("rb"));
if (file.IsOpened()) {
// Load decomposed text.
// Load source text.
unsigned __int64 n;
file.Read(&n, sizeof(n));
if (!file.Error()) {
wxString decomposed;
file.Read(wxStringBuffer(decomposed, n), sizeof(wchar_t)*n);
wxString source;
file.Read(wxStringBuffer(source, (size_t)n), sizeof(wchar_t)*(size_t)n);
if (!file.Error()) {
// Load composed text.
// Load destination text.
file.Read(&n, sizeof(n));
if (!file.Error()) {
wxString composed;
file.Read(wxStringBuffer(composed, n), sizeof(wchar_t)*n);
wxString destination;
file.Read(wxStringBuffer(destination, (size_t)n), sizeof(wchar_t)*(size_t)n);
if (!file.Error()) {
// Restore state.
m_decomposed->SetValue(decomposed);
m_decomposed->GetSelection(&m_selDecomposed.first, &m_selDecomposed.second);
SetHexValue(m_decomposedHex, m_selDecomposedHex, m_mappingDecomposedHex, decomposed.GetData(), decomposed.Length(), m_selDecomposed.first, m_selDecomposed.second);
m_decomposedChanged = false;
m_source->SetValue(source);
m_source->GetSelection(&m_selSource.first, &m_selSource.second);
SetHexValue(m_sourceHex, m_selSourceHex, m_mappingSourceHex, source.GetData(), source.Length(), m_selSource.first, m_selSource.second);
m_sourceChanged = false;
m_composed->SetValue(composed);
m_composed->GetSelection(&m_selComposed.first, &m_selComposed.second);
SetHexValue(m_composedHex, m_selComposedHex, m_mappingComposedHex, composed.GetData(), composed.Length(), m_selComposed.first, m_selComposed.second);
m_composedChanged = false;
m_destination->SetValue(destination);
m_destination->GetSelection(&m_selDestination.first, &m_selDestination.second);
SetHexValue(m_destinationHex, m_selDestinationHex, m_mappingDestinationHex, destination.GetData(), destination.Length(), m_selDestination.first, m_selDestination.second);
m_destinationChanged = false;
}
}
}
@@ -70,208 +85,277 @@ wxZRColaComposerPanel::wxZRColaComposerPanel(wxWindow* parent) :
}
wxZRColaComposerPanel::~wxZRColaComposerPanel()
{
m_decomposed->PopEventHandler();
// This is a controlled exit. Purge saved state.
wxString fileName(GetStateFileName());
if (wxFileExists(fileName))
wxRemoveFile(fileName);
}
void wxZRColaComposerPanel::SynchronizePanels()
{
if (m_decomposedChanged) {
if (m_sourceChanged) {
m_timerSave.Stop();
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
wxString src;
size_t len = GetValue(m_decomposed, src);
std::wstring norm;
app->m_t_db.Decompose(src.data(), len, norm, &m_mapping1);
wxString src = m_source->GetValue();
size_t len = src.Length();
std::wstring dst(src.data(), len), dst2;
ZRCola::mapping_vector map;
std::wstring dst;
app->m_t_db.Compose(norm.data(), norm.size(), dst, &m_mapping2);
m_mapping.clear();
m_decomposed->GetSelection(&m_selDecomposed.first, &m_selDecomposed.second);
if (app->m_mainWnd->m_composition) {
// ZRCola decompose first, then re-compose.
app->m_t_db.TranslateInv(ZRCOLA_TRANSEQID_DEFAULT, dst.data(), dst.size(), dst2, &map);
m_mapping.push_back(std::move(map));
// Update decomposed HEX dump.
SetHexValue(m_decomposedHex, m_selDecomposedHex, m_mappingDecomposedHex, src.data(), len, m_selDecomposed.first, m_selDecomposed.second);
app->m_t_db.Translate(ZRCOLA_TRANSEQID_DEFAULT, dst2.data(), dst2.size(), dst, &map);
m_mapping.push_back(std::move(map));
}
// Update composed text, and its HEX dump.
m_composed->SetValue(dst);
m_composed->SetSelection(
m_selComposed.first = m_mapping2.to_dst(m_mapping1.to_dst(m_selDecomposed.first )),
m_selComposed.second = m_mapping2.to_dst(m_mapping1.to_dst(m_selDecomposed.second)));
SetHexValue(m_composedHex, m_selComposedHex, m_mappingComposedHex, dst.data(), dst.length(), m_selComposed.first, m_selComposed.second);
// Other translations
const ZRCola::transetid_t *sets_begin, *sets_end;
GetTranslationSeq(sets_begin, sets_end);
for (auto s = sets_begin; s != sets_end; ++s) {
app->m_t_db.Translate(*s, dst.data(), dst.size(), dst2, &map);
m_mapping.push_back(std::move(map));
dst = std::move(dst2);
}
m_source->GetSelection(&m_selSource.first, &m_selSource.second);
// Update source HEX dump.
SetHexValue(m_sourceHex, m_selSourceHex, m_mappingSourceHex, src.data(), len, m_selSource.first, m_selSource.second);
// Update destination text, and its HEX dump.
m_destination->SetValue(dst);
m_destination->SetSelection(
m_selDestination.first = (long)MapToDestination(m_selSource.first ),
m_selDestination.second = (long)MapToDestination(m_selSource.second));
SetHexValue(m_destinationHex, m_selDestinationHex, m_mappingDestinationHex, dst.data(), dst.length(), m_selDestination.first, m_selDestination.second);
// Schedule state save after 3s.
m_timerSave.Start(3000, true);
} else if (m_composedChanged) {
} else if (m_destinationChanged) {
m_timerSave.Stop();
wxString src;
size_t len = GetValue(m_composed, src);
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
std::wstring dst;
wxZRColaFrame *mainWnd = dynamic_cast<wxZRColaFrame*>(wxGetActiveWindow());
if (mainWnd)
app->m_t_db.Decompose(src.data(), len, &app->m_lc_db, mainWnd->m_settings->m_lang, dst, &m_mapping2);
else
app->m_t_db.Decompose(src.data(), len, dst, &m_mapping2);
m_mapping1.clear();
m_mapping2.invert();
wxString src = m_destination->GetValue();
size_t len = src.Length();
std::wstring dst(src.data(), len), dst2;
ZRCola::mapping_vector map;
m_composed->GetSelection(&m_selComposed.first, &m_selComposed.second);
m_mapping.clear();
// Update composed HEX dump.
SetHexValue(m_composedHex, m_selComposedHex, m_mappingComposedHex, src.data(), len, m_selComposed.first, m_selComposed.second);
// Other translations
const ZRCola::transetid_t *sets_begin, *sets_end;
GetTranslationSeq(sets_begin, sets_end);
for (auto s = sets_end; (s--) != sets_begin;) {
app->m_t_db.TranslateInv(*s, dst.data(), dst.size(), dst2, &map);
dst = std::move(dst2);
// Update decomposed text, and its HEX dump.
m_decomposed->SetValue(dst);
m_decomposed->SetSelection(
m_selDecomposed.first = m_mapping1.to_src(m_mapping2.to_src(m_selComposed.first )),
m_selDecomposed.second = m_mapping1.to_src(m_mapping2.to_src(m_selComposed.second)));
SetHexValue(m_decomposedHex, m_selDecomposedHex, m_mappingDecomposedHex, dst.data(), dst.length(), m_selDecomposed.first, m_selDecomposed.second);
map.invert();
m_mapping.push_back(std::move(map));
}
if (app->m_mainWnd->m_composition) {
// ZRCola decompose.
app->m_t_db.TranslateInv(ZRCOLA_TRANSEQID_DEFAULT, dst.data(), dst.size(), &app->m_lc_db, app->m_mainWnd->m_settings->m_lang, dst2, &map);
dst = std::move(dst2);
map.invert();
m_mapping.push_back(std::move(map));
}
m_destination->GetSelection(&m_selDestination.first, &m_selDestination.second);
// Update destination HEX dump.
SetHexValue(m_destinationHex, m_selDestinationHex, m_mappingDestinationHex, src.data(), len, m_selDestination.first, m_selDestination.second);
// Update source text, and its HEX dump.
m_source->SetValue(dst);
m_source->SetSelection(
m_selSource.first = (long)MapToSource(m_selDestination.first ),
m_selSource.second = (long)MapToSource(m_selDestination.second));
SetHexValue(m_sourceHex, m_selSourceHex, m_mappingSourceHex, dst.data(), dst.length(), m_selSource.first, m_selSource.second);
// Schedule state save after 3s.
m_timerSave.Start(3000, true);
}
m_decomposedChanged = false;
m_composedChanged = false;
m_sourceChanged = false;
m_destinationChanged = false;
}
void wxZRColaComposerPanel::SetDestinationFont(const wxFont& font, int flags)
{
m_styleDestination.SetFont(font, flags);
m_styleDestinationPUA.SetFont(font, flags);
}
void wxZRColaComposerPanel::OnDecomposedPaint(wxPaintEvent& event)
void wxZRColaComposerPanel::RestyleSource()
{
m_sourceRestyled = true;
m_source->SetStyle(0, GetWindowTextLength(m_source->GetHWND()), m_styleSource);
m_sourceRestyled = false;
}
void wxZRColaComposerPanel::RestyleDestination()
{
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
m_destinationRestyled = true;
if (app->m_mainWnd->m_warnPUA) {
wxString src = m_destination->GetValue();
size_t len = src.Length();
for (size_t i = 0, j; i < len;) {
bool pua_i = is_pua(src[i]);
for (j = i + 1; j < len && pua_i == is_pua(src[j]); j++);
m_destination->SetStyle((long)i, (long)j, pua_i ? m_styleDestinationPUA : m_styleDestination);
i = j;
}
} else
m_destination->SetStyle(0, GetWindowTextLength(m_destination->GetHWND()), m_styleDestination);
m_destinationRestyled = false;
}
void wxZRColaComposerPanel::OnSourcePaint(wxPaintEvent& event)
{
event.Skip();
if (m_sourceRestyled)
return;
long from, to;
m_decomposed->GetSelection(&from, &to);
m_source->GetSelection(&from, &to);
if (m_selDecomposed.first != from || m_selDecomposed.second != to) {
if (m_selSource.first != from || m_selSource.second != to) {
// Save new selection first, to avoid loop.
m_selDecomposed.first = from;
m_selDecomposed.second = to;
m_selSource.first = from;
m_selSource.second = to;
m_decomposedHex->SetSelection(
m_selDecomposedHex.first = m_mappingDecomposedHex.to_dst(from),
m_selDecomposedHex.second = m_mappingDecomposedHex.to_dst(to ));
m_sourceHex->SetSelection(
m_selSourceHex.first = (long)m_mappingSourceHex.to_dst(from),
m_selSourceHex.second = (long)m_mappingSourceHex.to_dst(to ));
m_composed->SetSelection(
m_selComposed.first = m_mapping2.to_dst(m_mapping1.to_dst(from)),
m_selComposed.second = m_mapping2.to_dst(m_mapping1.to_dst(to )));
m_destination->SetSelection(
m_selDestination.first = (long)MapToDestination(from),
m_selDestination.second = (long)MapToDestination(to ));
m_composedHex->SetSelection(
m_selComposedHex.first = m_mappingComposedHex.to_dst(m_selComposed.first ),
m_selComposedHex.second = m_mappingComposedHex.to_dst(m_selComposed.second));
m_destinationHex->SetSelection(
m_selDestinationHex.first = (long)m_mappingDestinationHex.to_dst(m_selDestination.first ),
m_selDestinationHex.second = (long)m_mappingDestinationHex.to_dst(m_selDestination.second));
}
}
void wxZRColaComposerPanel::OnDecomposedHexPaint(wxPaintEvent& event)
void wxZRColaComposerPanel::OnSourceHexPaint(wxPaintEvent& event)
{
event.Skip();
long from, to;
m_decomposedHex->GetSelection(&from, &to);
m_sourceHex->GetSelection(&from, &to);
if (m_selDecomposedHex.first != from || m_selDecomposedHex.second != to) {
if (m_selSourceHex.first != from || m_selSourceHex.second != to) {
// Save new selection first, to avoid loop.
m_selDecomposedHex.first = from;
m_selDecomposedHex.second = to;
m_selSourceHex.first = from;
m_selSourceHex.second = to;
m_decomposed->SetSelection(
m_selDecomposed.first = m_mappingDecomposedHex.to_src(from),
m_selDecomposed.second = m_mappingDecomposedHex.to_src(to ));
m_source->SetSelection(
m_selSource.first = (long)m_mappingSourceHex.to_src(from),
m_selSource.second = (long)m_mappingSourceHex.to_src(to ));
m_composed->SetSelection(
m_selComposed.first = m_mapping2.to_dst(m_mapping1.to_dst(m_selDecomposed.first )),
m_selComposed.second = m_mapping2.to_dst(m_mapping1.to_dst(m_selDecomposed.second)));
m_destination->SetSelection(
m_selDestination.first = (long)MapToDestination(m_selSource.first ),
m_selDestination.second = (long)MapToDestination(m_selSource.second));
m_composedHex->SetSelection(
m_selComposedHex.first = m_mappingComposedHex.to_dst(m_selComposed.first ),
m_selComposedHex.second = m_mappingComposedHex.to_dst(m_selComposed.second));
m_destinationHex->SetSelection(
m_selDestinationHex.first = (long)m_mappingDestinationHex.to_dst(m_selDestination.first ),
m_selDestinationHex.second = (long)m_mappingDestinationHex.to_dst(m_selDestination.second));
}
}
void wxZRColaComposerPanel::OnDecomposedText(wxCommandEvent& event)
void wxZRColaComposerPanel::OnSourceText(wxCommandEvent& event)
{
event.Skip();
// Set the flag the decomposed text changed to trigger idle-time composition.
m_decomposedChanged = true;
if (m_sourceRestyled)
return;
// Set the flag the source text changed to trigger idle-time translation.
m_sourceChanged = true;
RestyleSource();
}
void wxZRColaComposerPanel::OnComposedPaint(wxPaintEvent& event)
void wxZRColaComposerPanel::OnDestinationPaint(wxPaintEvent& event)
{
event.Skip();
if (m_destinationRestyled)
return;
long from, to;
m_destination->GetSelection(&from, &to);
if (m_selDestination.first != from || m_selDestination.second != to) {
// Save new selection first, to avoid loop.
m_selDestination.first = from;
m_selDestination.second = to;
m_destinationHex->SetSelection(
m_selDestinationHex.first = (long)m_mappingDestinationHex.to_dst(from),
m_selDestinationHex.second = (long)m_mappingDestinationHex.to_dst(to ));
m_source->SetSelection(
m_selSource.first = (long)MapToSource(from),
m_selSource.second = (long)MapToSource(to ));
m_sourceHex->SetSelection(
m_selSourceHex.first = (long)m_mappingSourceHex.to_dst(m_selSource.first ),
m_selSourceHex.second = (long)m_mappingSourceHex.to_dst(m_selSource.second));
}
}
void wxZRColaComposerPanel::OnDestinationHexPaint(wxPaintEvent& event)
{
event.Skip();
long from, to;
m_composed->GetSelection(&from, &to);
m_destinationHex->GetSelection(&from, &to);
if (m_selComposed.first != from || m_selComposed.second != to) {
if (m_selDestinationHex.first != from || m_selDestinationHex.second != to) {
// Save new selection first, to avoid loop.
m_selComposed.first = from;
m_selComposed.second = to;
m_selDestinationHex.first = from;
m_selDestinationHex.second = to;
m_composedHex->SetSelection(
m_selComposedHex.first = m_mappingComposedHex.to_dst(from),
m_selComposedHex.second = m_mappingComposedHex.to_dst(to ));
m_destination->SetSelection(
m_selDestination.first = (long)m_mappingDestinationHex.to_src(from),
m_selDestination.second = (long)m_mappingDestinationHex.to_src(to ));
m_decomposed->SetSelection(
m_selDecomposed.first = m_mapping1.to_src(m_mapping2.to_src(from)),
m_selDecomposed.second = m_mapping1.to_src(m_mapping2.to_src(to )));
m_source->SetSelection(
m_selSource.first = (long)MapToSource(m_selDestination.first ),
m_selSource.second = (long)MapToSource(m_selDestination.second));
m_decomposedHex->SetSelection(
m_selDecomposedHex.first = m_mappingDecomposedHex.to_dst(m_selDecomposed.first ),
m_selDecomposedHex.second = m_mappingDecomposedHex.to_dst(m_selDecomposed.second));
m_sourceHex->SetSelection(
m_selSourceHex.first = (long)m_mappingSourceHex.to_dst(m_selSource.first ),
m_selSourceHex.second = (long)m_mappingSourceHex.to_dst(m_selSource.second));
}
}
void wxZRColaComposerPanel::OnComposedHexPaint(wxPaintEvent& event)
void wxZRColaComposerPanel::OnDestinationText(wxCommandEvent& event)
{
event.Skip();
long from, to;
m_composedHex->GetSelection(&from, &to);
if (m_destinationRestyled)
return;
if (m_selComposedHex.first != from || m_selComposedHex.second != to) {
// Save new selection first, to avoid loop.
m_selComposedHex.first = from;
m_selComposedHex.second = to;
m_composed->SetSelection(
m_selComposed.first = m_mappingComposedHex.to_src(from),
m_selComposed.second = m_mappingComposedHex.to_src(to ));
m_decomposed->SetSelection(
m_selDecomposed.first = m_mapping1.to_src(m_mapping2.to_src(m_selComposed.first )),
m_selDecomposed.second = m_mapping1.to_src(m_mapping2.to_src(m_selComposed.second)));
m_decomposedHex->SetSelection(
m_selDecomposedHex.first = m_mappingDecomposedHex.to_dst(m_selDecomposed.first ),
m_selDecomposedHex.second = m_mappingDecomposedHex.to_dst(m_selDecomposed.second));
}
}
void wxZRColaComposerPanel::OnComposedText(wxCommandEvent& event)
{
event.Skip();
// Set the flag the composed text changed to trigger idle-time decomposition.
m_composedChanged = true;
// Set the flag the destination text changed to trigger idle-time inverse translation.
m_destinationChanged = true;
RestyleDestination();
}
@@ -280,18 +364,21 @@ void wxZRColaComposerPanel::OnSaveTimer(wxTimerEvent& event)
wxString fileName(GetStateFileName());
wxFFile file(fileName, wxT("wb"));
if (file.IsOpened()) {
wxString text;
size_t len;
{
// Save source text.
wxString text = m_source->GetValue();
size_t len = text.Length();
file.Write(&len, sizeof(len));
file.Write((const wchar_t*)text, sizeof(wchar_t)*len);
}
// Save decomposed text.
len = GetValue(m_decomposed, text);
file.Write(&len, sizeof(len));
file.Write((const wchar_t*)text, sizeof(wchar_t)*len);
// Save composed text.
len = GetValue(m_composed, text);
file.Write(&len, sizeof(len));
file.Write((const wchar_t*)text, sizeof(wchar_t)*len);
{
// Save destination text.
wxString text = m_destination->GetValue();
size_t len = text.Length();
file.Write(&len, sizeof(len));
file.Write((const wchar_t*)text, sizeof(wchar_t)*len);
}
}
event.Skip();
@@ -316,31 +403,6 @@ wxString wxZRColaComposerPanel::GetStateFileName()
}
size_t wxZRColaComposerPanel::GetValue(wxTextCtrl *wnd, wxString &text)
{
#ifdef __WINDOWS__
// Use Windows GetWindowText() function to avoid line ending conversion incompletely imposed by wxWidgets.
WXHWND hWnd = wnd->GetHWND();
size_t len = ::GetWindowTextLengthW(hWnd);
if (len < 0x100) {
WCHAR buf[0x100];
::GetWindowTextW(hWnd, buf, len + 1);
text.assign(buf, len);
} else {
LPWSTR buf = new WCHAR[len + 1];
::GetWindowTextW(hWnd, buf, len + 1);
text.assign(buf, len);
delete [] buf;
}
return len;
#else
text = wnd->GetValue();
return text.Length();
#endif
}
void wxZRColaComposerPanel::SetHexValue(wxTextCtrl *wnd, std::pair<long, long> &range, ZRCola::mapping_vector &mapping, const wchar_t *src, size_t len, long from, long to)
{
wxString hex;
@@ -349,8 +411,8 @@ void wxZRColaComposerPanel::SetHexValue(wxTextCtrl *wnd, std::pair<long, long> &
mapping.clear();
for (size_t i = 0; i < len && src[i]; i++) {
wchar_t c = src[i];
if (c == L'\n' || c == '\r') {
hex += c;
if (c == L'\n') {
hex += L"\r\n";
first = true;
} else {
hex += wxString::Format(first ? wxT("%04X") : wxT(" %04X"), src[i]);
@@ -361,8 +423,8 @@ void wxZRColaComposerPanel::SetHexValue(wxTextCtrl *wnd, std::pair<long, long> &
wnd->SetValue(hex);
wnd->SetSelection(
range.first = mapping.to_dst(from),
range.second = mapping.to_dst(to ));
range.first = (long)mapping.to_dst(from),
range.second = (long)mapping.to_dst(to ));
}
@@ -370,6 +432,9 @@ void wxZRColaComposerPanel::SetHexValue(wxTextCtrl *wnd, std::pair<long, long> &
// wxPersistentZRColaComposerPanel
//////////////////////////////////////////////////////////////////////////
const int wxPersistentZRColaComposerPanel::s_guiLevel = 1;
wxPersistentZRColaComposerPanel::wxPersistentZRColaComposerPanel(wxZRColaComposerPanel *wnd) : wxPersistentWindow<wxZRColaComposerPanel>(wnd)
{
}
@@ -383,10 +448,12 @@ wxString wxPersistentZRColaComposerPanel::GetKind() const
void wxPersistentZRColaComposerPanel::Save() const
{
auto const wnd = static_cast<const wxZRColaComposerPanel*>(GetWindow()); // dynamic_cast is not reliable as we are typically called late in the wxTopLevelWindowMSW destructor.
auto wnd = static_cast<wxZRColaComposerPanel*>(GetWindow()); // dynamic_cast is not reliable as we are typically called late in the wxTopLevelWindowMSW destructor.
SaveValue(wxT("splitDecomposed"), wnd->m_splitterDecomposed->GetSashPosition());
SaveValue(wxT("splitComposed" ), wnd->m_splitterComposed ->GetSashPosition());
SaveValue(wxT("guiLevel" ), s_guiLevel);
SaveValue(wxT("dpiX" ), wxClientDC(wnd).GetPPI().x);
SaveValue(wxT("splitDecomposed"), wnd->m_splitterSource ->GetSashPosition());
SaveValue(wxT("splitComposed" ), wnd->m_splitterDestination->GetSashPosition());
}
@@ -394,18 +461,27 @@ bool wxPersistentZRColaComposerPanel::Restore()
{
auto wnd = dynamic_cast<wxZRColaComposerPanel*>(GetWindow());
int guiLevel;
if (!RestoreValue(wxT("guiLevel"), &guiLevel) || guiLevel != s_guiLevel)
return true;
int dpiHorz = wxClientDC(wnd).GetPPI().x;
int dpiHorzVal;
int sashVal;
if (!RestoreValue(wxT("dpiX"), &dpiHorzVal))
dpiHorzVal = 96;
if (RestoreValue(wxT("splitDecomposed"), &sashVal)) {
// wxFormBuilder sets initial splitter stash in idle event handler after GUI settles. Overriding our loaded value. Disconnect it's idle event handler.
wnd->m_splitterDecomposed->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaComposerPanelBase::m_splitterDecomposedOnIdle ), NULL, wnd );
wnd->m_splitterDecomposed->SetSashPosition(sashVal);
wnd->m_splitterSource->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaComposerPanelBase::m_splitterSourceOnIdle ), NULL, wnd );
wnd->m_splitterSource->SetSashPosition(wxMulDivInt32(sashVal, dpiHorz, dpiHorzVal));
}
if (RestoreValue(wxT("splitComposed"), &sashVal)) {
// wxFormBuilder sets initial splitter stash in idle event handler after GUI settles. Overriding our loaded value. Disconnect it's idle event handler.
wnd->m_splitterComposed->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaComposerPanelBase::m_splitterComposedOnIdle ), NULL, wnd );
wnd->m_splitterComposed->SetSashPosition(sashVal);
wnd->m_splitterDestination->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaComposerPanelBase::m_splitterDestinationOnIdle ), NULL, wnd );
wnd->m_splitterDestination->SetSashPosition(wxMulDivInt32(sashVal, dpiHorz, dpiHorzVal));
}
return true;

View File

@@ -1,20 +1,6 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
///
@@ -25,11 +11,19 @@ class wxZRColaComposerPanel;
#pragma once
#include <wxex/common.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include "zrcolagui.h"
#pragma warning(pop)
#include "zrcolakeyhndlr.h"
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include <wx/persist/window.h>
#include <wx/timer.h>
#pragma warning(pop)
#include <utility>
#include <vector>
///
@@ -41,36 +35,48 @@ public:
wxZRColaComposerPanel(wxWindow* parent);
virtual ~wxZRColaComposerPanel();
void RestoreFromStateFile();
void SynchronizePanels();
void SetDestinationFont(const wxFont& font, int flags = (wxTEXT_ATTR_FONT & ~wxTEXT_ATTR_FONT_PIXEL_SIZE));
void RestyleSource();
void RestyleDestination();
friend class wxPersistentZRColaComposerPanel; // Allow saving/restoring window state.
protected:
virtual void OnDecomposedPaint(wxPaintEvent& event);
virtual void OnDecomposedHexPaint(wxPaintEvent& event);
virtual void OnDecomposedText(wxCommandEvent& event);
virtual void OnComposedPaint(wxPaintEvent& event);
virtual void OnComposedHexPaint(wxPaintEvent& event);
virtual void OnComposedText(wxCommandEvent& event);
virtual void OnSourcePaint(wxPaintEvent& event);
virtual void OnSourceHexPaint(wxPaintEvent& event);
virtual void OnSourceText(wxCommandEvent& event);
virtual void OnDestinationPaint(wxPaintEvent& event);
virtual void OnDestinationHexPaint(wxPaintEvent& event);
virtual void OnDestinationText(wxCommandEvent& event);
virtual void OnSaveTimer(wxTimerEvent& event);
inline size_t MapToDestination(_In_ size_t src) const;
inline size_t MapToSource(_In_ size_t dst) const;
inline void GetTranslationSeq(_Out_ const ZRCola::transetid_t *&sets_begin, _Out_ const ZRCola::transetid_t *&sets_end) const;
static wxString GetStateFileName();
static size_t GetValue(wxTextCtrl *wnd, wxString &text);
static void SetHexValue(wxTextCtrl *wnd, std::pair<long, long> &range, ZRCola::mapping_vector &mapping, const wchar_t *src, size_t len, long from, long to);
protected:
bool m_decomposedChanged; ///< Boolean flag to mark decomposed text "dirty" to trigger composition
bool m_composedChanged; ///< Boolean flag to mark composed text "dirty" to trigger decomposition
ZRCola::mapping_vector m_mapping1; ///< Character index mapping vector between decomposed and normalized text
ZRCola::mapping_vector m_mapping2; ///< Character index mapping vector between normalized and composed text
bool m_sourceChanged; ///< Boolean flag to mark source text "dirty" to trigger translation
bool m_destinationChanged; ///< Boolean flag to mark destination text "dirty" to trigger inverse translation
volatile bool
m_sourceRestyled, ///< Boolean flag to mark source text is being restyled
m_destinationRestyled; ///< Boolean flag to mark destination text is being restyled
wxTextAttr
m_styleSource, ///< Normal source text style
m_styleDestination, ///< Normal destination text style
m_styleDestinationPUA; ///< PUA character destination text style
std::vector<ZRCola::mapping_vector> m_mapping; ///< Character index mapping vector between source and normalized text
std::pair<long, long>
m_selDecomposed, ///< Character index of selected text in decomposed text control
m_selDecomposedHex, ///< Character index of selected text in decomposed HEX dump text control
m_selComposed, ///< Character index of selected text in composed text control
m_selComposedHex; ///< Character index of selected text in composed HEX dump text control
wxZRColaKeyHandler m_keyhandler; ///< Key handler for decomposed window
ZRCola::mapping_vector m_mappingDecomposedHex; ///< Character index mapping vector between decomposed text and its HEX dump
ZRCola::mapping_vector m_mappingComposedHex; ///< Character index mapping vector between composed text and its HEX dump
m_selSource, ///< Character index of selected text in source text control
m_selSourceHex, ///< Character index of selected text in source HEX dump text control
m_selDestination, ///< Character index of selected text in destination text control
m_selDestinationHex; ///< Character index of selected text in destination HEX dump text control
wxZRColaKeyHandler m_keyhandler; ///< Key handler for source window
ZRCola::mapping_vector m_mappingSourceHex; ///< Character index mapping vector between source text and its HEX dump
ZRCola::mapping_vector m_mappingDestinationHex; ///< Character index mapping vector between destination text and its HEX dump
};
@@ -85,9 +91,54 @@ public:
virtual wxString GetKind() const;
virtual void Save() const;
virtual bool Restore();
protected:
static const int s_guiLevel; ///< Persisted placements/sizing are considered incompatible between different GUI levels
};
inline size_t wxZRColaComposerPanel::MapToDestination(_In_ size_t src) const
{
for (auto m = m_mapping.cbegin(), m_end = m_mapping.cend(); m != m_end; ++m)
src = m->to_dst(src);
return src;
}
inline size_t wxZRColaComposerPanel::MapToSource(_In_ size_t dst) const
{
for (auto m = m_mapping.crbegin(), m_end = m_mapping.crend(); m != m_end; ++m)
dst = m->to_src(dst);
return dst;
}
inline void wxZRColaComposerPanel::GetTranslationSeq(_Out_ const ZRCola::transetid_t *&sets_begin, _Out_ const ZRCola::transetid_t *&sets_end) const
{
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
if (app->m_mainWnd->m_transeq_id == ZRCOLA_TRANSEQID_DEFAULT) {
sets_begin = NULL;
sets_end = NULL;
} else if (app->m_mainWnd->m_transeq_id == ZRCOLA_TRANSEQID_CUSTOM) {
sets_begin = app->m_mainWnd->m_transeq->m_transeq.data();
sets_end = sets_begin + app->m_mainWnd->m_transeq->m_transeq.size();
} else {
size_t start;
if (app->m_tsq_db.idxTranSeq.find(ZRCola::transeq_db::transeq(app->m_mainWnd->m_transeq_id), start)) {
const auto &ts = app->m_tsq_db.idxTranSeq[start];
sets_begin = ts.sets();
sets_end = ts.sets_end();
} else {
sets_begin = NULL;
sets_end = NULL;
}
}
}
inline wxPersistentObject *wxCreatePersistentObject(wxZRColaComposerPanel *wnd)
{
return new wxPersistentZRColaComposerPanel(wnd);

View File

@@ -1,23 +1,9 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#include "stdafx.h"
#include "pch.h"
//////////////////////////////////////////////////////////////////////////
@@ -25,52 +11,95 @@
//////////////////////////////////////////////////////////////////////////
wxBEGIN_EVENT_TABLE(wxZRColaFrame, wxZRColaFrameBase)
EVT_MENU (wxID_EXIT , wxZRColaFrame::OnExit )
EVT_MENU (wxID_EXIT , wxZRColaFrame::OnExit )
EVT_UPDATE_UI_RANGE(wxID_CUT , wxID_CLEAR , wxZRColaFrame::OnForwardEventUpdate )
EVT_MENU_RANGE (wxID_CUT , wxID_CLEAR , wxZRColaFrame::OnForwardEvent )
EVT_UPDATE_UI (wxID_SELECTALL , wxZRColaFrame::OnForwardEventUpdate )
EVT_MENU (wxID_SELECTALL , wxZRColaFrame::OnForwardEvent )
EVT_UPDATE_UI_RANGE(wxID_CUT , wxID_CLEAR , wxZRColaFrame::OnForwardEventUpdate )
EVT_MENU_RANGE (wxID_CUT , wxID_CLEAR , wxZRColaFrame::OnForwardEvent )
EVT_UPDATE_UI (wxID_SELECTALL , wxZRColaFrame::OnForwardEventUpdate )
EVT_MENU (wxID_SELECTALL , wxZRColaFrame::OnForwardEvent )
EVT_MENU (wxID_CHARACTER_SELECTOR , wxZRColaFrame::OnInsertCharacter )
EVT_UPDATE_UI (wxID_CHARACTER_SELECTOR , wxZRColaFrame::OnInsertCharacterUpdate )
EVT_MENU (wxID_CHARACTER_SELECTOR , wxZRColaFrame::OnInsertCharacter )
EVT_UPDATE_UI_RANGE(wxID_SEND_COMPOSED , wxID_SEND_ABORT, wxZRColaFrame::OnSendUpdate )
EVT_MENU (wxID_SEND_COMPOSED , wxZRColaFrame::OnSendComposed )
EVT_MENU (wxID_SEND_DECOMPOSED , wxZRColaFrame::OnSendDecomposed )
EVT_MENU (wxID_SEND_ABORT , wxZRColaFrame::OnSendAbort )
EVT_UPDATE_UI_RANGE(wxID_SEND_DESTINATION , wxID_SEND_ABORT , wxZRColaFrame::OnSendUpdate )
EVT_MENU (wxID_COPY_DESTINATION_AND_RETURN , wxZRColaFrame::OnCopyDestinationAndReturn )
EVT_MENU (wxID_SEND_DESTINATION , wxZRColaFrame::OnSendDestination )
EVT_MENU (wxID_COPY_SOURCE_AND_RETURN , wxZRColaFrame::OnCopySourceAndReturn )
EVT_MENU (wxID_SEND_SOURCE , wxZRColaFrame::OnSendSource )
EVT_MENU (wxID_SEND_ABORT , wxZRColaFrame::OnSendAbort )
EVT_MENU (wxID_SETTINGS , wxZRColaFrame::OnSettings )
EVT_MENU (wxID_COMPOSITION , wxZRColaFrame::OnComposition )
EVT_MENU (wxID_FONT_DESTINATION , wxZRColaFrame::OnFontDestination )
EVT_MENU (wxID_WARN_PUA , wxZRColaFrame::OnWarnPUA )
EVT_MENU_RANGE (wxID_TRANSLATION_SEQ_DEFAULT, wxID_TRANSLATION_SEQ_END, wxZRColaFrame::OnTranslationSeqMenu )
EVT_UPDATE_UI (wxID_TOOLBAR_EDIT , wxZRColaFrame::OnToolbarEditUpdate )
EVT_MENU (wxID_TOOLBAR_EDIT , wxZRColaFrame::OnToolbarEdit )
EVT_UPDATE_UI (wxID_TOOLBAR_COMPOSE , wxZRColaFrame::OnToolbarComposeUpdate )
EVT_MENU (wxID_TOOLBAR_COMPOSE , wxZRColaFrame::OnToolbarCompose )
EVT_UPDATE_UI (wxID_PANEL_CHRGRPS , wxZRColaFrame::OnPanelCharacterCatalogUpdate)
EVT_MENU (wxID_PANEL_CHRGRPS , wxZRColaFrame::OnPanelCharacterCatalog )
EVT_MENU (wxID_FOCUS_CHARACTER_CATALOG , wxZRColaFrame::OnPanelCharacterCatalogFocus )
EVT_MENU (wxID_SETTINGS , wxZRColaFrame::OnSettings )
EVT_MENU (wxID_HELP_INSTRUCTIONS , wxZRColaFrame::OnHelpInstructions )
EVT_MENU (wxID_HELP_SHORTCUTS , wxZRColaFrame::OnHelpShortcuts )
EVT_UPDATE_UI (wxID_TOOLBAR_EDIT , wxZRColaFrame::OnToolbarEditUpdate )
EVT_MENU (wxID_TOOLBAR_EDIT , wxZRColaFrame::OnToolbarEdit )
EVT_UPDATE_UI (wxID_TOOLBAR_TRANSLATE , wxZRColaFrame::OnToolbarTranslateUpdate )
EVT_MENU (wxID_TOOLBAR_TRANSLATE , wxZRColaFrame::OnToolbarTranslate )
EVT_UPDATE_UI (wxID_TOOLBAR_DESTINATION , wxZRColaFrame::OnToolbarDestinationUpdate )
EVT_MENU (wxID_TOOLBAR_DESTINATION , wxZRColaFrame::OnToolbarDestination )
EVT_UPDATE_UI (wxID_PANEL_CHRGRPS , wxZRColaFrame::OnPanelCharacterCatalogUpdate)
EVT_MENU (wxID_PANEL_CHRGRPS , wxZRColaFrame::OnPanelCharacterCatalog )
EVT_MENU (wxID_FOCUS_CHARACTER_CATALOG , wxZRColaFrame::OnPanelCharacterCatalogFocus )
EVT_MENU (wxID_HELP_REQCHAR , wxZRColaFrame::OnHelpReqChar )
EVT_MENU (wxID_HELP_UPDATE , wxZRColaFrame::OnHelpUpdate )
EVT_MENU (wxID_ABOUT , wxZRColaFrame::OnHelpAbout )
EVT_MENU (wxID_HELP_INSTRUCTIONS , wxZRColaFrame::OnHelpInstructions )
EVT_MENU (wxID_HELP_SHORTCUTS , wxZRColaFrame::OnHelpShortcuts )
EVT_MENU (wxID_HELP_REQCHAR , wxZRColaFrame::OnHelpReqChar )
EVT_MENU (wxID_HELP_UPDATE , wxZRColaFrame::OnHelpUpdate )
EVT_MENU (wxID_ABOUT , wxZRColaFrame::OnHelpAbout )
wxEND_EVENT_TABLE()
const int wxZRColaFrame::s_guiLevel = 1;
wxZRColaFrame::wxZRColaFrame() :
m_hWndSource(NULL),
m_wasIconised(false),
m_chrSelect(NULL),
m_settings(NULL),
m_chrReq(NULL),
m_composition(true),
m_fontDestination(20, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("ZRCola")),
m_warnPUA(false),
m_transeq_id(ZRCOLA_TRANSEQID_DEFAULT),
m_transeq(NULL),
wxZRColaFrameBase(NULL)
{
{
// wxFrameBuilder 3.5 does not support wxAUI_TB_HORIZONTAL flag. Add it manually.
wxAuiPaneInfo &paneInfo = m_mgr.GetPane(m_toolbarCompose);
wxAuiPaneInfo &paneInfo = m_mgr.GetPane(m_toolbarTranslate);
paneInfo.LeftDockable(false);
paneInfo.RightDockable(false);
m_toolbarCompose->SetWindowStyleFlag(m_toolbarCompose->GetWindowStyleFlag() | wxAUI_TB_HORIZONTAL);
m_toolbarTranslate->SetWindowStyleFlag(m_toolbarTranslate->GetWindowStyleFlag() | wxAUI_TB_HORIZONTAL);
}
// Populate list of translation sequences.
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
m_toolTranslationSeq->Clear();
{
wxString name_tran(_("No Translation"));
m_menuTranslationSeq->AppendRadioItem(wxID_TRANSLATION_SEQ_DEFAULT, name_tran);
m_toolTranslationSeq->Append(name_tran, reinterpret_cast<void*>(ZRCOLA_TRANSEQID_DEFAULT));
}
for (size_t i = 0, n = app->m_tsq_db.idxRank.size(); ; i++) {
if (i < n) {
const ZRCola::transeq_db::transeq &ts = app->m_tsq_db.idxRank[i];
wxString
name(ts.name(), ts.name_len()),
name_tran(wxGetTranslation(name, wxT("ZRCola-zrcdb")));
m_menuTranslationSeq->AppendRadioItem((int)(wxID_TRANSLATION_SEQ_START + i), name_tran);
m_toolTranslationSeq->Append(name_tran, reinterpret_cast<void*>(ts.seq));
} else {
wxString name_tran(_("Custom Translation..."));
m_menuTranslationSeq->AppendRadioItem((int)(wxID_TRANSLATION_SEQ_START + i), name_tran);
m_toolTranslationSeq->Append(name_tran, reinterpret_cast<void*>(ZRCOLA_TRANSEQID_CUSTOM));
break;
}
}
// Load main window icons.
@@ -92,31 +121,38 @@ wxZRColaFrame::wxZRColaFrame() :
} else {
// Taskbar icon creation failed. Not the end of the world. No taskbar icon then.
delete m_taskBarIcon;
m_taskBarIcon = NULL;
}
wxPersistenceManager &persist_mgr = wxPersistenceManager::Get();
m_settings = new wxZRColaSettings(this);
wxPersistentRegisterAndRestore<wxZRColaSettings>(m_settings);
persist_mgr.RegisterAndRestore(m_settings, new wxPersistentZRColaSettings(m_settings));
m_transeq = new wxZRColaTranslationSeq(this);
persist_mgr.RegisterAndRestore(m_transeq, new wxPersistentZRColaTranslationSeq(m_transeq));
m_chrSelect = new wxZRColaCharSelect(this);
wxPersistentRegisterAndRestore<wxZRColaCharSelect>(m_chrSelect);
persist_mgr.RegisterAndRestore(m_chrSelect, new wxPersistentZRColaCharSelect(m_chrSelect));
m_chrReq = new wxZRColaCharRequest(this);
wxPersistentRegisterAndRestore<wxZRColaCharRequest>(m_chrReq);
persist_mgr.RegisterAndRestore(m_chrReq, new wxPersistentZRColaCharRequest(m_chrReq));
// Set focus.
m_panel->m_decomposed->SetFocus();
m_panel->m_source->SetFocus();
#if defined(__WXMSW__)
// Register notification sink for language detection.
m_ulRefCount = 1;
m_tfSource = NULL;
m_dwCookie = MAXDWORD;
ITfInputProcessorProfiles *pProfiles;
HRESULT hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER, IID_ITfInputProcessorProfiles, (LPVOID*)&pProfiles);
if(SUCCEEDED(hr)) {
hr = pProfiles->QueryInterface(IID_ITfSource, (LPVOID*)&m_tfSource);
if(SUCCEEDED(hr)) {
hr = m_tfSource->AdviseSink(IID_ITfLanguageProfileNotifySink, (ITfLanguageProfileNotifySink*)this, &m_dwCookie);
if (FAILED(hr) || m_dwCookie == -1) {
if (FAILED(hr) || m_dwCookie == MAXDWORD) {
m_tfSource->Release();
m_tfSource = NULL;
}
@@ -133,13 +169,53 @@ wxZRColaFrame::wxZRColaFrame() :
SetAcceleratorTable(wxAcceleratorTable(_countof(entries), entries));
}
// Restore persistent state of wxAuiManager manually, since m_mgr is not on the heap.
wxPersistentAuiManager(&m_mgr).Restore();
int guiLevel;
if (wxConfigBase::Get()->Read(wxT("guiLevel"), &guiLevel) && guiLevel == s_guiLevel) {
// Restore persistent state of wxAuiManager manually, since m_mgr is not a standalone heap object
// and cannot be registered for persistence.
wxPersistentAuiManager(&m_mgr).Restore();
}
persist_mgr.RegisterAndRestore(this, new wxPersistentZRColaFrame(this));
// Update (de)composition selection.
if (m_composition) {
m_menuItemComposition->Check(true);
m_toolComposition->SetState(m_toolComposition->GetState() | wxAUI_BUTTON_STATE_CHECKED);
} else {
m_menuItemComposition->Check(false);
m_toolComposition->SetState(m_toolComposition->GetState() & ~wxAUI_BUTTON_STATE_CHECKED);
}
m_fontpickerDestination->SetSelectedFont(m_fontDestination);
m_panel->SetDestinationFont(m_fontDestination);
if (m_warnPUA) {
m_menuItemWarnPUA->Check(true);
m_toolWarnPUA->SetState(m_toolWarnPUA->GetState() | wxAUI_BUTTON_STATE_CHECKED);
} else {
m_menuItemWarnPUA->Check(false);
m_toolWarnPUA->SetState(m_toolWarnPUA->GetState() & ~wxAUI_BUTTON_STATE_CHECKED);
}
// Update translation sequence selection.
for (unsigned int i = 0, n = m_toolTranslationSeq->GetCount(); ; i++) {
if (i < n) {
if (static_cast<ZRCola::transeqid_t>((size_t)m_toolTranslationSeq->GetClientData(i)) == m_transeq_id) {
m_menuTranslationSeq->Check(wxID_TRANSLATION_SEQ_DEFAULT + i, true);
m_toolTranslationSeq->SetSelection(i);
break;
}
} else {
m_transeq_id = ZRCOLA_TRANSEQID_DEFAULT;
m_menuTranslationSeq->Check(wxID_TRANSLATION_SEQ_DEFAULT, true);
m_toolTranslationSeq->SetSelection(0);
break;
}
}
// Register global hotkey(s).
if (!RegisterHotKey(wxZRColaHKID_INVOKE_COMPOSE, wxMOD_WIN, VK_F5))
if (!RegisterHotKey(wxZRColaHKID_INVOKE_TRANSLATE, wxMOD_WIN, VK_F5))
wxMessageBox(_("ZRCola keyboard shortcut Win+F5 could not be registered. Some functionality will not be available."), _("Warning"), wxOK | wxICON_WARNING);
if (!RegisterHotKey(wxZRColaHKID_INVOKE_DECOMPOSE, wxMOD_WIN, VK_F6))
if (!RegisterHotKey(wxZRColaHKID_INVOKE_TRANSLATE_INV, wxMOD_WIN, VK_F6))
wxMessageBox(_("ZRCola keyboard shortcut Win+F6 could not be registered. Some functionality will not be available."), _("Warning"), wxOK | wxICON_WARNING);
}
@@ -147,8 +223,14 @@ wxZRColaFrame::wxZRColaFrame() :
wxZRColaFrame::~wxZRColaFrame()
{
// Unregister global hotkey(s).
UnregisterHotKey(wxZRColaHKID_INVOKE_DECOMPOSE);
UnregisterHotKey(wxZRColaHKID_INVOKE_COMPOSE);
UnregisterHotKey(wxZRColaHKID_INVOKE_TRANSLATE_INV);
UnregisterHotKey(wxZRColaHKID_INVOKE_TRANSLATE );
// Save wxAuiManager's state before destructor is finished.
// m_mgr is not a standalone heap object and is bound to wxZRColaFrame, which is being destroyed.
wxConfigBase::Get()->Write(wxT("guiLevel"), s_guiLevel);
wxPersistentAuiManager(&m_mgr).Save();
wxPersistenceManager::Get().SaveAndUnregister(this);
#if defined(__WXMSW__)
if (m_tfSource) {
@@ -164,16 +246,6 @@ wxZRColaFrame::~wxZRColaFrame()
}
void wxZRColaFrame::OnClose(wxCloseEvent& event)
{
event.Skip();
// Save wxAuiManager's state before destructor.
// Since the destructor calls m_mgr.UnInit() the regular persistence mechanism is useless to save wxAuiManager's state.
wxPersistentAuiManager(&m_mgr).Save();
}
void wxZRColaFrame::OnExit(wxCommandEvent& event)
{
Close();
@@ -200,12 +272,15 @@ void wxZRColaFrame::OnForwardEvent(wxCommandEvent& event)
}
void wxZRColaFrame::OnInsertCharacterUpdate(wxUpdateUIEvent& event)
{
event.Check(m_chrSelect->IsVisible());
}
void wxZRColaFrame::OnInsertCharacter(wxCommandEvent& event)
{
if (m_chrSelect->ShowModal() == wxID_OK && m_chrSelect->m_char) {
m_panel->m_decomposed->WriteText(m_chrSelect->m_char);
m_panel->m_decomposed->SetFocus();
}
m_chrSelect->Show(!m_chrSelect->IsVisible());
}
@@ -215,19 +290,37 @@ void wxZRColaFrame::OnSendUpdate(wxUpdateUIEvent& event)
}
void wxZRColaFrame::OnSendComposed(wxCommandEvent& event)
void wxZRColaFrame::OnSendDestination(wxCommandEvent& event)
{
if (m_hWndSource)
DoSend(m_panel->m_composed->GetValue());
DoSend(m_panel->m_destination->GetValue());
event.Skip();
}
void wxZRColaFrame::OnSendDecomposed(wxCommandEvent& event)
void wxZRColaFrame::OnCopyDestinationAndReturn(wxCommandEvent& event)
{
if (m_hWndSource)
DoSend(m_panel->m_decomposed->GetValue());
DoCopyAndReturn(m_panel->m_destination->GetValue());
event.Skip();
}
void wxZRColaFrame::OnSendSource(wxCommandEvent& event)
{
if (m_hWndSource)
DoSend(m_panel->m_source->GetValue());
event.Skip();
}
void wxZRColaFrame::OnCopySourceAndReturn(wxCommandEvent& event)
{
if (m_hWndSource)
DoCopyAndReturn(m_panel->m_source->GetValue());
event.Skip();
}
@@ -237,14 +330,70 @@ void wxZRColaFrame::OnSendAbort(wxCommandEvent& event)
{
if (m_hWndSource) {
// Return focus to the source window.
if (m_wasIconised) Iconize();
::SetActiveWindow(m_hWndSource);
::SetForegroundWindow(m_hWndSource);
m_hWndSource = NULL;
}
// Select all input in composer to prepare for the overwrite next time.
m_panel->m_decomposed->SelectAll();
m_panel->m_composed->SelectAll();
m_panel->m_source ->SelectAll();
m_panel->m_destination->SelectAll();
event.Skip();
}
void wxZRColaFrame::OnComposition(wxCommandEvent& event)
{
m_composition = !m_composition;
m_menuItemComposition->Check(m_composition);
m_toolComposition->SetState((m_toolComposition->GetState() & ~wxAUI_BUTTON_STATE_CHECKED) | (m_composition ? wxAUI_BUTTON_STATE_CHECKED : 0));
m_toolbarTranslate->Refresh();
// Notify source text something changed and should re-translate.
wxCommandEvent event2(wxEVT_COMMAND_TEXT_UPDATED);
m_panel->m_source->ProcessWindowEvent(event2);
event.Skip();
}
void wxZRColaFrame::OnFontDestinationChanged(wxFontPickerEvent& event)
{
m_fontDestination = event.GetFont();
m_panel->SetDestinationFont(m_fontDestination);
m_panel->RestyleDestination();
event.Skip();
}
void wxZRColaFrame::OnFontDestination(wxCommandEvent& event)
{
wxFontData data;
data.SetInitialFont(m_fontDestination);
wxFontDialog dlg(this, data);
if (dlg.ShowModal() == wxID_OK)
{
data = dlg.GetFontData();
m_fontDestination = data.GetChosenFont();
m_fontpickerDestination->SetSelectedFont(m_fontDestination);
m_panel->SetDestinationFont(m_fontDestination);
m_panel->RestyleDestination();
}
event.Skip();
}
void wxZRColaFrame::OnWarnPUA(wxCommandEvent& event)
{
m_warnPUA = !m_warnPUA;
m_menuItemWarnPUA->Check(m_warnPUA);
m_toolWarnPUA->SetState((m_toolWarnPUA->GetState() & ~wxAUI_BUTTON_STATE_CHECKED) | (m_warnPUA ? wxAUI_BUTTON_STATE_CHECKED : 0));
m_toolbarDestination->Refresh();
m_panel->RestyleDestination();
event.Skip();
}
@@ -266,8 +415,8 @@ void wxZRColaFrame::OnIdle(wxIdleEvent& event)
void wxZRColaFrame::OnTaskbarIconClick(wxTaskBarIconEvent& event)
{
Iconize(false);
Show(true);
Iconize(false);
Raise();
event.Skip();
@@ -297,20 +446,59 @@ void wxZRColaFrame::OnToolbarEdit(wxCommandEvent& event)
}
void wxZRColaFrame::OnToolbarComposeUpdate(wxUpdateUIEvent& event)
void wxZRColaFrame::OnToolbarTranslateUpdate(wxUpdateUIEvent& event)
{
event.Check(m_mgr.GetPane(m_toolbarCompose).IsShown());
event.Check(m_mgr.GetPane(m_toolbarTranslate).IsShown());
}
void wxZRColaFrame::OnToolbarCompose(wxCommandEvent& event)
void wxZRColaFrame::OnToolbarTranslate(wxCommandEvent& event)
{
wxAuiPaneInfo &paneInfo = m_mgr.GetPane(m_toolbarCompose);
wxAuiPaneInfo &paneInfo = m_mgr.GetPane(m_toolbarTranslate);
paneInfo.Show(!paneInfo.IsShown());
m_mgr.Update();
}
void wxZRColaFrame::OnToolbarDestinationUpdate(wxUpdateUIEvent& event)
{
event.Check(m_mgr.GetPane(m_toolbarDestination).IsShown());
}
void wxZRColaFrame::OnToolbarDestination(wxCommandEvent& event)
{
wxAuiPaneInfo &paneInfo = m_mgr.GetPane(m_toolbarDestination);
paneInfo.Show(!paneInfo.IsShown());
m_mgr.Update();
}
void wxZRColaFrame::OnTranslationSeqMenu(wxCommandEvent& event)
{
int idx = event.GetId() - wxID_TRANSLATION_SEQ_DEFAULT;
ZRCola::transeqid_t transeq_id = static_cast<ZRCola::transeqid_t>((size_t)m_toolTranslationSeq->GetClientData(idx));
DoSetTranslationSeq(idx, transeq_id);
m_toolTranslationSeq->Select(idx);
}
void wxZRColaFrame::OnTranslationSeqChoice(wxCommandEvent& event)
{
int idx = event.GetSelection();
ZRCola::transeqid_t transeq_id = static_cast<ZRCola::transeqid_t>((size_t)event.GetClientData());
DoSetTranslationSeq(idx, transeq_id);
if (m_transeq_id == ZRCOLA_TRANSEQID_DEFAULT)
m_menuTranslationSeq->Check(wxID_TRANSLATION_SEQ_DEFAULT, true);
else
m_menuTranslationSeq->Check(wxID_TRANSLATION_SEQ_DEFAULT + idx, true);
}
void wxZRColaFrame::OnPanelCharacterCatalogUpdate(wxUpdateUIEvent& event)
{
event.Check(m_mgr.GetPane(m_panelChrCat).IsShown());
@@ -349,10 +537,11 @@ void wxZRColaFrame::OnHelpShortcuts(wxCommandEvent& event)
#ifdef __WXMSW__
// Search and try to launch installed PDF.
#pragma warning(suppress: 26812) // INSTALLSTATE is unscoped.
INSTALLSTATE pdf_is = ::MsiGetComponentPath(_T(PRODUCT_VERSION_GUID), _T("{68AC2C38-10E2-41A3-B92C-844C03FFDF6A}"), pdf_path);
if ((pdf_is == INSTALLSTATE_LOCAL || pdf_is == INSTALLSTATE_SOURCE) &&
wxFileExists(pdf_path) &&
(int)::ShellExecute(GetHWND(), NULL, pdf_path.c_str(), NULL, NULL, SW_SHOWNORMAL) > 32) return;
(intptr_t)::ShellExecute(GetHWND(), NULL, pdf_path.c_str(), NULL, NULL, SW_SHOWNORMAL) > 32) return;
#endif
// Search and try to launch local PDF copy.
@@ -360,7 +549,7 @@ void wxZRColaFrame::OnHelpShortcuts(wxCommandEvent& event)
pdf_path = app->GetDatabasePath();
pdf_path += _T("ZRCola_keyboard.pdf");
if (wxFileExists(pdf_path) &&
(int)::ShellExecute(GetHWND(), NULL, pdf_path.c_str(), NULL, NULL, SW_SHOWNORMAL) > 32) return;
(intptr_t)::ShellExecute(GetHWND(), NULL, pdf_path.c_str(), NULL, NULL, SW_SHOWNORMAL) > 32) return;
// When everything else fail, try the online version.
wxLaunchDefaultBrowser(_("http://zrcola.zrc-sazu.si/wp-content/uploads/2016/06/ZRCola_tipkovnica_Jun2016.pdf"));
@@ -450,10 +639,10 @@ void wxZRColaFrame::DoSend(const wxString& str)
{
// Prepare the INPUT table.
wxString::size_type n = str.length();
auto i_str = str.begin();
wxString::const_iterator i_str = str.begin();
std::vector<INPUT> input;
input.reserve(n*2);
for (std::vector<INPUT>::size_type i = 0; i < n; i++, i_str++) {
for (std::vector<INPUT>::size_type i = 0; i < n; i++, ++i_str) {
wxString::char_type c = *i_str;
// Add key down event.
@@ -468,15 +657,64 @@ void wxZRColaFrame::DoSend(const wxString& str)
}
// Return focus to the source window and send the input.
if (m_wasIconised) Iconize();
::SetActiveWindow(m_hWndSource);
::SetForegroundWindow(m_hWndSource);
::Sleep(200);
::SendInput(input.size(), input.data(), sizeof(INPUT));
::SendInput((UINT)input.size(), input.data(), sizeof(INPUT));
m_hWndSource = NULL;
// Select all input in composer and decomposed to prepare for the overwrite next time.
m_panel->m_decomposed->SelectAll();
m_panel->m_composed->SelectAll();
// Select all input in source and destination to prepare for the overwrite next time.
m_panel->m_source ->SelectAll();
m_panel->m_destination->SelectAll();
}
void wxZRColaFrame::DoCopyAndReturn(const wxString& str)
{
if (wxTheClipboard->Open()) {
wxTheClipboard->SetData(new wxTextDataObject(str));
wxTheClipboard->Close();
}
// Return focus to the source window.
if (m_wasIconised) Iconize();
::SetActiveWindow(m_hWndSource);
::SetForegroundWindow(m_hWndSource);
m_hWndSource = NULL;
// Select all input in composer and source to prepare for the overwrite next time.
m_panel->m_source->SelectAll();
m_panel->m_destination->SelectAll();
}
void wxZRColaFrame::DoSetTranslationSeq(int idx, ZRCola::transeqid_t transeq_id)
{
if (transeq_id == ZRCOLA_TRANSEQID_CUSTOM) {
// Prompt user to modify translation.
if (m_transeq->ShowModal() != wxID_OK)
return;
if (m_transeq->m_transeq.empty()) {
// User submitted an empty translation. Revert to "No Translation" case.
m_transeq_id = ZRCOLA_TRANSEQID_DEFAULT;
m_menuTranslationSeq->Check(wxID_TRANSLATION_SEQ_DEFAULT, true);
m_toolTranslationSeq->SetSelection(0);
} else {
m_transeq_id = ZRCOLA_TRANSEQID_CUSTOM;
m_menuTranslationSeq->Check(wxID_TRANSLATION_SEQ_DEFAULT + idx, true);
}
} else if (m_transeq_id != transeq_id) {
// User choose a new translation sequence.
m_transeq_id = transeq_id;
m_menuTranslationSeq->Check(wxID_TRANSLATION_SEQ_DEFAULT + idx, true);
} else
return;
// Notify source text something changed and should re-translate.
wxCommandEvent event2(wxEVT_COMMAND_TEXT_UPDATED);
m_panel->m_source->ProcessWindowEvent(event2);
}
@@ -489,8 +727,8 @@ WXLRESULT wxZRColaFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM
WXHWND hWndSource = ::GetForegroundWindow();
switch (wParam) {
case wxZRColaHKID_INVOKE_COMPOSE : m_panel->m_decomposed->SetFocus(); break;
case wxZRColaHKID_INVOKE_DECOMPOSE: m_panel->m_composed ->SetFocus(); break;
case wxZRColaHKID_INVOKE_TRANSLATE: m_panel->m_source->SetFocus(); break;
case wxZRColaHKID_INVOKE_TRANSLATE_INV: m_panel->m_destination->SetFocus(); break;
default:
wxFAIL_MSG(wxT("not our registered shortcut"));
return wxZRColaFrameBase::MSWWindowProc(message, wParam, lParam);
@@ -502,12 +740,13 @@ WXLRESULT wxZRColaFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM
}
m_hWndSource = hWndSource;
m_wasIconised = IsIconized();
//if (m_state == wxABS_FLOAT) {
if (IsIconized())
::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_RESTORE, 0);
::SetActiveWindow(m_hWnd);
::SetForegroundWindow(m_hWnd);
Show(true);
Iconize(false);
Raise();
::SetActiveWindow(m_hWnd);
//} else if (wxAppBarIsDocked(m_state)) {
// // ZRCola window is currently docked.
@@ -522,7 +761,8 @@ WXLRESULT wxZRColaFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM
// wxFAIL_MSG(wxT("unsupported application bar state"));
return 0;
} else
}
else
return wxZRColaFrameBase::MSWWindowProc(message, wParam, lParam);
}
@@ -533,17 +773,35 @@ WXLRESULT wxZRColaFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM
// wxPersistentZRColaFrame
//////////////////////////////////////////////////////////////////////////
wxPersistentZRColaFrame::wxPersistentZRColaFrame(wxZRColaFrame *wnd) : wxPersistentTLW(wnd)
const int wxPersistentZRColaFrame::s_guiLevel = 1;
wxPersistentZRColaFrame::wxPersistentZRColaFrame(wxZRColaFrame *wnd) : wxPersistentTLWEx(wnd)
{
}
void wxPersistentZRColaFrame::Save() const
{
wxPersistentTLW::Save();
SaveValue(wxT("guiLevel"), s_guiLevel);
wxPersistentTLWEx::Save();
auto wnd = static_cast<const wxZRColaFrame*>(GetWindow()); // dynamic_cast is not reliable as we are typically called late in the wxTopLevelWindowMSW destructor.
SaveValue(wxT("composition"), wnd->m_composition);
SaveValue(wxT("transeqId"), static_cast<int>(wnd->m_transeq_id));
#pragma warning(push)
#pragma warning(disable: 26812) // wxWidgets font enums are unscoped.
SaveValue(wxT("fontDestinationSize" ), wnd->m_fontDestination.GetPointSize());
SaveValue(wxT("fontDestinationFamily" ), wnd->m_fontDestination.GetFamily());
SaveValue(wxT("fontDestinationStyle" ), wnd->m_fontDestination.GetStyle());
SaveValue(wxT("fontDestinationWeight" ), wnd->m_fontDestination.GetWeight());
SaveValue(wxT("fontDestinationIsUnderlined"), wnd->m_fontDestination.GetUnderlined());
SaveValue(wxT("fontDestinationFace" ), wnd->m_fontDestination.GetFaceName());
#pragma warning(pop)
SaveValue(wxT("warnPUA"), wnd->m_warnPUA);
wxPersistentZRColaComposerPanel(wnd->m_panel).Save();
wxPersistentZRColaCharacterCatalogPanel(wnd->m_panelChrCat).Save();
}
@@ -556,5 +814,33 @@ bool wxPersistentZRColaFrame::Restore()
wxPersistentZRColaCharacterCatalogPanel(wnd->m_panelChrCat).Restore();
wxPersistentZRColaComposerPanel(wnd->m_panel).Restore();
return wxPersistentTLW::Restore();
int num;
if (RestoreValue(wxT("transeqId"), &num))
wnd->m_transeq_id = (ZRCola::transeqid_t)num;
bool b;
if (RestoreValue(wxT("composition"), &b))
wnd->m_composition = b;
else
wnd->m_composition = wnd->m_transeq_id == ZRCOLA_TRANSEQID_DEFAULT;
int fontSize = 20, fontFamily = wxFONTFAMILY_DEFAULT, fontStyle = wxFONTSTYLE_NORMAL, fontWeight = wxFONTWEIGHT_NORMAL;
bool fontIsUnderlined = false;
wxString fontFace(wxT("ZRCola"));
if (RestoreValue(wxT("fontDestinationSize" ), &fontSize) &&
RestoreValue(wxT("fontDestinationFamily" ), &fontFamily) &&
RestoreValue(wxT("fontDestinationStyle" ), &fontStyle) &&
RestoreValue(wxT("fontDestinationWeight" ), &fontWeight) &&
RestoreValue(wxT("fontDestinationIsUnderlined"), &fontIsUnderlined) &&
RestoreValue(wxT("fontDestinationFace" ), &fontFace))
wnd->m_fontDestination = wxFont(fontSize, (wxFontFamily)fontFamily, (wxFontStyle)fontStyle, (wxFontWeight)fontWeight, fontIsUnderlined, fontFace);
else
wnd->m_fontDestination = wxFont(20, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxT("ZRCola"));
if (RestoreValue(wxT("warnPUA"), &b))
wnd->m_warnPUA = b;
else
wnd->m_warnPUA = false;
int guiLevel;
return RestoreValue(wxT("guiLevel"), &guiLevel) && guiLevel == s_guiLevel ? wxPersistentTLWEx::Restore() : true;
}

View File

@@ -1,37 +1,33 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
///
/// Forward declarations
///
class wxZRColaFrame;
class wxPersistentZRColaFrame;
#pragma once
#include <wxex/common.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include "zrcolagui.h"
#pragma warning(pop)
#include "zrcolachrslct.h"
#include "zrcolachrreq.h"
#include "zrcolasettings.h"
#include "zrcolatranseq.h"
#include <zrcola/language.h>
#include <zrcola/translate.h>
#include <wxex/persist/toplevel.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include <wx/taskbar.h>
#include <wx/persist/toplevel.h>
#pragma warning(pop)
#if defined(__WXMSW__)
#include <msctf.h>
#endif
@@ -40,8 +36,8 @@ class wxZRColaFrame;
///
/// Global hotkey message identifiers
///
#define wxZRColaHKID_INVOKE_COMPOSE 0
#define wxZRColaHKID_INVOKE_DECOMPOSE 1
#define wxZRColaHKID_INVOKE_TRANSLATE 0
#define wxZRColaHKID_INVOKE_TRANSLATE_INV 1
///
@@ -57,6 +53,9 @@ public:
enum
{
wxID_FOCUS_CHARACTER_CATALOG = 2000,
wxID_TRANSLATION_SEQ_DEFAULT = 2001,
wxID_TRANSLATION_SEQ_START = 2002,
wxID_TRANSLATION_SEQ_END = 2100,
};
wxZRColaFrame();
@@ -66,23 +65,33 @@ public:
friend class wxZRColaComposerPanel;
protected:
virtual void OnClose(wxCloseEvent& event);
void OnExit(wxCommandEvent& event);
void OnForwardEventUpdate(wxUpdateUIEvent& event);
void OnForwardEvent(wxCommandEvent& event);
void OnInsertCharacterUpdate(wxUpdateUIEvent& event);
void OnInsertCharacter(wxCommandEvent& event);
void OnSendUpdate(wxUpdateUIEvent& event);
void OnSendComposed(wxCommandEvent& event);
void OnSendDecomposed(wxCommandEvent& event);
void OnSendDestination(wxCommandEvent& event);
void OnCopyDestinationAndReturn(wxCommandEvent& event);
void OnSendSource(wxCommandEvent& event);
void OnCopySourceAndReturn(wxCommandEvent& event);
void OnSendAbort(wxCommandEvent& event);
void OnComposition(wxCommandEvent& event);
virtual void OnFontDestinationChanged(wxFontPickerEvent& event);
void OnFontDestination(wxCommandEvent& event);
void OnWarnPUA(wxCommandEvent& event);
void OnSettings(wxCommandEvent& event);
virtual void OnIdle(wxIdleEvent& event);
void OnTaskbarIconClick(wxTaskBarIconEvent& event);
virtual void OnIconize(wxIconizeEvent& event);
void OnToolbarEditUpdate(wxUpdateUIEvent& event);
void OnToolbarEdit(wxCommandEvent& event);
void OnToolbarComposeUpdate(wxUpdateUIEvent& event);
void OnToolbarCompose(wxCommandEvent& event);
void OnToolbarTranslateUpdate(wxUpdateUIEvent& event);
void OnToolbarTranslate(wxCommandEvent& event);
void OnToolbarDestinationUpdate(wxUpdateUIEvent& event);
void OnToolbarDestination(wxCommandEvent& event);
void OnTranslationSeqMenu(wxCommandEvent& event);
virtual void OnTranslationSeqChoice(wxCommandEvent& event);
void OnPanelCharacterCatalogUpdate(wxUpdateUIEvent& event);
void OnPanelCharacterCatalog(wxCommandEvent& event);
void OnPanelCharacterCatalogFocus(wxCommandEvent& event);
@@ -111,31 +120,45 @@ protected:
private:
void DoSend(const wxString& str);
void DoCopyAndReturn(const wxString& str);
void DoSetTranslationSeq(int idx, ZRCola::transeqid_t transeq_id);
protected:
#ifdef __WXMSW__
virtual WXLRESULT MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
#endif
protected:
static const int s_guiLevel; ///< Persisted placements/sizing are considered incompatible between different GUI levels
protected:
WXHWND m_hWndSource; ///< Handle of the active window, when the ZRCola hotkey was pressed
bool m_wasIconised; ///< Was the ZRCola window iconized, when the ZRCola hotkey was pressed
wxTaskBarIcon *m_taskBarIcon; ///< Taskbar icon
wxZRColaCharSelect *m_chrSelect; ///< Character selection dialog
wxZRColaCharRequest *m_chrReq; ///< Request a New Character dialog
wxZRColaSettings *m_settings; ///< Configuration dialog
bool m_composition; ///< Is (de)composition enabled?
wxFont m_fontDestination; ///< Destination window font
bool m_warnPUA; ///< Mark Private-Use-Area characters in destination text
ZRCola::transeqid_t m_transeq_id; ///< Translation sequence ID
wxZRColaTranslationSeq *m_transeq; ///< Custom translation sequence dialog
};
///
/// Supports saving/restoring wxZRColaFrame GUI state
///
class wxPersistentZRColaFrame : public wxPersistentTLW
class wxPersistentZRColaFrame : public wxPersistentTLWEx
{
public:
wxPersistentZRColaFrame(wxZRColaFrame *wnd);
virtual void Save() const;
virtual bool Restore();
protected:
static const int s_guiLevel; ///< Persisted placements/sizing are considered incompatible between different GUI levels
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,368 +1,423 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jun 17 2015)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __ZRCOLAGUI_H__
#define __ZRCOLAGUI_H__
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/cshelp.h>
#include <wx/intl.h>
class wxZRColaCharGrid;
#include <wx/string.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/menu.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/aui/aui.h>
#include <wx/aui/auibar.h>
class wxZRColaCharacterCatalogPanel;
class wxZRColaComposerPanel;
#include <wx/statusbr.h>
#include <wx/frame.h>
#include <wx/textctrl.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <wx/panel.h>
#include <wx/splitter.h>
#include <wx/timer.h>
#include <wx/choice.h>
#include <wx/grid.h>
#include <wx/checkbox.h>
#include <wx/srchctrl.h>
#include <wx/hyperlink.h>
#include <wx/checklst.h>
#include <wx/stattext.h>
#include <wx/button.h>
#include <wx/dialog.h>
#include <wx/radiobut.h>
#include <wx/listbox.h>
#include <wx/listbook.h>
#include <wx/listctrl.h>
#include <wx/statbmp.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaFrameBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaFrameBase : public wxFrame
{
private:
protected:
enum
{
wxID_CHARACTER_SELECTOR = 1000,
wxID_SEND_COMPOSED,
wxID_SEND_DECOMPOSED,
wxID_SEND_ABORT,
wxID_SETTINGS,
wxID_TOOLBAR_EDIT,
wxID_TOOLBAR_COMPOSE,
wxID_PANEL_CHRGRPS,
wxID_HELP_INSTRUCTIONS,
wxID_HELP_SHORTCUTS,
wxID_HELP_REQCHAR,
wxID_HELP_UPDATE
};
wxMenuBar* m_menubar;
wxMenu* m_menuProgram;
wxMenu* m_menuEdit;
wxMenu* m_menuView;
wxMenu* m_menuHelp;
wxAuiToolBar* m_toolbarEdit;
wxAuiToolBarItem* m_toolEditCut;
wxAuiToolBarItem* m_toolEditCopy;
wxAuiToolBarItem* m_toolEditPaste;
wxAuiToolBar* m_toolbarCompose;
wxAuiToolBarItem* m_toolCharSelect;
wxAuiToolBarItem* m_toolSendComposed;
wxAuiToolBarItem* m_toolSendDecomposed;
wxZRColaCharacterCatalogPanel* m_panelChrCat;
wxStatusBar* m_statusBar;
// Virtual event handlers, overide them in your derived class
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnIconize( wxIconizeEvent& event ) { event.Skip(); }
virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); }
public:
wxZRColaComposerPanel* m_panel;
wxZRColaFrameBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("ZRCola"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 600,400 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL, const wxString& name = wxT("ZRCola") );
wxAuiManager m_mgr;
~wxZRColaFrameBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaComposerPanelBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaComposerPanelBase : public wxPanel
{
private:
protected:
enum
{
wxID_TIMER_SAVE = 1000
};
wxSplitterWindow* m_splitterDecomposed;
wxPanel* m_panelDecomposedEdit;
wxPanel* m_panelDecomposedHex;
wxTextCtrl* m_decomposedHex;
wxSplitterWindow* m_splitterComposed;
wxPanel* m_panelComposedEdit;
wxPanel* m_panelComposedHex;
wxTextCtrl* m_composedHex;
wxTimer m_timerSave;
// Virtual event handlers, overide them in your derived class
virtual void OnDecomposedPaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnDecomposedText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnDecomposedHexPaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnComposedPaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnComposedText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnComposedHexPaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnSaveTimer( wxTimerEvent& event ) { event.Skip(); }
public:
wxTextCtrl* m_decomposed;
wxTextCtrl* m_composed;
wxZRColaComposerPanelBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxT("ZRColaComposerPanel") );
~wxZRColaComposerPanelBase();
void m_splitterDecomposedOnIdle( wxIdleEvent& )
{
m_splitterDecomposed->SetSashPosition( -5 );
m_splitterDecomposed->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaComposerPanelBase::m_splitterDecomposedOnIdle ), NULL, this );
}
void m_splitterComposedOnIdle( wxIdleEvent& )
{
m_splitterComposed->SetSashPosition( -5 );
m_splitterComposed->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaComposerPanelBase::m_splitterComposedOnIdle ), NULL, this );
}
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaCharacterCatalogPanelBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaCharacterCatalogPanelBase : public wxPanel
{
private:
protected:
wxChoice* m_choice;
wxZRColaCharGrid* m_grid;
wxCheckBox* m_show_all;
// Virtual event handlers, overide them in your derived class
virtual void OnChoice( wxCommandEvent& event ) { event.Skip(); }
virtual void OnGridClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnGridKeyDown( wxKeyEvent& event ) { event.Skip(); }
virtual void OnShowAll( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaCharacterCatalogPanelBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxT("ZRColaCharacterCatalog") );
~wxZRColaCharacterCatalogPanelBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaCharSelectBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaCharSelectBase : public wxDialog
{
private:
protected:
wxSearchCtrl* m_search;
wxHyperlinkCtrl* m_search_more;
wxPanel* m_search_panel;
wxCheckListBox* m_categories;
wxHyperlinkCtrl* m_categoriesAll;
wxHyperlinkCtrl* m_categoriesNone;
wxHyperlinkCtrl* m_categoriesInvert;
wxZRColaCharGrid* m_gridResults;
wxZRColaCharGrid* m_gridRecent;
wxStaticText* m_labelUnicode;
wxTextCtrl* m_unicode;
wxTextCtrl* m_shortcut;
wxGrid* m_gridPreview;
wxTextCtrl* m_description;
wxTextCtrl* m_tags;
wxTextCtrl* m_category;
wxHyperlinkCtrl* m_navigateBack;
wxHyperlinkCtrl* m_navigateForward;
wxZRColaCharGrid* m_gridRelated;
wxStdDialogButtonSizer* m_sdbSizerButtons;
wxButton* m_sdbSizerButtonsOK;
wxButton* m_sdbSizerButtonsCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); }
virtual void OnSearchText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSearchMore( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnCategoriesToggle( wxCommandEvent& event ) { event.Skip(); }
virtual void OnCategoriesAll( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnCategoriesNone( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnCategoriesInvert( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnResultCellDClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnResultSelectCell( wxGridEvent& event ) { event.Skip(); }
virtual void OnResultsKeyDown( wxKeyEvent& event ) { event.Skip(); }
virtual void OnRecentCellDClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnRecentSelectCell( wxGridEvent& event ) { event.Skip(); }
virtual void OnRecentKeyDown( wxKeyEvent& event ) { event.Skip(); }
virtual void OnUnicodeText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnPreviewKeyDown( wxKeyEvent& event ) { event.Skip(); }
virtual void OnNavigateBack( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnNavigateForward( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnRelatedSelectCell( wxGridEvent& event ) { event.Skip(); }
virtual void OnOKButtonClick( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaCharSelectBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Character Search"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaCharSelect") );
~wxZRColaCharSelectBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaSettingsBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaSettingsBase : public wxDialog
{
private:
protected:
wxListbook* m_listbook;
wxPanel* m_panelLanguage;
wxStaticText* m_langLabel;
wxRadioButton* m_langAuto;
wxRadioButton* m_langManual;
wxListBox* m_languages;
wxPanel* m_panelAutoStart;
wxStaticText* m_autoStartLabel;
wxCheckBox* m_autoStart;
wxStdDialogButtonSizer* m_sdbSizerButtons;
wxButton* m_sdbSizerButtonsOK;
wxButton* m_sdbSizerButtonsApply;
wxButton* m_sdbSizerButtonsCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
virtual void OnLangAuto( wxCommandEvent& event ) { event.Skip(); }
virtual void OnLangManual( wxCommandEvent& event ) { event.Skip(); }
virtual void OnApplyButtonClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOKButtonClick( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaSettingsBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaSettings") );
~wxZRColaSettingsBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaAboutBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaAboutBase : public wxDialog
{
private:
protected:
wxStaticBitmap* m_bitmapIcon;
wxStaticText* m_staticTextZRCola;
wxStaticText* m_staticTextVersion;
wxStaticText* m_staticTextColophone;
wxStaticText* m_staticTextCopyright;
wxHyperlinkCtrl* m_hyperlink;
wxStaticText* m_staticTextDeclaration;
wxTextCtrl* m_declaration;
wxStdDialogButtonSizer* m_sdbSizerButtons;
wxButton* m_sdbSizerButtonsOK;
public:
wxZRColaAboutBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About ZRCola"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaAbout") );
~wxZRColaAboutBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaUpdaterBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaUpdaterBase : public wxDialog
{
private:
protected:
wxTextCtrl* m_log;
wxButton* m_buttonUpdate;
wxButton* m_buttonClose;
// Virtual event handlers, overide them in your derived class
virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); }
virtual void OnUpdate( wxCommandEvent& event ) { event.Skip(); }
virtual void OnClose( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaUpdaterBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Product Update"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaUpdater") );
~wxZRColaUpdaterBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaCharRequestBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaCharRequestBase : public wxDialog
{
private:
protected:
wxStaticText* m_characterLbl;
wxTextCtrl* m_character;
wxStaticText* m_characterNote;
wxStaticText* m_contextLbl;
wxTextCtrl* m_context;
wxStaticText* m_note;
wxStdDialogButtonSizer* m_sdbSizerButtons;
wxButton* m_sdbSizerButtonsOK;
wxButton* m_sdbSizerButtonsCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnOKButtonClick( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaCharRequestBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Request a New Character"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaCharRequest") );
~wxZRColaCharRequestBase();
};
#endif //__ZRCOLAGUI_H__
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/cshelp.h>
#include <wx/intl.h>
class wxZRColaCharGrid;
#include <wx/string.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/menu.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/aui/aui.h>
#include <wx/aui/auibar.h>
#include <wx/choice.h>
#include <wx/fontpicker.h>
class wxZRColaCharacterCatalogPanel;
class wxZRColaComposerPanel;
#include <wx/statusbr.h>
#include <wx/frame.h>
#include <wx/textctrl.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <wx/panel.h>
#include <wx/splitter.h>
#include <wx/timer.h>
#include <wx/grid.h>
#include <wx/checkbox.h>
#include <wx/srchctrl.h>
#include <wx/hyperlink.h>
#include <wx/checklst.h>
#include <wx/stattext.h>
#include <wx/button.h>
#include <wx/dialog.h>
#include <wx/radiobut.h>
#include <wx/listbox.h>
#include <wx/listbook.h>
#include <wx/listctrl.h>
#include <wx/statbmp.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaFrameBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaFrameBase : public wxFrame
{
private:
protected:
enum
{
wxID_CHARACTER_SELECTOR = 1000,
wxID_SEND_DESTINATION,
wxID_COPY_DESTINATION_AND_RETURN,
wxID_SEND_SOURCE,
wxID_COPY_SOURCE_AND_RETURN,
wxID_SEND_ABORT,
wxID_COMPOSITION,
wxID_FONT_DESTINATION,
wxID_WARN_PUA,
wxID_SETTINGS,
wxID_TOOLBAR_EDIT,
wxID_TOOLBAR_TRANSLATE,
wxID_TOOLBAR_DESTINATION,
wxID_PANEL_CHRGRPS,
wxID_HELP_INSTRUCTIONS,
wxID_HELP_SHORTCUTS,
wxID_HELP_REQCHAR,
wxID_HELP_UPDATE
};
wxMenuBar* m_menubar;
wxMenu* m_menuProgram;
wxMenu* m_menuEdit;
wxMenuItem* m_menuItemComposition;
wxMenu* m_menuTranslationSeq;
wxMenuItem* m_menuItemWarnPUA;
wxMenu* m_menuView;
wxMenu* m_menuHelp;
wxAuiToolBar* m_toolbarEdit;
wxAuiToolBarItem* m_toolEditCut;
wxAuiToolBarItem* m_toolEditCopy;
wxAuiToolBarItem* m_toolEditPaste;
wxAuiToolBar* m_toolbarTranslate;
wxAuiToolBarItem* m_toolCharSelect;
wxAuiToolBarItem* m_toolSendDestination;
wxAuiToolBarItem* m_toolSendSource;
wxAuiToolBarItem* m_toolComposition;
wxChoice* m_toolTranslationSeq;
wxAuiToolBar* m_toolbarDestination;
wxFontPickerCtrl* m_fontpickerDestination;
wxAuiToolBarItem* m_toolWarnPUA;
wxZRColaCharacterCatalogPanel* m_panelChrCat;
wxStatusBar* m_statusBar;
// Virtual event handlers, overide them in your derived class
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnIconize( wxIconizeEvent& event ) { event.Skip(); }
virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); }
virtual void OnTranslationSeqChoice( wxCommandEvent& event ) { event.Skip(); }
virtual void OnFontDestinationChanged( wxFontPickerEvent& event ) { event.Skip(); }
public:
wxZRColaComposerPanel* m_panel;
wxZRColaFrameBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("ZRCola"), const wxPoint& pos = wxDefaultPosition, long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL, const wxString& name = wxT("ZRCola") );
wxAuiManager m_mgr;
~wxZRColaFrameBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaComposerPanelBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaComposerPanelBase : public wxPanel
{
private:
protected:
enum
{
wxID_TIMER_SAVE = 1000
};
wxSplitterWindow* m_splitterSource;
wxPanel* m_panelSourceEdit;
wxPanel* m_panelSourceHex;
wxTextCtrl* m_sourceHex;
wxSplitterWindow* m_splitterDestination;
wxPanel* m_panelDestinationEdit;
wxPanel* m_panelDestinationHex;
wxTextCtrl* m_destinationHex;
wxTimer m_timerSave;
// Virtual event handlers, overide them in your derived class
virtual void OnSourcePaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnSourceText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSourceHexPaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnDestinationPaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnDestinationText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnDestinationHexPaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnSaveTimer( wxTimerEvent& event ) { event.Skip(); }
public:
wxTextCtrl* m_source;
wxTextCtrl* m_destination;
wxZRColaComposerPanelBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxT("ZRColaComposerPanel") );
~wxZRColaComposerPanelBase();
void m_splitterSourceOnIdle( wxIdleEvent& )
{
m_splitterSource->SetSashPosition( FromDIP(-5) );
m_splitterSource->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaComposerPanelBase::m_splitterSourceOnIdle ), NULL, this );
}
void m_splitterDestinationOnIdle( wxIdleEvent& )
{
m_splitterDestination->SetSashPosition( FromDIP(-5) );
m_splitterDestination->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaComposerPanelBase::m_splitterDestinationOnIdle ), NULL, this );
}
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaCharacterCatalogPanelBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaCharacterCatalogPanelBase : public wxPanel
{
private:
protected:
wxChoice* m_choice;
wxZRColaCharGrid* m_grid;
wxCheckBox* m_show_all;
// Virtual event handlers, overide them in your derived class
virtual void OnChoice( wxCommandEvent& event ) { event.Skip(); }
virtual void OnGridClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnGridKeyDown( wxKeyEvent& event ) { event.Skip(); }
virtual void OnShowAll( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaCharacterCatalogPanelBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxT("ZRColaCharacterCatalog") );
~wxZRColaCharacterCatalogPanelBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaCharSelectBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaCharSelectBase : public wxDialog
{
private:
protected:
wxSearchCtrl* m_search;
wxHyperlinkCtrl* m_search_more;
wxPanel* m_search_panel;
wxCheckListBox* m_categories;
wxHyperlinkCtrl* m_categoriesAll;
wxHyperlinkCtrl* m_categoriesNone;
wxHyperlinkCtrl* m_categoriesInvert;
wxZRColaCharGrid* m_gridResults;
wxZRColaCharGrid* m_gridRecent;
wxStaticText* m_labelUnicode;
wxTextCtrl* m_unicode;
wxTextCtrl* m_shortcut;
wxGrid* m_gridPreview;
wxTextCtrl* m_description;
wxTextCtrl* m_tags;
wxTextCtrl* m_category;
wxHyperlinkCtrl* m_navigateBack;
wxHyperlinkCtrl* m_navigateForward;
wxZRColaCharGrid* m_gridRelated;
wxButton* m_buttonInsert;
// Virtual event handlers, overide them in your derived class
virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); }
virtual void OnSearchText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSearchMore( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnCategoriesToggle( wxCommandEvent& event ) { event.Skip(); }
virtual void OnCategoriesAll( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnCategoriesNone( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnCategoriesInvert( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnResultCellDClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnResultSelectCell( wxGridEvent& event ) { event.Skip(); }
virtual void OnResultsKeyDown( wxKeyEvent& event ) { event.Skip(); }
virtual void OnRecentCellDClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnRecentSelectCell( wxGridEvent& event ) { event.Skip(); }
virtual void OnRecentKeyDown( wxKeyEvent& event ) { event.Skip(); }
virtual void OnUnicodeText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnPreviewKeyDown( wxKeyEvent& event ) { event.Skip(); }
virtual void OnNavigateBack( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnNavigateForward( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void OnRelatedSelectCell( wxGridEvent& event ) { event.Skip(); }
virtual void OnInsert( wxCommandEvent& event ) { event.Skip(); }
virtual void OnInsertUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
public:
wxZRColaCharSelectBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Character Search"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaCharSelect") );
~wxZRColaCharSelectBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaSettingsBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaSettingsBase : public wxDialog
{
private:
protected:
wxListbook* m_listbook;
wxPanel* m_panelLanguage;
wxStaticText* m_langLabel;
wxRadioButton* m_langAuto;
wxRadioButton* m_langManual;
wxListBox* m_languages;
wxPanel* m_panelAutoStart;
wxStaticText* m_autoStartLabel;
wxCheckBox* m_autoStart;
wxStdDialogButtonSizer* m_sdbSizerButtons;
wxButton* m_sdbSizerButtonsOK;
wxButton* m_sdbSizerButtonsApply;
wxButton* m_sdbSizerButtonsCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
virtual void OnLanguageUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnApplyButtonClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOKButtonClick( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaSettingsBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaSettings") );
~wxZRColaSettingsBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaAboutBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaAboutBase : public wxDialog
{
private:
protected:
wxStaticBitmap* m_bitmapIcon;
wxStaticText* m_staticTextZRCola;
wxStaticText* m_staticTextVersion;
wxStaticText* m_staticTextColophone;
wxStaticText* m_staticTextCopyright;
wxHyperlinkCtrl* m_hyperlink;
wxStaticText* m_staticTextDeclaration;
wxTextCtrl* m_declaration;
wxStdDialogButtonSizer* m_sdbSizerButtons;
wxButton* m_sdbSizerButtonsOK;
public:
wxZRColaAboutBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About ZRCola"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaAbout") );
~wxZRColaAboutBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaUpdaterBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaUpdaterBase : public wxDialog
{
private:
protected:
wxTextCtrl* m_log;
wxButton* m_buttonUpdate;
wxButton* m_buttonClose;
// Virtual event handlers, overide them in your derived class
virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); }
virtual void OnUpdate( wxCommandEvent& event ) { event.Skip(); }
virtual void OnClose( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaUpdaterBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Product Update"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaUpdater") );
~wxZRColaUpdaterBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaCharRequestBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaCharRequestBase : public wxDialog
{
private:
protected:
wxStaticText* m_characterLbl;
wxTextCtrl* m_character;
wxStaticText* m_characterNote;
wxStaticText* m_contextLbl;
wxTextCtrl* m_context;
wxStaticText* m_note;
wxStdDialogButtonSizer* m_sdbSizerButtons;
wxButton* m_sdbSizerButtonsOK;
wxButton* m_sdbSizerButtonsCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnOKButtonClick( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaCharRequestBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Request a New Character"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaCharRequest") );
~wxZRColaCharRequestBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaTranslationSeqBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaTranslationSeqBase : public wxDialog
{
private:
protected:
wxStaticText* m_transLbl;
wxStaticText* m_availableLbl;
wxListBox* m_available;
wxButton* m_add;
wxButton* m_remove;
wxStaticText* m_selectedLbl;
wxListBox* m_selected;
wxButton* m_selectedUp;
wxButton* m_selectedDown;
wxStdDialogButtonSizer* m_sdbSizerButtons;
wxButton* m_sdbSizerButtonsOK;
wxButton* m_sdbSizerButtonsCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
virtual void OnUpdate( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnAvailableChar( wxKeyEvent& event ) { event.Skip(); }
virtual void OnAvailableDClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnAdd( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRemove( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSelectedChar( wxKeyEvent& event ) { event.Skip(); }
virtual void OnSelectedDClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSelectedUp( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSelectedDown( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOKButtonClick( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaTranslationSeqBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Custom Translation Sequence"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaTranslationSeq") );
~wxZRColaTranslationSeqBase();
};

View File

@@ -1,23 +1,9 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#include "stdafx.h"
#include "pch.h"
//////////////////////////////////////////////////////////////////////////
@@ -47,7 +33,7 @@ bool wxZRColaKeyHandler::ProcessEvent(wxEvent& event)
if (!chr) {
int key = e.GetKeyCode();
if (WXK_NUMPAD0 <= key && key <= WXK_NUMPAD9)
chr = '0' + (key - WXK_NUMPAD0);
chr = '0' + (wxChar)(key - WXK_NUMPAD0);
}
wxFrame *pFrame = wxDynamicCast(dynamic_cast<ZRColaApp*>(wxTheApp)->m_mainWnd, wxFrame);
if (('0' <= chr && chr <= '9' || 'A' <= chr && chr <= 'F') && m_insert_seq.size() < 4) {
@@ -81,14 +67,14 @@ bool wxZRColaKeyHandler::ProcessEvent(wxEvent& event)
{
// Parse key event and save it at the end of the key sequence.
ZRCola::keyseq_db::keyseq::key_t key;
key.key = e.GetRawKeyCode();
key.key = (wchar_t)e.GetRawKeyCode();
#if defined(__WXMSW__)
// Translate from local keyboard to scan code.
key.key = ::MapVirtualKey(key.key, MAPVK_VK_TO_VSC);
key.key = static_cast<wchar_t>(::MapVirtualKey(key.key, MAPVK_VK_TO_VSC) & 0xffff);
// Translate from scan code to U.S. Keyboard.
static const HKL s_hkl = ::LoadKeyboardLayout(_T("00000409"), 0);
key.key = ::MapVirtualKeyEx(key.key, MAPVK_VSC_TO_VK, s_hkl);
key.key = static_cast<wchar_t>(::MapVirtualKeyEx(key.key, MAPVK_VSC_TO_VK, s_hkl) & 0xffff);
#endif
key.modifiers =
(e.ShiftDown() ? ZRCola::keyseq_db::keyseq::SHIFT : 0) |
@@ -96,13 +82,9 @@ bool wxZRColaKeyHandler::ProcessEvent(wxEvent& event)
(e.AltDown() ? ZRCola::keyseq_db::keyseq::ALT : 0);
m_seq.push_back(key);
auto n = m_seq.size();
ZRCola::keyseq_db::keyseq *ks = (ZRCola::keyseq_db::keyseq*)new char[sizeof(ZRCola::keyseq_db::keyseq) + sizeof(ZRCola::keyseq_db::keyseq::key_t)*n];
ks->chr = 0;
ks->seq_len = n;
memcpy(ks->seq, m_seq.data(), sizeof(ZRCola::keyseq_db::keyseq::key_t)*n);
std::unique_ptr<ZRCola::keyseq_db::keyseq> ks((ZRCola::keyseq_db::keyseq*)new char[sizeof(ZRCola::keyseq_db::keyseq) + sizeof(ZRCola::keyseq_db::keyseq::key_t)*m_seq.size()]);
ks->ZRCola::keyseq_db::keyseq::keyseq(m_seq.data(), m_seq.size());
found = app->m_ks_db.idxKey.find(*ks, start);
delete ks;
}
if (found) {
@@ -116,14 +98,14 @@ bool wxZRColaKeyHandler::ProcessEvent(wxEvent& event)
wxObject *obj = event.GetEventObject();
if (obj && obj->IsKindOf(wxCLASSINFO(wxTextCtrl))) {
// Push text to source control.
((wxTextCtrl*)obj)->WriteText(ks.chr);
((wxTextCtrl*)obj)->WriteText(wxString(ks.chr(), ks.chr_len()));
// Event is fully processed now.
event.StopPropagation();
return true;
}
} else if (start < app->m_ks_db.idxKey.size() &&
ZRCola::keyseq_db::keyseq::CompareSequence(m_seq.data(), m_seq.size(), app->m_ks_db.idxKey[start].seq, std::min<unsigned __int16>(app->m_ks_db.idxKey[start].seq_len, m_seq.size())) == 0)
ZRCola::keyseq_db::keyseq::CompareSequence(m_seq.data(), m_seq.size(), app->m_ks_db.idxKey[start].seq(), std::min<size_t>(app->m_ks_db.idxKey[start].seq_len(), m_seq.size())) == 0)
{
// The sequence is a partial match. Continue watching.
if (pFrame && pFrame->GetStatusBar())
@@ -151,7 +133,7 @@ bool wxZRColaKeyHandler::ProcessEvent(wxEvent& event)
if (count) {
// Zero terminate sequence and parse the Unicode value.
m_insert_seq.push_back(0);
wchar_t chr = strtoul(m_insert_seq.data(), NULL, 16);
wchar_t chr = (wchar_t)strtoul(m_insert_seq.data(), NULL, 16);
if (chr) {
wxObject *obj = event.GetEventObject();

View File

@@ -1,20 +1,6 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
///
@@ -27,7 +13,11 @@ class wxZRColaKeyHandler;
#include <zrcolaui/keyboard.h>
#include <wxex/common.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include <wx/event.h>
#pragma warning(pop)
#include <vector>

View File

@@ -1,23 +1,9 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#include "stdafx.h"
#include "pch.h"
//////////////////////////////////////////////////////////////////////////
@@ -31,12 +17,12 @@ wxZRColaSettings::wxZRColaSettings(wxWindow* parent) :
{
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
m_languages->Clear();
for (size_t i = 0, n = app->m_lang_db.idxLng.size(); i < n; i++) {
const auto &lang = app->m_lang_db.idxLng[i];
for (size_t i = 0, n = app->m_lang_db.idxLang.size(); i < n; i++) {
const auto &lang = app->m_lang_db.idxLang[i];
wxString
label(lang.name, lang.name_len),
label(lang.name(), lang.name_len()),
label_tran(wxGetTranslation(label, wxT("ZRCola-zrcdb")));
m_languages->Insert(label_tran, i);
m_languages->Insert(label_tran, (unsigned int)i);
}
}
@@ -58,22 +44,16 @@ void wxZRColaSettings::OnInitDialog(wxInitDialogEvent& event)
(m_lang_auto ? m_langAuto : m_langManual)->SetValue(true);
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
char l[sizeof(ZRCola::language_db::language)] = {};
((ZRCola::language_db::language*)l)->id = m_lang;
ZRCola::language_db::indexLang::size_type start;
m_languages->Select(app->m_lang_db.idxLng.find(*(ZRCola::language_db::language*)l, start) ? start : -1);
m_languages->Select(app->m_lang_db.idxLang.find(ZRCola::language_db::language(m_lang), start) ? (int)start : -1);
}
void wxZRColaSettings::OnLangAuto(wxCommandEvent& event)
void wxZRColaSettings::OnLanguageUpdate(wxUpdateUIEvent& event)
{
m_languages->Enable(!event.IsChecked());
}
m_languages->Enable(m_langManual->GetValue());
void wxZRColaSettings::OnLangManual(wxCommandEvent& event)
{
m_languages->Enable(event.IsChecked());
wxZRColaSettingsBase::OnLanguageUpdate(event);
}
@@ -122,20 +102,19 @@ void wxZRColaSettings::OnApplyButtonClick(wxCommandEvent& event)
m_lang_auto = false;
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
const auto &lang = app->m_lang_db.idxLng[m_languages->GetSelection()];
const auto &lang = app->m_lang_db.idxLang[m_languages->GetSelection()];
if (m_lang != lang.id) {
m_lang = lang.id;
if (m_lang != lang.lang) {
m_lang = lang.lang;
// Notify composed text something changed and should re-decompose.
// Notify destination text something changed and should re-inverse translate.
wxCommandEvent event2(wxEVT_COMMAND_TEXT_UPDATED);
app->m_mainWnd->m_panel->m_composed->ProcessWindowEvent(event2);
app->m_mainWnd->m_panel->m_destination->ProcessWindowEvent(event2);
}
}
}
void wxZRColaSettings::OnOKButtonClick(wxCommandEvent& event)
{
wxZRColaSettings::OnApplyButtonClick(event);
@@ -146,14 +125,18 @@ void wxZRColaSettings::OnOKButtonClick(wxCommandEvent& event)
// wxPersistentZRColaSettings
//////////////////////////////////////////////////////////////////////////
wxPersistentZRColaSettings::wxPersistentZRColaSettings(wxZRColaSettings *wnd) : wxPersistentDialog(wnd)
const int wxPersistentZRColaSettings::s_guiLevel = 1;
wxPersistentZRColaSettings::wxPersistentZRColaSettings(wxZRColaSettings *wnd) : wxPersistentTLWEx(wnd)
{
}
void wxPersistentZRColaSettings::Save() const
{
wxPersistentDialog::Save();
SaveValue(wxT("guiLevel"), s_guiLevel);
wxPersistentTLWEx::Save();
auto wnd = static_cast<const wxZRColaSettings*>(GetWindow()); // dynamic_cast is not reliable as we are typically called late in the wxTopLevelWindowMSW destructor.
@@ -179,11 +162,11 @@ bool wxPersistentZRColaSettings::Restore()
} else if (RestoreValue(wxT("lang"), &lang) && lang.Length() == 3) {
// The language was read from configuration.
wnd->m_lang = lang.c_str();
} else if (!app->m_lang_db.idxLng.empty()) {
const auto &lang = app->m_lang_db.idxLng[0];
wnd->m_lang = lang.id;
} else if (!app->m_lang_db.idxLang.empty()) {
wnd->m_lang = app->m_lang_db.idxLang[0].lang;
} else
wnd->m_lang = ZRCola::langid_t::blank;
return wxPersistentDialog::Restore();
int guiLevel;
return RestoreValue(wxT("guiLevel"), &guiLevel) && guiLevel == s_guiLevel ? wxPersistentTLWEx::Restore() : true;
}

View File

@@ -1,20 +1,6 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
///
@@ -26,8 +12,13 @@ class wxPersistentZRColaSettings;
#pragma once
#include <wxex/common.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include "zrcolagui.h"
#include <wxex/persist/dialog.h>
#pragma warning(pop)
#include <wxex/persist/toplevel.h>
#include <vector>
///
@@ -42,27 +33,29 @@ public:
protected:
virtual void OnInitDialog(wxInitDialogEvent& event);
virtual void OnLangAuto(wxCommandEvent& event);
virtual void OnLangManual(wxCommandEvent& event);
virtual void OnLanguageUpdate(wxUpdateUIEvent& event);
virtual void OnApplyButtonClick(wxCommandEvent& event);
virtual void OnOKButtonClick(wxCommandEvent& event);
public:
bool m_lang_auto; ///< Is language for decomposing resolved using currently selected keyboard
ZRCola::langid_t m_lang; ///< Language for decomposing
bool m_lang_auto; ///< Is language for inverse translation resolved using currently selected keyboard
ZRCola::langid_t m_lang; ///< Language for inverse translation
};
///
/// Supports saving/restoring wxZRColaSettings state
///
class wxPersistentZRColaSettings : public wxPersistentDialog
class wxPersistentZRColaSettings : public wxPersistentTLWEx
{
public:
wxPersistentZRColaSettings(wxZRColaSettings *wnd);
virtual void Save() const;
virtual bool Restore();
protected:
static const int s_guiLevel; ///< Persisted placements/sizing are considered incompatible between different GUI levels
};

244
ZRCola/zrcolatranseq.cpp Normal file
View File

@@ -0,0 +1,244 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#include "pch.h"
//////////////////////////////////////////////////////////////////////////
// wxZRColaTranslationSeq
//////////////////////////////////////////////////////////////////////////
wxZRColaTranslationSeq::wxZRColaTranslationSeq(wxWindow* parent) :
wxZRColaTranslationSeqBase(parent)
{
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
m_available->Clear();
for (size_t i = 0, n = app->m_ts_db.idxTranSet.size(); i < n; i++) {
const ZRCola::transet_db::transet &ts = app->m_ts_db.idxTranSet[i];
wxString
src(ts.src(), ts.src_len()),
dst(ts.dst(), ts.dst_len()),
src_tran(wxGetTranslation(src, wxT("ZRCola-zrcdb"))),
dst_tran(wxGetTranslation(dst, wxT("ZRCola-zrcdb"))),
label_tran(wxString::Format(wxT("%s \x00bb %s"), src_tran.c_str(), dst_tran.c_str()));
m_available->Append(label_tran, (void*)ts.set);
}
}
void wxZRColaTranslationSeq::OnInitDialog(wxInitDialogEvent& event)
{
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
m_selected->Clear();
for (auto s = m_transeq.cbegin(), s_end = m_transeq.cend(); s != s_end; ++s) {
ZRCola::transet_db::indexTranSet::size_type start;
if (app->m_ts_db.idxTranSet.find(ZRCola::transet_db::transet(*s), start)) {
const ZRCola::transet_db::transet &ts = app->m_ts_db.idxTranSet[start];
wxString
src(ts.src(), ts.src_len()),
dst(ts.dst(), ts.dst_len()),
src_tran(wxGetTranslation(src, wxT("ZRCola-zrcdb"))),
dst_tran(wxGetTranslation(dst, wxT("ZRCola-zrcdb"))),
label_tran(wxString::Format(wxT("%s \x00bb %s"), src_tran.c_str(), dst_tran.c_str()));
m_selected->Append(label_tran, (void*)ts.set);
} else {
wxString label_tran(wxString::Format(_("Unknown translation (%u)"), (unsigned int)*s));
m_selected->Append(label_tran, (void*)*s);
}
}
wxZRColaTranslationSeqBase::OnInitDialog(event);
}
void wxZRColaTranslationSeq::OnUpdate(wxUpdateUIEvent& event)
{
m_add->Enable(m_available->GetSelection() != wxNOT_FOUND);
int idx = m_selected->GetSelection();
m_remove ->Enable(idx != wxNOT_FOUND);
m_selectedUp ->Enable(idx != wxNOT_FOUND && (unsigned int)idx > 0);
m_selectedDown->Enable(idx != wxNOT_FOUND && (unsigned int)idx < m_selected->GetCount() - 1);
wxZRColaTranslationSeqBase::OnUpdate(event);
}
void wxZRColaTranslationSeq::OnAvailableChar(wxKeyEvent& event)
{
if (event.GetRawKeyCode() == VK_INSERT) {
int idx = m_available->GetSelection();
if (idx != wxNOT_FOUND) {
m_selected->Append(
m_available->GetString(idx),
m_available->GetClientData(idx));
}
}
wxZRColaTranslationSeqBase::OnAvailableChar(event);
}
void wxZRColaTranslationSeq::OnAvailableDClick(wxCommandEvent& event)
{
int idx = m_available->GetSelection();
if (idx != wxNOT_FOUND) {
m_selected->Append(
m_available->GetString(idx),
m_available->GetClientData(idx));
}
wxZRColaTranslationSeqBase::OnAvailableDClick(event);
}
void wxZRColaTranslationSeq::OnAdd(wxCommandEvent& event)
{
int idx = m_available->GetSelection();
wxASSERT_MSG(idx != wxNOT_FOUND, wxT("no available translation selected"));
m_selected->Append(
m_available->GetString(idx),
m_available->GetClientData(idx));
wxZRColaTranslationSeqBase::OnAdd(event);
}
void wxZRColaTranslationSeq::OnRemove(wxCommandEvent& event)
{
int idx = m_selected->GetSelection();
wxASSERT_MSG(idx != wxNOT_FOUND, wxT("no active translation selected"));
m_selected->Delete(idx);
wxZRColaTranslationSeqBase::OnRemove(event);
}
void wxZRColaTranslationSeq::OnSelectedChar(wxKeyEvent& event)
{
if (event.GetRawKeyCode() == VK_DELETE) {
int idx = m_selected->GetSelection();
if (idx != wxNOT_FOUND)
m_selected->Delete(idx);
}
wxZRColaTranslationSeqBase::OnSelectedChar(event);
}
void wxZRColaTranslationSeq::OnSelectedDClick(wxCommandEvent& event)
{
int idx = m_selected->GetSelection();
if (idx != wxNOT_FOUND)
m_selected->Delete(idx);
wxZRColaTranslationSeqBase::OnSelectedDClick(event);
}
void wxZRColaTranslationSeq::OnSelectedUp(wxCommandEvent& event)
{
int idx = m_selected->GetSelection();
wxASSERT_MSG(idx != wxNOT_FOUND && (unsigned int)idx > 0, wxT("no or first active translation selected"));
wxString label = m_selected->GetString(idx);
void *data = m_selected->GetClientData(idx);
m_selected->Delete(idx);
m_selected->Insert(label, idx - 1, data);
m_selected->Select(idx - 1);
wxZRColaTranslationSeqBase::OnSelectedUp(event);
}
void wxZRColaTranslationSeq::OnSelectedDown(wxCommandEvent& event)
{
int idx = m_selected->GetSelection();
wxASSERT_MSG(idx != wxNOT_FOUND && (unsigned int)idx < m_selected->GetCount() - 1, wxT("no or last active translation selected"));
wxString label = m_selected->GetString(idx);
void *data = m_selected->GetClientData(idx);
m_selected->Delete(idx);
m_selected->Insert(label, idx + 1, data);
m_selected->Select(idx + 1);
wxZRColaTranslationSeqBase::OnSelectedDown(event);
}
void wxZRColaTranslationSeq::OnApplyButtonClick(wxCommandEvent& event)
{
event.Skip();
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
m_transeq.clear();
for (unsigned int i = 0, n = m_selected->GetCount(); i < n; i++)
m_transeq.push_back(static_cast<ZRCola::transetid_t>((size_t)m_selected->GetClientData(i)));
// Notify source text something changed and should re-translate.
wxCommandEvent event2(wxEVT_COMMAND_TEXT_UPDATED);
app->m_mainWnd->m_panel->m_source->ProcessWindowEvent(event2);
}
void wxZRColaTranslationSeq::OnOKButtonClick(wxCommandEvent& event)
{
wxZRColaTranslationSeq::OnApplyButtonClick(event);
}
//////////////////////////////////////////////////////////////////////////
// wxPersistentZRColaTranslationSeq
//////////////////////////////////////////////////////////////////////////
const int wxPersistentZRColaTranslationSeq::s_guiLevel = 1;
wxPersistentZRColaTranslationSeq::wxPersistentZRColaTranslationSeq(wxZRColaTranslationSeq *wnd) : wxPersistentTLWEx(wnd)
{
}
void wxPersistentZRColaTranslationSeq::Save() const
{
SaveValue(wxT("guiLevel"), s_guiLevel);
wxPersistentTLWEx::Save();
auto wnd = static_cast<const wxZRColaTranslationSeq*>(GetWindow()); // dynamic_cast is not reliable as we are typically called late in the wxTopLevelWindowMSW destructor.
wxString str;
bool first = true;
for (auto s = wnd->m_transeq.cbegin(), s_end = wnd->m_transeq.cend(); s != s_end; ++s, first = false)
str += wxString::Format(first ? wxT("%u") : wxT("|%u"), *s);
SaveValue(wxT("transeq"), str);
}
bool wxPersistentZRColaTranslationSeq::Restore()
{
auto wnd = dynamic_cast<wxZRColaTranslationSeq*>(GetWindow());
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
wxString str;
if (RestoreValue(wxT("transeq"), &str)) {
std::vector<ZRCola::transetid_t> transet;
for (wxStringTokenizer tok(str, wxT("|")); tok.HasMoreTokens(); ) {
ZRCola::transetid_t val = (ZRCola::transetid_t)_tcstoul(tok.GetNextToken().c_str(), NULL, 10);
for (size_t i = 0, n = app->m_ts_db.idxTranSet.size(); i < n; i++) {
const ZRCola::transet_db::transet &cg = app->m_ts_db.idxTranSet[i];
if (cg.set == val) {
transet.push_back(val);
break;
}
}
}
if (!transet.empty())
wnd->m_transeq = std::move(transet);
}
int guiLevel;
return RestoreValue(wxT("guiLevel"), &guiLevel) && guiLevel == s_guiLevel ? wxPersistentTLWEx::Restore() : true;
}

73
ZRCola/zrcolatranseq.h Normal file
View File

@@ -0,0 +1,73 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
///
/// Forward declarations
///
class wxZRColaTranslationSeq;
class wxPersistentZRColaTranslationSeq;
#pragma once
#include <wxex/common.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include "zrcolagui.h"
#pragma warning(pop)
#include <zrcola/translate.h>
#include <wxex/persist/toplevel.h>
#include <vector>
///
/// Configuration dialog
///
class wxZRColaTranslationSeq : public wxZRColaTranslationSeqBase
{
public:
wxZRColaTranslationSeq(wxWindow* parent);
friend class wxPersistentZRColaTranslationSeq; // Allow saving/restoring window state.
protected:
virtual void OnInitDialog(wxInitDialogEvent& event);
virtual void OnUpdate(wxUpdateUIEvent& event);
virtual void OnAvailableChar(wxKeyEvent& event);
virtual void OnAvailableDClick(wxCommandEvent& event);
virtual void OnAdd(wxCommandEvent& event);
virtual void OnRemove(wxCommandEvent& event);
virtual void OnSelectedChar(wxKeyEvent& event);
virtual void OnSelectedDClick(wxCommandEvent& event);
virtual void OnSelectedUp(wxCommandEvent& event);
virtual void OnSelectedDown(wxCommandEvent& event);
virtual void OnApplyButtonClick(wxCommandEvent& event);
virtual void OnOKButtonClick(wxCommandEvent& event);
public:
std::vector<ZRCola::transetid_t> m_transeq; ///< Custom translation set sequence
};
///
/// Supports saving/restoring wxZRColaTranslationSeq state
///
class wxPersistentZRColaTranslationSeq : public wxPersistentTLWEx
{
public:
wxPersistentZRColaTranslationSeq(wxZRColaTranslationSeq *wnd);
virtual void Save() const;
virtual bool Restore();
protected:
static const int s_guiLevel; ///< Persisted placements/sizing are considered incompatible between different GUI levels
};
inline wxPersistentObject *wxCreatePersistentObject(wxZRColaTranslationSeq *wnd)
{
return new wxPersistentZRColaTranslationSeq(wnd);
}

View File

@@ -1,23 +1,9 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#include "stdafx.h"
#include "pch.h"
//////////////////////////////////////////////////////////////////////////
@@ -41,6 +27,7 @@ wxZRColaUpdater::wxZRColaUpdater(wxWindow* parent) :
// Prepare Updater.
auto app = dynamic_cast<ZRColaApp*>(wxTheApp);
#pragma warning(suppress: 26812) // wxLanguage is unscoped.
m_updater = new wxUpdCheckThread(app->m_lang_ui == wxLANGUAGE_DEFAULT ? wxT("en_US") : wxLocale::GetLanguageCanonicalName(app->m_lang_ui), this);
//if (m_updater->Run() != wxTHREAD_NO_ERROR) {
// wxFAIL_MSG(wxT("Can't create the thread!"));
@@ -80,7 +67,7 @@ wxZRColaUpdater::~wxZRColaUpdater()
void wxZRColaUpdater::OnIdle(wxIdleEvent& event)
{
if (!m_finished) {
m_buttonUpdate->Enable(m_updater->CheckForUpdate() == wxUpdCheckThread::wxUpdUpdateAvailable);
m_buttonUpdate->Enable(m_updater->CheckForUpdate() == wxUpdCheckThread::wxResult::UpdateAvailable);
m_finished = true;
}
}

View File

@@ -1,20 +1,6 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
///
@@ -25,11 +11,16 @@ class wxZRColaUpdater;
#pragma once
#include <wxex/common.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include "zrcolagui.h"
#pragma warning(pop)
#include <Updater/chkthread.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include <wx/log.h>
#pragma warning(pop)
///

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>..\output\$(Platform).$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\lib\wxExtend\include;..\lib\WinStd\include;..\lib\stdex\include;..\lib\libZRCola\include;..\lib\libZRColaUI\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

Binary file not shown.

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -15,44 +15,49 @@
<RootNamespace>ZRColaCompile</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)'=='Debug'">
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)'=='Release'">
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\Win32.props" />
<Import Project="..\include\Debug.props" />
<Import Project="ZRColaCompile.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\Win32.props" />
<Import Project="..\include\Release.props" />
<Import Project="ZRColaCompile.props" />
<Import Project="..\include\$(Platform).props" />
<Import Project="..\include\$(Configuration).props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>..\output\$(Platform).$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>..\lib\wxExtend\include;..\lib\WinStd\include;..\lib\stdex\include;..\lib\libZRCola\include;..\lib\libZRColaUI\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="dbsource.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<ClCompile Include="parse.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="dbsource.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="parse.h" />
<ClInclude Include="pch.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\lib\libZRColaUI\build\libZRColaUI.vcxproj">
@@ -61,11 +66,11 @@
<ProjectReference Include="..\lib\libZRCola\build\libZRCola.vcxproj">
<Project>{3c61929e-7289-4101-8d0a-da22d6e1aea8}</Project>
</ProjectReference>
<ProjectReference Include="..\lib\WinStd\build\WinStd-10.0.vcxproj">
<ProjectReference Include="..\lib\WinStd\build\WinStd.vcxproj">
<Project>{47399d91-7eb9-41de-b521-514ba5db0c43}</Project>
</ProjectReference>
<ProjectReference Include="..\lib\wxExtend\build\wxExtendDll-10.0.vcxproj">
<Project>{a3a36689-ac35-4026-93da-a3ba0c0e767c}</Project>
<ProjectReference Include="..\lib\wxExtend\build\wxExtendLib.vcxproj">
<Project>{D3E29951-D9F5-486D-A167-20AE8E90B1FA}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>

View File

@@ -19,7 +19,7 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
@@ -28,14 +28,20 @@
<ClCompile Include="dbsource.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="parse.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="dbsource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="parse.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ZRColaCompile.rc">

View File

@@ -1,23 +1,9 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#include "stdafx.h"
#include "pch.h"
using namespace std;
using namespace stdex;
@@ -28,35 +14,19 @@ using namespace winstd;
// ZRCola::DBSource::character_bank
//////////////////////////////////////////////////////////////////////////
ZRCola::DBSource::character_bank::character_bank() : vector<unique_ptr<ZRCola::DBSource::character> >()
{
resize(0x10000);
}
void ZRCola::DBSource::character_bank::build_related()
{
// Initialize ignore list.
m_ignore.insert(L"letter");
m_ignore.insert(L"modifier");
m_ignore.insert(L"symbol");
m_ignore.insert(L"accent");
m_ignore.insert(L"with");
m_ignore.insert(L"and");
m_ignore.insert(L"capital");
m_ignore.insert(L"small");
m_ignore.insert(L"combining");
SYSTEM_INFO si;
GetSystemInfo(&si);
// Launch workers.
build_related_worker **workers = new build_related_worker*[si.dwNumberOfProcessors];
size_type from = 0, to;
for (DWORD i = 0; i < si.dwNumberOfProcessors; i++) {
to = MulDiv(i + 1, 0x10000, si.dwNumberOfProcessors);
workers[i] = new build_related_worker(this, from, to);
from = to;
size_type from = 0, total = size();
iterator chr_from = begin(), chr_to;
for (DWORD i = 0; i < si.dwNumberOfProcessors; i++, chr_from = chr_to) {
size_type to = MulDiv(i + 1, total, si.dwNumberOfProcessors);
for (chr_to = chr_from; from < to; from++, ++chr_to);
workers[i] = new build_related_worker(this, chr_from, chr_to);
}
// Wait for workers.
@@ -67,12 +37,12 @@ void ZRCola::DBSource::character_bank::build_related()
}
}
delete workers; // This line of code sounds horrible, I know.
delete [] workers; // This line of code sounds horrible, I know.
}
ZRCola::DBSource::character_bank::build_related_worker::build_related_worker(_In_ const character_bank *cb, _In_ size_type from, _In_ size_type to) :
win_handle((HANDLE)_beginthreadex(NULL, 0, process, this, CREATE_SUSPENDED, NULL)),
ZRCola::DBSource::character_bank::build_related_worker::build_related_worker(_In_ const character_bank *cb, _In_ iterator from, _In_ iterator to) :
win_handle<INVALID_HANDLE_VALUE>((HANDLE)_beginthreadex(NULL, 0, process, this, CREATE_SUSPENDED, NULL)),
m_heap(HeapCreate(0, 0, 0)),
m_cb(cb),
m_from(from),
@@ -86,40 +56,39 @@ ZRCola::DBSource::character_bank::build_related_worker::build_related_worker(_In
unsigned int ZRCola::DBSource::character_bank::build_related_worker::process()
{
heap_allocator<wchar_t> al(m_heap);
basic_string<wchar_t, char_traits<wchar_t>, heap_allocator<wchar_t> > rel(al);
vector<wchar_t, heap_allocator<wchar_t> > rel(al);
set<wstring, less<wstring>, heap_allocator<wstring> > matching(less<wstring>(), al);
for (size_type i = m_from; i < m_to; i++) {
auto &chr = *(m_cb->at(i).get());
if (&chr == NULL) continue;
for (auto c = m_from; c != m_to; c++) {
rel.clear();
// Remove all unexisting, inactive, or self related characters.
for (auto j = chr.rel.length(); j--;) {
wchar_t c = chr.rel[j];
if (m_cb->at(c) && (wchar_t)j != c)
rel += c;
// Skip all unexisting, or self related characters.
auto m_cb_end = m_cb->cend();
for (std::vector<wchar_t>::const_pointer c_rel = c->second.rel.data(), c_rel_end = c_rel + c->second.rel.size(), c_rel_next = c_rel_end; c_rel < c_rel_end; c_rel = c_rel_next) {
c_rel_next = c_rel + wcsnlen(c_rel, c_rel_end - c_rel) + 1;
if (m_cb->find(c_rel) != m_cb_end && c->first.compare(c_rel) != 0)
rel.insert(rel.end(), c_rel, c_rel_next);
}
// Add all characters that share enought keywords.
for (size_type j = 0, j_end = m_cb->size(); j < j_end; j++) {
if (i == j || rel.find((wchar_t)j) != wstring::npos)
// Add all characters that share enough keywords.
for (auto c2 = m_cb->cbegin(), c2_end = m_cb->cend(); c2 != c2_end; ++c2) {
if (c == c2)
continue;
const auto &chr2 = *(m_cb->at(j).get());
if (&chr2 == NULL)
bool already_present = false;
for (std::vector<wchar_t>::const_pointer c_rel = rel.data(), c_rel_end = c_rel + rel.size(), c_rel_next = c_rel_end; c_rel < c_rel_end; c_rel = c_rel_next) {
c_rel_next = c_rel + wcsnlen(c_rel, c_rel_end - c_rel) + 1;
if (c2->first.compare(c_rel) == 0) {
already_present = true;
break;
}
}
if (already_present)
continue;
set<wstring>::size_type comparisons = 0;
matching.clear();
for (auto term = chr.terms.cbegin(), term_end = chr.terms.cend(); term != term_end; ++term) {
// Test for ignored word(s).
if (m_cb->m_ignore.find(*term) != m_cb->m_ignore.cend())
continue;
for (auto term2 = chr2.terms.cbegin(), term2_end = chr2.terms.cend(); term2 != term2_end; ++term2) {
// Test for ignored word(s).
if (m_cb->m_ignore.find(*term2) != m_cb->m_ignore.cend())
continue;
for (auto term = c->second.terms_rel.cbegin(), term_end = c->second.terms_rel.cend(); term != term_end; ++term) {
for (auto term2 = c2->second.terms_rel.cbegin(), term2_end = c2->second.terms_rel.cend(); term2 != term2_end; ++term2) {
comparisons++;
if (*term == *term2)
matching.insert(*term);
@@ -130,11 +99,11 @@ unsigned int ZRCola::DBSource::character_bank::build_related_worker::process()
// If 1/2 terms match, assume related.
auto hits = matching.size();
if (hits*hits*2 >= comparisons)
rel += chr2.chr;
rel.insert(rel.end(), c2->first.data(), c2->first.data() + c2->first.length() + 1);
}
}
chr.rel.assign(rel.c_str(), rel.length());
c->second.rel.assign(rel.cbegin(), rel.cend());
}
return 0;
@@ -151,7 +120,7 @@ unsigned int __stdcall ZRCola::DBSource::character_bank::build_related_worker::p
// ZRCola::DBSource::character_desc_idx
//////////////////////////////////////////////////////////////////////////
void ZRCola::DBSource::character_desc_idx::parse_keywords(const wchar_t *str, set<wstring> &terms)
void ZRCola::DBSource::character_desc_idx::parse_keywords(_In_ const wchar_t *str, _Inout_ set<wstring> &terms)
{
wxASSERT_MSG(str, wxT("string is NULL"));
@@ -197,7 +166,7 @@ void ZRCola::DBSource::character_desc_idx::parse_keywords(const wchar_t *str, se
}
void ZRCola::DBSource::character_desc_idx::add_keywords(const set<wstring> &terms, wchar_t chr, size_t sub)
void ZRCola::DBSource::character_desc_idx::add_keywords(const set<wstring> &terms, const wstring &chr, size_t sub)
{
for (auto term = terms.cbegin(), term_end = terms.cend(); term != term_end; ++term) {
if (sub) {
@@ -248,14 +217,29 @@ void ZRCola::DBSource::character_desc_idx::save(ZRCola::textindex<wchar_t, wchar
// ZRCola::DBSource
//////////////////////////////////////////////////////////////////////////
ZRCola::DBSource::DBSource()
ZRCola::DBSource::DBSource() :
m_locale(nullptr)
{
// Initialize ignore list.
m_terms_ignore.insert(L"letter");
m_terms_ignore.insert(L"modifier");
m_terms_ignore.insert(L"symbol");
m_terms_ignore.insert(L"accent");
m_terms_ignore.insert(L"with");
m_terms_ignore.insert(L"and");
m_terms_ignore.insert(L"capital");
m_terms_ignore.insert(L"small");
m_terms_ignore.insert(L"combining");
}
ZRCola::DBSource::~DBSource()
{
// Manually release all COM objects related to the database before we close the database.
m_pTranslationSets1.free();
m_comTranslationSets.free();
m_pTranslation1.free();
m_comTranslation.free();
m_pCharacterGroup1.free();
m_comCharacterGroup.free();
@@ -280,19 +264,25 @@ bool ZRCola::DBSource::Open(LPCTSTR filename)
cn += L"Dbq=";
cn += filename;
cn += L";Uid=;Pwd=;";
#pragma warning(push)
#pragma warning(disable: 6387) // Connection15::Open() declaration is wrong: it defaults username and password parameters to NULL, but annotates them as required non-NULL.
hr = m_db->Open(bstr(cn.c_str()));
#pragma warning(pop)
if (SUCCEEDED(hr)) {
// Database open and ready.
m_filename = filename;
m_locale = _create_locale(LC_ALL, "Slovenian_Slovenia.1250");
wxASSERT_MSG(!m_comCharacterGroup, wxT("ADO command already created"));
// Create ADO command(s).
wxASSERT_MSG(!m_comCharacterGroup, wxT("ADO command already created"));
wxVERIFY(SUCCEEDED(::CoCreateInstance(CLSID_CADOCommand, NULL, CLSCTX_ALL, IID_IADOCommand, (LPVOID*)&m_comCharacterGroup)));
wxVERIFY(SUCCEEDED(m_comCharacterGroup->put_ActiveConnection(variant(m_db))));
wxVERIFY(SUCCEEDED(m_comCharacterGroup->put_CommandType(adCmdText)));
wxVERIFY(SUCCEEDED(m_comCharacterGroup->put_CommandText(bstr(L"SELECT [VRS_SkupineZnakov].[Znak], [VRS_SkupineZnakov].[pogost] FROM [VRS_SkupineZnakov] LEFT JOIN [VRS_CharList] ON [VRS_SkupineZnakov].[Znak]=[VRS_CharList].[znak] WHERE [VRS_CharList].[aktiven]=1 AND [VRS_SkupineZnakov].[Skupina]=? ORDER BY [VRS_SkupineZnakov].[Rang] ASC, [VRS_SkupineZnakov].[Znak] ASC"))));
wxVERIFY(SUCCEEDED(m_comCharacterGroup->put_CommandText(bstr(L"SELECT [VRS_SkupineZnakov].[Znak], [VRS_SkupineZnakov].[pogost] "
L"FROM [VRS_SkupineZnakov] "
L"LEFT JOIN [VRS_CharList] ON [VRS_SkupineZnakov].[Znak]=[VRS_CharList].[znak] "
L"WHERE [VRS_CharList].[aktiven]=1 AND [VRS_SkupineZnakov].[Skupina]=? "
L"ORDER BY [VRS_SkupineZnakov].[Rang] ASC, [VRS_SkupineZnakov].[Znak] ASC"))));
{
// Create and add command parameters.
com_obj<ADOParameters> params;
@@ -302,6 +292,40 @@ bool ZRCola::DBSource::Open(LPCTSTR filename)
wxVERIFY(SUCCEEDED(params->Append(m_pCharacterGroup1)));
}
wxASSERT_MSG(!m_comTranslation, wxT("ADO command already created"));
wxVERIFY(SUCCEEDED(::CoCreateInstance(CLSID_CADOCommand, NULL, CLSCTX_ALL, IID_IADOCommand, (LPVOID*)&m_comTranslation)));
wxVERIFY(SUCCEEDED(m_comTranslation->put_ActiveConnection(variant(m_db))));
wxVERIFY(SUCCEEDED(m_comTranslation->put_CommandType(adCmdText)));
wxVERIFY(SUCCEEDED(m_comTranslation->put_CommandText(bstr(L"SELECT [Komb1] AS [komb], [rang_komb1] AS [rang_komb], '' AS [Kano], 0 AS [Kanoniziraj], [Komb2] AS [znak], [rang_komb2] AS [rang_znak] "
L"FROM [VRS_ScriptRepl2] "
L"WHERE [Script]=? "
L"ORDER BY [Komb2], [rang_komb2], [rang_komb1], [Komb1]"))));
{
// Create and add command parameters.
com_obj<ADOParameters> params;
wxVERIFY(SUCCEEDED(m_comTranslation->get_Parameters(&params)));
wxASSERT_MSG(!m_pTranslation1, wxT("ADO command parameter already created"));
wxVERIFY(SUCCEEDED(m_comTranslation->CreateParameter(bstr(L"@Script"), adInteger, adParamInput, 0, variant(DISP_E_PARAMNOTFOUND, VT_ERROR), &m_pTranslation1)));
wxVERIFY(SUCCEEDED(params->Append(m_pTranslation1)));
}
wxASSERT_MSG(!m_comTranslationSets, wxT("ADO command already created"));
wxVERIFY(SUCCEEDED(::CoCreateInstance(CLSID_CADOCommand, NULL, CLSCTX_ALL, IID_IADOCommand, (LPVOID*)&m_comTranslationSets)));
wxVERIFY(SUCCEEDED(m_comTranslationSets->put_ActiveConnection(variant(m_db))));
wxVERIFY(SUCCEEDED(m_comTranslationSets->put_CommandType(adCmdText)));
wxVERIFY(SUCCEEDED(m_comTranslationSets->put_CommandText(bstr(L"SELECT [Script] "
L"FROM [VRS_Script2SeqScr] "
L"WHERE [ID]=? "
L"ORDER BY [Rank] ASC"))));
{
// Create and add command parameters.
com_obj<ADOParameters> params;
wxVERIFY(SUCCEEDED(m_comTranslationSets->get_Parameters(&params)));
wxASSERT_MSG(!m_pTranslationSets1, wxT("ADO command parameter already created"));
wxVERIFY(SUCCEEDED(m_comTranslationSets->CreateParameter(bstr(L"@ID"), adInteger, adParamInput, 0, variant(DISP_E_PARAMNOTFOUND, VT_ERROR), &m_pTranslationSets1)));
wxVERIFY(SUCCEEDED(params->Append(m_pTranslationSets1)));
}
return true;
} else {
_ftprintf(stderr, wxT("%s: error ZCC0011: Could not open database (0x%x).\n"), (LPCTSTR)filename, hr);
@@ -376,6 +400,23 @@ bool ZRCola::DBSource::GetValue(const com_obj<ADOField>& f, int& val) const
}
bool ZRCola::DBSource::GetValue(const com_obj<ADOField>& f, string& val) const
{
wxASSERT_MSG(f, wxT("field is empty"));
variant v;
wxVERIFY(SUCCEEDED(f->get_Value(&v)));
if (V_VT(&v) != VT_NULL) {
wxCHECK(SUCCEEDED(v.change_type(VT_BSTR)), false);
WideCharToMultiByte(CP_ACP, 0, V_BSTR(&v), ::SysStringLen(V_BSTR(&v)), val, NULL, NULL);
} else
val.clear();
return true;
}
bool ZRCola::DBSource::GetValue(const com_obj<ADOField>& f, wstring& val) const
{
wxASSERT_MSG(f, wxT("field is empty"));
@@ -434,35 +475,73 @@ bool ZRCola::DBSource::GetUnicodeString(const com_obj<ADOField>& f, wstring& str
variant v;
wxVERIFY(SUCCEEDED(f->get_Value(&v)));
wxCHECK(SUCCEEDED(v.change_type(VT_BSTR)), false);
// Parse the field. Must be "xxxx+xxxx+xxxx..." sequence.
str.clear();
for (UINT i = 0, n = ::SysStringLen(V_BSTR(&v)); i < n && V_BSTR(&v)[i];) {
// Parse Unicode code.
UINT j = 0;
wchar_t c = 0;
for (; i < n && V_BSTR(&v)[i]; i++, j++) {
if (L'0' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'9') c = c*0x10 + (V_BSTR(&v)[i] - L'0');
else if (L'A' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'F') c = c*0x10 + (V_BSTR(&v)[i] - L'A' + 10);
else if (L'a' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'f') c = c*0x10 + (V_BSTR(&v)[i] - L'a' + 10);
else break;
}
if (j <= 0 || 4 < j) {
bstr 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"), m_filename.c_str(), fieldname.length(), (BSTR)fieldname, n, V_BSTR(&v));
return false;
}
str += c;
if (V_VT(&v) != VT_NULL) {
wxCHECK(SUCCEEDED(v.change_type(VT_BSTR)), false);
// 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++);
// Parse the field. Must be "xxxx+xxxx+xxxx..." sequence.
for (UINT i = 0, n = ::SysStringLen(V_BSTR(&v)); i < n && V_BSTR(&v)[i];) {
// Parse Unicode code.
UINT j = 0;
wchar_t c = 0;
for (; i < n && V_BSTR(&v)[i]; i++, j++) {
if (L'0' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'9') c = c*0x10 + (V_BSTR(&v)[i] - L'0');
else if (L'A' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'F') c = c*0x10 + (V_BSTR(&v)[i] - L'A' + 10);
else if (L'a' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'f') c = c*0x10 + (V_BSTR(&v)[i] - L'a' + 10);
else break;
}
if (j <= 0 || 4 < j) {
bstr 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"), m_filename.c_str(), fieldname.length(), (BSTR)fieldname, n, V_BSTR(&v));
return false;
}
str += c;
// 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;
}
bool ZRCola::DBSource::GetNormPerm(const winstd::com_obj<ADOField>& f, normperm& np) const
{
wxASSERT_MSG(f, wxT("field is empty"));
variant v;
wxVERIFY(SUCCEEDED(f->get_Value(&v)));
np.clear();
if (V_VT(&v) != VT_NULL) {
wxCHECK(SUCCEEDED(v.change_type(VT_BSTR)), false);
// Parse the field. Must be "nnnn,nnnn,nnnn..." sequence.
for (UINT i = 0, n = ::SysStringLen(V_BSTR(&v)); i < n && V_BSTR(&v)[i];) {
// Parse Unicode code.
UINT j = 0;
std::vector<size_t> p;
for (; i < n && V_BSTR(&v)[i]; i++, j++) {
if (L'0' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'9') p.push_back(V_BSTR(&v)[i] - L'0');
else break;
}
if (j <= 0) {
bstr fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
_ftprintf(stderr, wxT("%s: error ZCC0150: Syntax error in \"%.*ls\" field (\"%.*ls\"). Permutation sequence must be at least one decimal digit long.\n"), m_filename.c_str(), fieldname.length(), (BSTR)fieldname, n, V_BSTR(&v));
return false;
}
np.insert(std::move(p));
// 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;
}
bool ZRCola::DBSource::GetLanguage(const com_obj<ADOField>& f, ZRCola::langid_t& lang) const
{
wxASSERT_MSG(f, wxT("field is empty"));
@@ -549,7 +628,7 @@ bool ZRCola::DBSource::GetTagNames(const winstd::com_obj<ADOField>& f, LCID lcid
// Parse the field. Must be "name, name, name..." sequence.
names.clear();
for (UINT i = 0, n = ::SysStringLen(V_BSTR(&v)); i < n && V_BSTR(&v)[i];) {
for (UINT i = 0, i_end = ::SysStringLen(V_BSTR(&v)); i < i_end && V_BSTR(&v)[i];) {
if (iswspace(V_BSTR(&v)[i])) {
// Skip leading white space.
i++; continue;
@@ -557,7 +636,7 @@ bool ZRCola::DBSource::GetTagNames(const winstd::com_obj<ADOField>& f, LCID lcid
// Parse name.
UINT j = i, j_end = i;
for (; i < n && V_BSTR(&v)[i]; i++) {
for (; i < i_end && V_BSTR(&v)[i]; i++) {
if (V_BSTR(&v)[i] == L',' || V_BSTR(&v)[i] == L';') {
// Delimiter found.
i++; break;
@@ -583,6 +662,59 @@ bool ZRCola::DBSource::GetTagNames(const winstd::com_obj<ADOField>& f, LCID lcid
}
bool ZRCola::DBSource::SelectNormPermSets(winstd::com_obj<ADORecordset>& rs) const
{
// Create a new recordset.
rs.free();
wxCHECK(SUCCEEDED(::CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_ALL, IID_IADORecordset, (LPVOID*)&rs)), false);
// Open it.
if (FAILED(rs->Open(variant(
L"SELECT [oblika], [oblike] "
L"FROM [VRS_CharCanoOblike] "
L"ORDER BY [oblika], [oblike]"), variant(m_db), adOpenStatic, adLockReadOnly, adCmdText)))
{
_ftprintf(stderr, wxT("%s: error ZCC0160: Error loading normalization permutation sets from database. Please make sure the file is ZRCola.zrc compatible.\n"), m_filename.c_str());
LogErrors();
return false;
}
return true;
}
bool ZRCola::DBSource::GetNormPerm(const winstd::com_obj<ADORecordset>& rs, std::string& norm, normperm& np) const
{
wxASSERT_MSG(rs, wxT("recordset is empty"));
com_obj<ADOFields> flds;
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"oblika"), &f)));
wxCHECK(GetValue(f, norm), false);
}
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"oblike"), &f)));
wxCHECK(GetNormPerm(f, np), false);
}
// Verify all lengths match.
size_t n = norm.length();
for (auto p = np.cbegin(), p_end = np.cend(); p != p_end; ++p) {
if (p->size() != n) {
_ftprintf(stderr, wxT("%s: error ZCC0170: Inconsistent normalization sequence \"%.*hs\" permutation length. Please make sure all permutation lengths match normalization sequence length (%u).\n"), m_filename.c_str(), n, norm.c_str(), n);
return false;
}
}
return true;
}
bool ZRCola::DBSource::SelectTranslations(com_obj<ADORecordset> &rs) const
{
// Create a new recordset.
@@ -591,12 +723,33 @@ bool ZRCola::DBSource::SelectTranslations(com_obj<ADORecordset> &rs) const
// Open it.
if (FAILED(rs->Open(variant(
L"SELECT [komb], [znak], [rang_znak] "
L"SELECT [komb], [rang_komb], [Kano], [Kanoniziraj], [znak], [rang_znak] "
L"FROM [VRS_ReplChar] "
L"WHERE [rang_komb]=1 "
L"ORDER BY [znak], [rang_znak], [komb]"), variant(m_db), adOpenStatic, adLockReadOnly, adCmdText)))
L"ORDER BY [znak], [rang_znak], [rang_komb], [komb]"), variant(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"), m_filename.c_str());
_ftprintf(stderr, wxT("%s: error ZCC0040: Error loading translations from database. Please make sure the file is ZRCola.zrc compatible.\n"), m_filename.c_str());
LogErrors();
return false;
}
return true;
}
bool ZRCola::DBSource::SelectTranslations(int set, winstd::com_obj<ADORecordset>& rs) const
{
// Create a new recordset.
rs.free();
wxVERIFY(SUCCEEDED(::CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_ALL, IID_IADORecordset, (LPVOID*)&rs)));
wxVERIFY(SUCCEEDED(rs->put_CursorLocation(adUseClient)));
wxVERIFY(SUCCEEDED(rs->put_CursorType(adOpenForwardOnly)));
wxVERIFY(SUCCEEDED(rs->put_LockType(adLockReadOnly)));
// Open it.
wxVERIFY(SUCCEEDED(m_pTranslation1->put_Value(variant(set))));
if (FAILED(rs->Open(variant(m_comTranslation), variant(DISP_E_PARAMNOTFOUND, VT_ERROR)))) {
_ftprintf(stderr, wxT("%s: error ZCC0100: Error loading translations from database. Please make sure the file is ZRCola.zrc compatible.\n"), m_filename.c_str());
LogErrors();
return false;
}
@@ -615,19 +768,165 @@ bool ZRCola::DBSource::GetTranslation(const com_obj<ADORecordset>& rs, ZRCola::D
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"komb"), &f)));
wxCHECK(GetUnicodeString(f, t.decomp.str), false);
wxCHECK(GetUnicodeString(f, t.src.str), false);
}
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"znak"), &f)));
wxCHECK(GetUnicodeCharacter(f, t.chr), false);
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"rang_komb"), &f)));
wxCHECK(GetValue(f, t.src.rank), false);
}
{
bool norm;
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"Kanoniziraj"), &f)));
wxCHECK(GetValue(f, norm), false);
if (norm) {
com_obj<ADOField> f2;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"Kano"), &f2)));
wxCHECK(GetValue(f2, t.norm), false);
} else
t.norm.clear();
}
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"rang_znak"), &f)));
wxCHECK(GetValue(f, t.decomp.rank), false);
wxCHECK(GetValue(f, t.dst.rank), false);
}
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"znak"), &f)));
wxCHECK(GetUnicodeString(f, t.dst.str), false);
}
return true;
}
bool ZRCola::DBSource::SelectTranlationSets(com_obj<ADORecordset> &rs) const
{
// Create a new recordset.
rs.free();
wxCHECK(SUCCEEDED(::CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_ALL, IID_IADORecordset, (LPVOID*)&rs)), false);
// Open it.
if (FAILED(rs->Open(variant(
L"SELECT DISTINCT [entCode], [Src_En], [Dst_En] "
L"FROM [VRS_Script2] "
L"ORDER BY [entCode], [Src_En], [Dst_En]"), variant(m_db), adOpenStatic, adLockReadOnly, adCmdText)))
{
_ftprintf(stderr, wxT("%s: error ZCC0060: Error loading translation sets from database. Please make sure the file is ZRCola.zrc compatible.\n"), m_filename.c_str());
LogErrors();
return false;
}
return true;
}
bool ZRCola::DBSource::GetTranslationSet(const com_obj<ADORecordset>& rs, ZRCola::DBSource::transet& ts) const
{
wxASSERT_MSG(rs, wxT("recordset is empty"));
com_obj<ADOFields> flds;
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"entCode"), &f)));
wxCHECK(GetValue(f, ts.set), false);
}
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"Src_En"), &f)));
wxCHECK(GetValue(f, ts.src), false);
}
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"Dst_En"), &f)));
wxCHECK(GetValue(f, ts.dst), false);
}
return true;
}
bool ZRCola::DBSource::SelectTranlationSeqs(com_obj<ADORecordset> &rs) const
{
// Create a new recordset.
rs.free();
wxCHECK(SUCCEEDED(::CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_ALL, IID_IADORecordset, (LPVOID*)&rs)), false);
// Open it.
if (FAILED(rs->Open(variant(
L"SELECT DISTINCT [ID], [Descr], [Rank] "
L"FROM [VRS_Script2Seq] "
L"ORDER BY [Rank], [Descr]"), variant(m_db), adOpenStatic, adLockReadOnly, adCmdText)))
{
_ftprintf(stderr, wxT("%s: error ZCC0060: Error loading translation 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::GetTranslationSeq(const com_obj<ADORecordset>& rs, ZRCola::DBSource::transeq& ts) const
{
wxASSERT_MSG(rs, wxT("recordset is empty"));
com_obj<ADOFields> flds;
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"ID"), &f)));
wxCHECK(GetValue(f, ts.seq), false);
}
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"Rank"), &f)));
wxCHECK(GetValue(f, ts.rank), false);
}
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"Descr"), &f)));
wxCHECK(GetValue(f, ts.name), false);
}
// Read translation sequence sets from database.
wxVERIFY(SUCCEEDED(m_pTranslationSets1->put_Value(variant(ts.seq))));
com_obj<ADORecordset> rs_chars;
wxVERIFY(SUCCEEDED(::CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_ALL, IID_IADORecordset, (LPVOID*)&rs_chars)));
wxVERIFY(SUCCEEDED(rs_chars->put_CursorLocation(adUseClient)));
wxVERIFY(SUCCEEDED(rs_chars->put_CursorType(adOpenForwardOnly)));
wxVERIFY(SUCCEEDED(rs_chars->put_LockType(adLockReadOnly)));
if (FAILED(rs_chars->Open(variant(m_comTranslationSets), variant(DISP_E_PARAMNOTFOUND, VT_ERROR)))) {
_ftprintf(stderr, wxT("%s: error ZCC0140: Error loading character group characters from database. Please make sure the file is ZRCola.zrc compatible.\n"), m_filename.c_str());
LogErrors();
return false;
}
{
ts.sets.clear();
com_obj<ADOFields> flds2;
wxVERIFY(SUCCEEDED(rs_chars->get_Fields(&flds2)));
com_obj<ADOField> f_set;
wxVERIFY(SUCCEEDED(flds2->get_Item(variant(L"Script"), &f_set)));
size_t n = 0;
for (VARIANT_BOOL eof = VARIANT_TRUE; SUCCEEDED(rs_chars->get_EOF(&eof)) && !eof; rs_chars->MoveNext(), n++) {
int set;
wxCHECK(GetValue(f_set, set), false);
ts.sets.push_back(set);
}
}
return true;
@@ -665,7 +964,7 @@ bool ZRCola::DBSource::GetKeySequence(const com_obj<ADORecordset>& rs, ZRCola::D
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"Znak"), &f)));
wxCHECK(GetUnicodeCharacter(f, ks.chr), false);
wxCHECK(GetUnicodeString(f, ks.chr), false);
}
int modifiers;
@@ -700,18 +999,18 @@ bool ZRCola::DBSource::GetKeySequence(const com_obj<ADORecordset>& rs, ZRCola::D
if (keycode1) {
// First key in the sequence is complete.
keyseq::keycode kc1 = {
keyseq::keycode::translate_slen(keycode1),
keyseq::keycode::translate_slen(static_cast<wchar_t>(keycode1 & 0xffff)),
(modifiers & 0x100) != 0,
(modifiers & 0x200) != 0,
(modifiers & 0x400) != 0 };
ks.seq.push_back(kc1);
keyseq::keycode kc2 = { keyseq::keycode::translate_slen(keycode), shift };
keyseq::keycode kc2 = { keyseq::keycode::translate_slen(static_cast<wchar_t>(keycode & 0xffff)), shift };
ks.seq.push_back(kc2);
} else {
// First key in the sequence is only modifier(s).
keyseq::keycode kc1 = {
keyseq::keycode::translate_slen(keycode),
keyseq::keycode::translate_slen(static_cast<wchar_t>(keycode & 0xffff)),
shift || (modifiers & 0x100) != 0,
(modifiers & 0x200) != 0,
(modifiers & 0x400) != 0 };
@@ -753,7 +1052,7 @@ bool ZRCola::DBSource::GetLanguage(const com_obj<ADORecordset>& rs, ZRCola::DBSo
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"entCode"), &f)));
wxCHECK(GetLanguage(f, lang.id), false);
wxCHECK(GetLanguage(f, lang.lang), false);
}
{
@@ -797,7 +1096,7 @@ bool ZRCola::DBSource::GetLanguageCharacter(const com_obj<ADORecordset>& rs, ZRC
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"znak"), &f)));
wxCHECK(GetUnicodeCharacter(f, lc.chr), false);
wxCHECK(GetUnicodeString(f, lc.chr), false);
}
{
@@ -837,18 +1136,18 @@ bool ZRCola::DBSource::GetCharacterGroup(const com_obj<ADORecordset>& rs, chrgrp
com_obj<ADOFields> flds;
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
wstring id;
wstring grp;
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"id"), &f)));
wxCHECK(GetValue(f, cg.id), false);
wxCHECK(GetValue(f, cg.grp), false);
}
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"Skupina"), &f)));
wxCHECK(GetValue(f, id), false);
wxCHECK(GetValue(f, grp), false);
}
{
@@ -864,14 +1163,14 @@ bool ZRCola::DBSource::GetCharacterGroup(const com_obj<ADORecordset>& rs, chrgrp
}
// Read character list from database.
wxVERIFY(SUCCEEDED(m_pCharacterGroup1->put_Value(variant(id.c_str()))));
wxVERIFY(SUCCEEDED(m_pCharacterGroup1->put_Value(variant(grp.c_str()))));
com_obj<ADORecordset> rs_chars;
wxVERIFY(SUCCEEDED(::CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_ALL, IID_IADORecordset, (LPVOID*)&rs_chars)));
wxVERIFY(SUCCEEDED(rs_chars->put_CursorLocation(adUseClient)));
wxVERIFY(SUCCEEDED(rs_chars->put_CursorType(adOpenForwardOnly)));
wxVERIFY(SUCCEEDED(rs_chars->put_LockType(adLockReadOnly)));
if (FAILED(rs_chars->Open(variant(m_comCharacterGroup), variant(DISP_E_PARAMNOTFOUND, VT_ERROR)))) {
_ftprintf(stderr, wxT("%s: error ZCC0100: Error loading character group characters from database. Please make sure the file is ZRCola.zrc compatible.\n"), m_filename.c_str());
_ftprintf(stderr, wxT("%s: error ZCC0140: Error loading character group characters from database. Please make sure the file is ZRCola.zrc compatible.\n"), m_filename.c_str());
LogErrors();
return false;
}
@@ -879,16 +1178,16 @@ bool ZRCola::DBSource::GetCharacterGroup(const com_obj<ADORecordset>& rs, chrgrp
{
cg.chars.clear();
cg.show.clear();
com_obj<ADOFields> flds;
wxVERIFY(SUCCEEDED(rs_chars->get_Fields(&flds)));
com_obj<ADOFields> flds2;
wxVERIFY(SUCCEEDED(rs_chars->get_Fields(&flds2)));
com_obj<ADOField> f_char, f_show;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"Znak" ), &f_char)));
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"pogost"), &f_show)));
for (VARIANT_BOOL eof = VARIANT_TRUE; SUCCEEDED(rs_chars->get_EOF(&eof)) && !eof; rs_chars->MoveNext()) {
wchar_t c;
wxCHECK(GetUnicodeCharacter(f_char, c), false);
size_t n = cg.chars.length();
cg.chars += c;
wxVERIFY(SUCCEEDED(flds2->get_Item(variant(L"Znak" ), &f_char)));
wxVERIFY(SUCCEEDED(flds2->get_Item(variant(L"pogost"), &f_show)));
size_t n = 0;
for (VARIANT_BOOL eof = VARIANT_TRUE; SUCCEEDED(rs_chars->get_EOF(&eof)) && !eof; rs_chars->MoveNext(), n++) {
wstring c;
wxCHECK(GetUnicodeString(f_char, c), false);
cg.chars.insert(cg.chars.end(), c.data(), c.data() + c.length() + 1);
bool show;
wxCHECK(GetValue(f_show, show), false);
if ((n % 16) == 0)
@@ -932,42 +1231,49 @@ bool ZRCola::DBSource::GetCharacter(const com_obj<ADORecordset>& rs, character&
com_obj<ADOFields> flds;
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
wchar_t c;
chr.rel.clear();
wstring c;
chr.second.terms.clear();
chr.second.terms_rel.clear();
chr.second.rel.clear();
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"znak"), &f)));
wxCHECK(GetUnicodeCharacter(f, chr.chr), false);
wxCHECK(GetUnicodeString(f, chr.first), false);
}
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"znak_v"), &f)));
wxCHECK(GetUnicodeCharacter(f, c), false);
if (c && c != chr.chr)
chr.rel += c;
wxCHECK(GetUnicodeString(f, c), false);
if (!c.empty() && c != chr.first)
chr.second.rel.insert(chr.second.rel.end(), c.data(), c.data() + c.length() + 1);
}
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"znak_m"), &f)));
wxCHECK(GetUnicodeCharacter(f, c), false);
if (c && c != chr.chr)
chr.rel += c;
wxCHECK(GetUnicodeString(f, c), false);
if (!c.empty() && c != chr.first)
chr.second.rel.insert(chr.second.rel.end(), c.data(), c.data() + c.length() + 1);
}
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"opis_en"), &f)));
wxCHECK(GetValue(f, chr.desc), false);
wxCHECK(GetValue(f, chr.second.desc), false);
ZRCola::DBSource::character_desc_idx::parse_keywords(chr.second.desc.c_str(), chr.second.terms);
for (auto term = chr.second.terms.cbegin(), term_end = chr.second.terms.cend(); term != term_end; ++term) {
if (m_terms_ignore.find(*term) != m_terms_ignore.cend())
continue;
chr.second.terms_rel.insert(*term);
}
}
ZRCola::DBSource::character_desc_idx::parse_keywords(chr.desc.c_str(), chr.terms);
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"kat"), &f)));
wxCHECK(GetChrCat(f, chr.cat), false);
wxCHECK(GetChrCat(f, chr.second.cat), false);
}
return true;
@@ -1002,12 +1308,11 @@ bool ZRCola::DBSource::GetCharacterCategory(const com_obj<ADORecordset>& rs, chr
com_obj<ADOFields> flds;
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
wstring id;
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"kat"), &f)));
wxCHECK(GetChrCat(f, cc.id), false);
wxCHECK(GetChrCat(f, cc.cat), false);
}
{
@@ -1053,12 +1358,11 @@ bool ZRCola::DBSource::GetCharacterTag(const winstd::com_obj<ADORecordset>& rs,
com_obj<ADOFields> flds;
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
wstring id;
{
com_obj<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(variant(L"znak"), &f)));
wxCHECK(GetUnicodeCharacter(f, ct.chr), false);
wxCHECK(GetUnicodeString(f, ct.chr), false);
}
{
@@ -1098,7 +1402,6 @@ bool ZRCola::DBSource::GetTagName(const winstd::com_obj<ADORecordset>& rs, tagna
com_obj<ADOFields> flds;
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
wstring id;
tn.names.clear();
{

View File

@@ -1,31 +1,32 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#pragma once
#include <zrcola/character.h>
#include <zrcola/common.h>
#include <zrcola/language.h>
#include <zrcola/tag.h>
#include <zrcola/translate.h>
#include <zrcolaui/chargroup.h>
#include <zrcolaui/keyboard.h>
#include <WinStd/COM.h>
#include <WinStd/Win.h>
#include <wxex/common.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include <wx/debug.h>
#pragma warning(pop)
#pragma warning(push)
#pragma warning(disable: 4091)
#include <adoint.h>
#pragma warning(pop)
#include <list>
#include <map>
#include <memory>
@@ -49,7 +50,8 @@ namespace ZRCola {
int rank; ///< Sequence rank
std::wstring str; ///< Sequence string
inline charseq()
inline charseq() :
rank(0)
{
}
@@ -59,18 +61,50 @@ namespace ZRCola {
{
}
///
/// Functor to compare two sequences by `rank`, and `str` members respectively
///
struct less_rank_str {
inline bool operator()(_In_ const charseq& a, _In_ const charseq& b) const
{
if (a.rank < b.rank) return true;
else if (a.rank > b.rank) return false;
else if (a.str < b.str ) return true;
else return false;
}
};
inline charseq(_In_ int _rank, _In_ const std::wstring &_str) :
rank(_rank),
str (_str)
{
}
inline charseq(_In_ int _rank, _Inout_ std::wstring &&_str) :
rank(_rank),
str (std::move(_str))
{
}
inline bool operator==(_In_ const charseq &other) const
{
return rank == other.rank && str == other.str;
}
inline bool operator!=(_In_ const charseq &other) const
{
return !operator==(other);
}
inline bool operator<(_In_ const charseq &other) const
{
if (rank < other.rank) return true;
else if (rank > other.rank) return false;
else if (str < other.str ) return true;
else return false;
}
inline bool operator<=(_In_ const charseq &other) const
{
return !operator>(other);
}
inline bool operator>(_In_ const charseq &other) const
{
return other.operator<(*this);
}
inline bool operator>=(_In_ const charseq &other) const
{
return !operator<(other);
}
};
@@ -79,11 +113,51 @@ namespace ZRCola {
///
class translation {
public:
wchar_t chr; ///< Composed character
charseq decomp; ///< Decomposed sequence
int set; ///< Translation set ID
charseq src; ///< Source sequence
std::string norm; ///< Normalization footprint
charseq dst; ///< Destination sequence
inline translation() : set((int)ZRCOLA_TRANSEQID_DEFAULT) {}
};
///
/// Translation set
///
class transet {
public:
int set; ///< ID
std::wstring src; ///< Source name
std::wstring dst; ///< Destination name
inline transet() : set((int)ZRCOLA_TRANSEQID_DEFAULT) {}
};
///
/// Translation sequence
///
class transeq {
public:
int seq; ///< ID
int rank; ///< Rank
std::wstring name; ///< Name
std::vector<int> sets; ///< Sets
inline transeq() :
seq(0),
rank(0)
{}
};
///
/// Normalization permutation set
///
typedef std::set<std::vector<size_t> > normperm;
///
/// Key sequence
///
@@ -114,7 +188,7 @@ namespace ZRCola {
};
public:
wchar_t chr; ///< Character
std::wstring chr; ///< Character
std::vector<keycode> seq; ///< Key sequence
};
@@ -124,8 +198,10 @@ namespace ZRCola {
///
class language {
public:
ZRCola::langid_t id; ///< Language ID
std::wstring name; ///< Language name
ZRCola::langid_t lang; ///< Language ID
std::wstring name; ///< Name
inline language() : lang(ZRCola::langid_t::blank) {}
};
@@ -134,8 +210,10 @@ namespace ZRCola {
///
class langchar {
public:
wchar_t chr; ///> Character
std::wstring chr; ///> Character
ZRCola::langid_t lang; ///< Language ID
inline langchar() : lang(ZRCola::langid_t::blank) {}
};
@@ -144,76 +222,67 @@ namespace ZRCola {
///
class chrgrp {
public:
int id; ///< Character group ID
int rank; ///< Character group rank
std::wstring name; ///< Character group name
std::wstring chars; ///< Character group characters
std::vector<unsigned __int16> show; ///< Bit vector if particular character is displayed initially
int grp; ///< Character group ID
int rank; ///< Rank
std::wstring name; ///< Name
std::vector<wchar_t> chars; ///< Characters (zero-delimited)
std::vector<unsigned __int16> show; ///< Bit vector if particular character from \c chars is displayed initially
inline chrgrp() : grp(0), rank(0) {}
};
///
/// Character data
///
class character_data {
public:
inline character_data()
{
cat.data[0] = 0;
cat.data[1] = 0;
}
inline character_data(_In_ const character_data &othr) :
cat (othr.cat),
desc (othr.desc),
terms (othr.terms),
terms_rel(othr.terms_rel),
rel (othr.rel)
{
}
ZRCola::chrcatid_t cat; ///< Category ID
std::wstring desc; ///< Character description
std::set<std::wstring> terms; ///< Search terms
std::set<std::wstring> terms_rel; ///< Relevant terms for relating characters
std::vector<wchar_t> rel; ///< Related characters (zero-delimited)
};
///
/// Character
///
class character {
public:
inline character()
{
chr = 0;
cat.data[0] = 0;
cat.data[1] = 0;
}
inline character(_In_ const character &othr) :
chr (othr.chr),
cat (othr.cat),
desc (othr.desc),
terms(othr.terms),
rel (othr.rel)
{
}
inline bool operator==(_In_ const character &othr) const
{
return
chr == othr.chr &&
cat == othr.cat &&
desc == othr.desc &&
terms == othr.terms &&
rel == othr.rel;
}
inline bool operator!=(_In_ const character &othr) const
{
return !operator==(othr);
}
wchar_t chr; ///< Character
ZRCola::chrcatid_t cat; ///< Category ID
std::wstring desc; ///< Character description
std::set<std::wstring> terms; ///< Search terms
std::wstring rel; ///< Related characters
};
typedef std::pair<std::wstring, character_data> character;
///
/// Character bank
///
class character_bank : public std::vector<std::unique_ptr<character> >
class character_bank : public std::map<std::wstring, character_data>
{
public:
character_bank();
void build_related();
protected:
class build_related_worker : public winstd::win_handle
class build_related_worker : public winstd::win_handle<INVALID_HANDLE_VALUE>
{
public:
build_related_worker(_In_ const character_bank *cb, _In_ size_type from, _In_ size_type to);
build_related_worker(_In_ const character_bank *cb, _In_ iterator from, _In_ iterator to);
inline void join()
{
if (m_h)
if (m_h != invalid)
WaitForSingleObject(m_h, INFINITE);
}
@@ -230,12 +299,9 @@ namespace ZRCola {
protected:
const character_bank *m_cb;
size_type m_from, m_to;
iterator m_from, m_to;
winstd::heap m_heap;
};
protected:
std::set<std::wstring> m_ignore;
};
@@ -265,9 +331,9 @@ namespace ZRCola {
class character_desc_idx : public std::map<std::wstring, std::vector<wchar_t>, character_desc_idx_less>
{
public:
static void parse_keywords(const wchar_t *str, std::set<std::wstring> &terms);
void add_keywords(const std::set<std::wstring> &terms, wchar_t chr, size_t sub = 0);
inline void add_keywords(const wchar_t *str, wchar_t chr, size_t sub = 0)
static void parse_keywords(_In_ const wchar_t *str, _Inout_ std::set<std::wstring> &terms);
void add_keywords(const std::set<std::wstring> &terms, const std::wstring &chr, size_t sub = 0);
inline void add_keywords(const wchar_t *str, const std::wstring &chr, size_t sub = 0)
{
std::set<std::wstring> terms;
parse_keywords(str, terms);
@@ -277,21 +343,21 @@ namespace ZRCola {
void save(ZRCola::textindex<wchar_t, wchar_t, unsigned __int32> &idx) const;
protected:
inline void add_keyword(const std::wstring &term, wchar_t chr)
inline void add_keyword(const std::wstring &term, const std::wstring &chr)
{
iterator idx = find(term);
if (idx == end()) {
// New keyword.
insert(std::make_pair(term, std::vector<wchar_t>(1, chr)));
insert(std::make_pair(term, mapped_type(chr.data(), chr.data() + chr.length() + 1)));
} else {
// Append to existing keyword.
std::vector<wchar_t> &val = idx->second;
for (auto i = val.cbegin(), i_end = val.cend(); ; ++i) {
if (i == i_end) {
auto &val = idx->second;
for (mapped_type::size_type i = 0, n = val.size(); ; i += wcsnlen(val.data() + i, n - i) + 1) {
if (i >= n) {
// End-of-values reached. Append character.
val.push_back(chr);
val.insert(val.end(), chr.data(), chr.data() + chr.length() + 1);
break;
} else if (*i == chr) {
} else if (chr.compare(val.data() + i) == 0) {
// Character already among the values.
break;
}
@@ -306,9 +372,11 @@ namespace ZRCola {
///
class chrcat {
public:
ZRCola::chrcatid_t id; ///> Category ID
int rank; ///< Character category rank
std::wstring name; ///< Character category name
ZRCola::chrcatid_t cat; ///> Category ID
int rank; ///< Rank
std::wstring name; ///< Name
inline chrcat() : cat(ZRCola::chrcatid_t::blank), rank(0) {}
};
@@ -317,8 +385,10 @@ namespace ZRCola {
///
class chrtag {
public:
wchar_t chr; ///> Character
std::wstring chr; ///> Character
int tag; ///< Tag ID
inline chrtag() : tag(0) {}
};
@@ -329,6 +399,8 @@ namespace ZRCola {
public:
int tag; ///< Tag ID
std::map<LCID, std::list<std::wstring> > names; ///< Names
inline tagname() : tag(0) {}
};
@@ -416,6 +488,18 @@ namespace ZRCola {
///
bool GetValue(const winstd::com_obj<ADOField>& f, int& val) const;
///
/// Gets string from ZRCola.zrc database
///
/// \param[in] f Data field
/// \param[out] val Output string value
///
/// \returns
/// - true when successful
/// - false otherwise
///
bool GetValue(const winstd::com_obj<ADOField>& f, std::string& val) const;
///
/// Gets string from ZRCola.zrc database
///
@@ -452,6 +536,18 @@ namespace ZRCola {
///
bool GetUnicodeString(const winstd::com_obj<ADOField>& f, std::wstring& str) const;
///
/// Gets encoded normalization permutations from ZRCola.zrc database
///
/// \param[in] f Data field
/// \param[out] str Output normalization permutation set
///
/// \returns
/// - true when successful
/// - false otherwise
///
bool GetNormPerm(const winstd::com_obj<ADOField>& f, normperm& np) const;
///
/// Gets language ID from ZRCola.zrc database
///
@@ -488,6 +584,29 @@ namespace ZRCola {
///
bool GetTagNames(const winstd::com_obj<ADOField>& f, LCID lcid, std::list<std::wstring>& names) const;
///
/// Returns normalization permutation sets
///
/// \param[out] rs Recordset with results
///
/// \returns
/// - true when query succeeds
/// - false otherwise
///
bool SelectNormPermSets(winstd::com_obj<ADORecordset>& rs) const;
///
/// Returns normalization permutation set
///
/// \param[in] rs Recordset with results
/// \param[out] np Normalization permutation set
///
/// \returns
/// - true when succeeded
/// - false otherwise
///
bool GetNormPerm(const winstd::com_obj<ADORecordset>& rs, std::string& norm, normperm& np) const;
///
/// Returns character translations
///
@@ -499,6 +618,18 @@ namespace ZRCola {
///
bool SelectTranslations(winstd::com_obj<ADORecordset>& rs) const;
///
/// Returns character translations by set
///
/// \param[in ] set Translation set ID
/// \param[out] rs Recordset with results
///
/// \returns
/// - true when query succeeds
/// - false otherwise
///
bool SelectTranslations(int set, winstd::com_obj<ADORecordset>& rs) const;
///
/// Returns translation data
///
@@ -511,6 +642,52 @@ namespace ZRCola {
///
bool GetTranslation(const winstd::com_obj<ADORecordset>& rs, translation& t) const;
///
/// Returns translation sets
///
/// \param[out] rs Recordset with results
///
/// \returns
/// - true when query succeeds
/// - false otherwise
///
bool SelectTranlationSets(winstd::com_obj<ADORecordset>& rs) const;
///
/// Returns translation set data
///
/// \param[in] rs Recordset with results
/// \param[out] lang Language
///
/// \returns
/// - true when succeeded
/// - false otherwise
///
bool GetTranslationSet(const winstd::com_obj<ADORecordset>& rs, transet& ts) const;
///
/// Returns translation sequences
///
/// \param[out] rs Recordset with results
///
/// \returns
/// - true when query succeeds
/// - false otherwise
///
bool SelectTranlationSeqs(winstd::com_obj<ADORecordset>& rs) const;
///
/// Returns translation sequence data
///
/// \param[in] rs Recordset with results
/// \param[out] lang Language
///
/// \returns
/// - true when succeeded
/// - false otherwise
///
bool GetTranslationSeq(const winstd::com_obj<ADORecordset>& rs, transeq& ts) const;
///
/// Returns key sequences
///
@@ -697,10 +874,241 @@ namespace ZRCola {
protected:
std::basic_string<TCHAR> m_filename; ///< Database filename
winstd::com_obj<ADOConnection> m_db; ///< Database
winstd::com_obj<ADOConnection> m_db; ///< Database
_locale_t m_locale; ///< Database locale
winstd::com_obj<ADOCommand> m_comCharacterGroup; ///< ADO Command for GetCharacterGroup subquery
winstd::com_obj<ADOParameter> m_pCharacterGroup1; ///< \c m_comCharacterGroup parameter
winstd::com_obj<ADOCommand> m_comCharacterGroup; ///< ADO Command for GetCharacterGroup subquery
winstd::com_obj<ADOParameter> m_pCharacterGroup1; ///< \c m_comCharacterGroup parameter
winstd::com_obj<ADOCommand> m_comTranslation; ///< ADO Command for SelectTranslations subquery
winstd::com_obj<ADOParameter> m_pTranslation1; ///< \c m_comTranslations parameter
winstd::com_obj<ADOCommand> m_comTranslationSets; ///< ADO Command for GetTranslationSeq subquery
winstd::com_obj<ADOParameter> m_pTranslationSets1; ///< \c m_comTranslationSets parameter
std::set<std::wstring> m_terms_ignore; ///< Terms to ignore when comparing characters
};
};
inline ZRCola::translation_db& operator<<(_Inout_ ZRCola::translation_db &db, _In_ const ZRCola::DBSource::translation &rec)
{
unsigned __int32 idx = db.data.size();
wxASSERT_MSG((int)0xffff0000 <= rec.set && rec.set <= (int)0x0000ffff, wxT("translation set id out of bounds"));
db.data.push_back((unsigned __int16)rec.set);
wxASSERT_MSG((int)0xffff8000 <= rec.dst.rank && rec.dst.rank <= (int)0x00007fff, wxT("destination character rank out of bounds"));
db.data.push_back((unsigned __int16)rec.dst.rank);
wxASSERT_MSG((int)0xffff8000 <= rec.src.rank && rec.src.rank <= (int)0x00007fff, wxT("source character rank out of bounds"));
db.data.push_back((unsigned __int16)rec.src.rank);
std::wstring::size_type n = rec.dst.str.length();
wxASSERT_MSG(n <= 0xffff, wxT("destination overflow"));
db.data.push_back((unsigned __int16)n);
n += rec.src.str.length();
wxASSERT_MSG(n <= 0xffff, wxT("source overflow"));
db.data.push_back((unsigned __int16)n);
db.data.insert(db.data.end(), rec.dst.str.cbegin(), rec.dst.str.cend());
db.data.insert(db.data.end(), rec.src.str.cbegin(), rec.src.str.cend());
db.idxSrc.push_back(idx);
db.idxDst.push_back(idx);
return db;
}
inline ZRCola::transet_db& operator<<(_Inout_ ZRCola::transet_db &db, _In_ const ZRCola::DBSource::transet &rec)
{
unsigned __int32 idx = db.data.size();
wxASSERT_MSG((int)0xffff0000 <= rec.set && rec.set <= (int)0x0000ffff, wxT("translation set id out of bounds"));
db.data.push_back((unsigned __int16)rec.set);
std::wstring::size_type n = rec.src.length();
wxASSERT_MSG(n <= 0xffff, wxT("translation set source name overflow"));
db.data.push_back((unsigned __int16)n);
n += rec.dst.length();
wxASSERT_MSG(n <= 0xffff, wxT("translation set destination name overflow"));
db.data.push_back((unsigned __int16)n);
db.data.insert(db.data.end(), rec.src.cbegin(), rec.src.cend());
db.data.insert(db.data.end(), rec.dst.cbegin(), rec.dst.cend());
db.idxTranSet.push_back(idx);
return db;
}
inline ZRCola::transeq_db& operator<<(_Inout_ ZRCola::transeq_db &db, _In_ const ZRCola::DBSource::transeq &rec)
{
unsigned __int32 idx = db.data.size();
wxASSERT_MSG((int)0xffff8000 <= rec.seq && rec.seq <= (int)0x00007fff, wxT("translation sequence id out of bounds"));
db.data.push_back((unsigned __int16)rec.seq);
wxASSERT_MSG((int)0xffff8000 <= rec.rank && rec.rank <= (int)0x00007fff, wxT("translation rank id out of bounds"));
db.data.push_back((unsigned __int16)rec.rank);
std::wstring::size_type n = rec.name.length();
wxASSERT_MSG(n <= 0xffff, wxT("translation sequence name overflow"));
db.data.push_back((unsigned __int16)n);
n += rec.sets.size();
wxASSERT_MSG(n <= 0xffff, wxT("translation sequence sets overflow"));
db.data.push_back((unsigned __int16)n);
db.data.insert(db.data.end(), rec.name.cbegin(), rec.name.cend());
for (auto s = rec.sets.cbegin(), s_end = rec.sets.cend(); s != s_end; ++s) {
int val = *s;
wxASSERT_MSG(val <= 0xffff, wxT("translation sequence ID overflow"));
db.data.push_back((unsigned __int16)val);
}
db.idxTranSeq.push_back(idx);
db.idxRank .push_back(idx);
return db;
}
inline ZRCola::keyseq_db& operator<<(_Inout_ ZRCola::keyseq_db &db, _In_ const ZRCola::DBSource::keyseq &rec)
{
unsigned __int32 idx = db.data.size();
std::wstring::size_type n = rec.chr.length();
wxASSERT_MSG(n <= 0xffff, wxT("character overflow"));
db.data.push_back((unsigned __int16)n);
n += rec.seq.size() * sizeof(ZRCola::keyseq_db::keyseq::key_t) / sizeof(wchar_t);
wxASSERT_MSG(n <= 0xffff, wxT("key sequence overflow"));
db.data.push_back((unsigned __int16)n);
db.data.insert(db.data.end(), rec.chr.cbegin(), rec.chr.cend());
for (auto kc = rec.seq.cbegin(), kc_end = rec.seq.cend(); kc != kc_end; ++kc) {
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);
return db;
}
inline ZRCola::language_db& operator<<(_Inout_ ZRCola::language_db &db, _In_ const ZRCola::DBSource::language &rec)
{
unsigned __int32 idx = db.data.size();
db.data.insert(db.data.end(), reinterpret_cast<const unsigned __int16*>(&rec.lang), reinterpret_cast<const unsigned __int16*>(&rec.lang + 1));
std::wstring::size_type n = rec.name.length();
wxASSERT_MSG(n <= 0xffff, wxT("language name overflow"));
db.data.push_back((unsigned __int16)n);
db.data.insert(db.data.end(), rec.name.cbegin(), rec.name.cend());
db.idxLang.push_back(idx);
return db;
}
inline ZRCola::langchar_db& operator<<(_Inout_ ZRCola::langchar_db &db, _In_ const ZRCola::DBSource::langchar &rec)
{
unsigned __int32 idx = db.data.size();
db.data.insert(db.data.end(), reinterpret_cast<const unsigned __int16*>(&rec.lang), reinterpret_cast<const unsigned __int16*>(&rec.lang + 1));
std::wstring::size_type n = rec.chr.length();
wxASSERT_MSG(n <= 0xffff, wxT("character overflow"));
db.data.push_back((unsigned __int16)n);
db.data.insert(db.data.end(), rec.chr.cbegin(), rec.chr.cend());
db.idxChr .push_back(idx);
#ifdef ZRCOLA_LANGCHAR_LANG_IDX
db.idxLang.push_back(idx);
#endif
return db;
}
inline ZRCola::chrgrp_db& operator<<(_Inout_ ZRCola::chrgrp_db &db, _In_ const ZRCola::DBSource::chrgrp &rec)
{
unsigned __int32 idx = db.data.size();
wxASSERT_MSG((int)0xffff8000 <= rec.grp && rec.grp <= (int)0x00007fff, wxT("character group ID out of bounds"));
db.data.push_back((unsigned __int16)rec.grp);
wxASSERT_MSG((int)0xffff8000 <= rec.rank && rec.rank <= (int)0x00007fff, wxT("character group rank out of bounds"));
db.data.push_back((unsigned __int16)rec.rank);
std::wstring::size_type n = rec.name.length();
wxASSERT_MSG(n <= 0xffff, wxT("character group name overflow"));
db.data.push_back((unsigned __int16)n);
n += rec.chars.size();
wxASSERT_MSG(n <= 0xffff, wxT("character group characters overflow"));
db.data.push_back((unsigned __int16)n);
db.data.insert(db.data.end(), rec.name .cbegin(), rec.name .cend());
db.data.insert(db.data.end(), rec.chars.cbegin(), rec.chars.cend());
db.data.insert(db.data.end(), rec.show .cbegin(), rec.show .cend());
db.idxRank.push_back(idx);
return db;
}
inline ZRCola::character_db& operator<<(_Inout_ ZRCola::character_db &db, _In_ const ZRCola::DBSource::character &rec)
{
unsigned __int32 idx = db.data.size();
db.data.insert(db.data.end(), reinterpret_cast<const unsigned __int16*>(&rec.second.cat), reinterpret_cast<const unsigned __int16*>(&rec.second.cat + 1));
std::wstring::size_type n = rec.first.length();
wxASSERT_MSG(n <= 0xffff, wxT("character overflow"));
db.data.push_back((unsigned __int16)n);
n += rec.second.desc.length();
wxASSERT_MSG(n <= 0xffff, wxT("character description overflow"));
db.data.push_back((unsigned __int16)n);
n += rec.second.rel.size();
wxASSERT_MSG(n <= 0xffff, wxT("related characters overflow"));
db.data.push_back((unsigned __int16)n);
db.data.insert(db.data.end(), rec.first .cbegin(), rec.first .cend());
db.data.insert(db.data.end(), rec.second.desc.cbegin(), rec.second.desc.cend());
db.data.insert(db.data.end(), rec.second.rel .cbegin(), rec.second.rel .cend());
db.idxChr.push_back(idx);
return db;
}
inline ZRCola::chrcat_db& operator<<(_Inout_ ZRCola::chrcat_db &db, _In_ const ZRCola::DBSource::chrcat &rec)
{
unsigned __int32 idx = db.data.size();
db.data.insert(db.data.end(), reinterpret_cast<const unsigned __int16*>(&rec.cat), reinterpret_cast<const unsigned __int16*>(&rec.cat + 1));
wxASSERT_MSG((int)0xffff8000 <= rec.rank && rec.rank <= (int)0x00007fff, wxT("character category rank out of bounds"));
db.data.push_back((unsigned __int16)rec.rank);
std::wstring::size_type n = rec.name.length();
wxASSERT_MSG(n <= 0xffff, wxT("character category name overflow"));
db.data.push_back((unsigned __int16)n);
db.data.insert(db.data.end(), rec.name.cbegin(), rec.name.cend());
db.idxChrCat.push_back(idx);
db.idxRank .push_back(idx);
return db;
}
inline ZRCola::chrtag_db& operator<<(_Inout_ ZRCola::chrtag_db &db, _In_ const ZRCola::DBSource::chrtag &rec)
{
unsigned __int32 idx = db.data.size();
wxASSERT_MSG((int)0xffff8000 <= rec.tag && rec.tag <= (int)0x00007fff, wxT("tag out of bounds"));
db.data.push_back((unsigned __int16)rec.tag);
std::wstring::size_type n = rec.chr.length();
wxASSERT_MSG(n <= 0xffff, wxT("character overflow"));
db.data.push_back((unsigned __int16)n);
db.data.insert(db.data.end(), rec.chr.cbegin(), rec.chr.cend());
db.idxChr.push_back(idx);
db.idxTag.push_back(idx);
return db;
}
inline ZRCola::tagname_db& operator<<(_Inout_ ZRCola::tagname_db &db, _In_ const ZRCola::DBSource::tagname &rec)
{
for (auto ln = rec.names.cbegin(), ln_end = rec.names.cend(); ln != ln_end; ++ln) {
for (auto nm = ln->second.cbegin(), nm_end = ln->second.cend(); nm != nm_end; ++nm) {
unsigned __int32 idx = db.data.size();
wxASSERT_MSG((int)0xffff8000 <= rec.tag && rec.tag <= (int)0x00007fff, wxT("tag out of bounds"));
db.data.push_back((unsigned __int16)rec.tag);
db.data.push_back(LOWORD(ln->first));
db.data.push_back(HIWORD(ln->first));
std::wstring::size_type n = nm->length();
wxASSERT_MSG(n <= 0xffff, wxT("tag name overflow"));
db.data.push_back((unsigned __int16)n);
db.data.insert(db.data.end(), nm->cbegin(), nm->cend());
db.idxName.push_back(idx);
db.idxTag .push_back(idx);
}
}
return db;
}

View File

@@ -2,7 +2,7 @@
msgid ""
msgstr ""
"Project-Id-Version: ZRColaCompile\n"
"POT-Creation-Date: 2016-10-13 11:49+0200\n"
"POT-Creation-Date: 2018-09-19 09:00+0200\n"
"PO-Revision-Date: 2016-04-13 18:11+0200\n"
"Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n"
"Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n"
@@ -10,26 +10,25 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.9\n"
"X-Generator: Poedit 2.1.1\n"
"X-Poedit-Basepath: ..\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n"
"%100==4 ? 2 : 3);\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
#: main.cpp:102
#: main.cpp:251
msgid "Show this help message"
msgstr ""
#: main.cpp:103
#: main.cpp:252
msgid "<input file>"
msgstr ""
#: main.cpp:104
#: main.cpp:253
msgid "<output file>"
msgstr ""
#: main.cpp:105
#: main.cpp:254
msgid "<output POT catalog>"
msgstr ""

View File

@@ -1,72 +1,209 @@
/*
Copyright 2015-2017 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/>.
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#include "stdafx.h"
#include "pch.h"
using namespace std;
using namespace stdex;
using namespace winstd;
typedef map<wchar_t, set<ZRCola::DBSource::charseq, ZRCola::DBSource::charseq::less_rank_str> > translation_db;
static set<wstring> decompose(_In_ const translation_db &db, _In_z_ const wchar_t *str, _Inout_ set<wchar_t> &path)
///
/// (destination character rank, (source character rank, source character)) data holder
///
class com_translation
{
set<wstring> res;
public:
int rank_src; ///< Source sequence rank
int rank_dst; ///< Destination character rank
string norm; ///< Normalization footprint
if (*str) {
// Decompose remainder first.
auto rem = decompose(db, str + 1, path);
if (rem.empty())
return res;
inline com_translation() :
rank_src(0),
rank_dst(0)
{
}
auto const t = db.find(*str);
if (t != db.end()) {
// Current characted decomposed. Iterate all possible decompositions and combine them with the remainder.
auto p = path.insert(*str);
if (!p.second) {
// Path already contains this character: Cycle detected!
return res;
}
for (auto d = t->second.cbegin(), d_end = t->second.cend(); d != d_end; ++d) {
auto dec = decompose(db, d->str.c_str(), path);
if (!dec.empty()) {
for (auto dd = dec.cbegin(), dd_end = dec.cend(); dd != dd_end; ++dd) {
for (auto r = rem.cbegin(), r_end = rem.cend(); r != r_end; ++r)
res.insert(*dd + *r);
}
} else {
// Cycle detected. Do not continue decomposition.
for (auto r = rem.cbegin(), r_end = rem.cend(); r != r_end; ++r)
res.insert(wstring(1, *str) + *r);
}
}
path.erase(p.first);
} else {
// Current character is non-decomposable. Combine it with the remainder(s).
for (auto r = rem.cbegin(), r_end = rem.cend(); r != r_end; ++r)
res.insert(wstring(1, *str) + *r);
inline com_translation(int _rank_src, int _rank_dst) :
rank_src(_rank_src),
rank_dst(_rank_dst)
{
}
inline com_translation(int _rank_src, int _rank_dst, const char *_norm) :
rank_src(_rank_src),
rank_dst(_rank_dst),
norm (_norm )
{
}
inline com_translation(int _rank_src, int _rank_dst, string &&_norm) :
rank_src( _rank_src ),
rank_dst( _rank_dst ),
norm (std::move(_norm ))
{
}
inline com_translation(const com_translation &other) :
rank_src(other.rank_src),
rank_dst(other.rank_dst),
norm (other.norm )
{
}
inline com_translation(com_translation &&other) noexcept :
rank_src( other.rank_src ),
rank_dst( other.rank_dst ),
norm (std::move(other.norm ))
{
}
inline com_translation& operator=(const com_translation &other)
{
if (this != std::addressof(other)) {
rank_src = other.rank_src;
rank_dst = other.rank_dst;
norm = other.norm ;
}
return *this;
}
inline com_translation& operator=(com_translation &&other) noexcept
{
if (this != std::addressof(other)) {
rank_src = other.rank_src ;
rank_dst = other.rank_dst ;
norm = std::move(other.norm );
}
return *this;
}
inline bool operator==(_In_ const com_translation& other) const
{
return
rank_src == other.rank_src &&
rank_dst == other.rank_dst &&
norm == other.norm;
}
inline bool operator!=(_In_ const com_translation &other) const
{
return !operator==(other);
}
inline bool operator<(_In_ const com_translation& other) const
{
if (rank_src < other.rank_src) return true;
else if (rank_src > other.rank_src) return false;
else if (rank_dst < other.rank_dst) return true;
else if (rank_dst > other.rank_dst) return false;
else if (norm < other.norm ) return true;
else return false;
}
inline bool operator<=(_In_ const com_translation &other) const
{
return !operator>(other);
}
inline bool operator>(_In_ const com_translation &other) const
{
return other.operator<(*this);
}
inline bool operator>=(_In_ const com_translation &other) const
{
return !operator<(other);
}
};
typedef map<wstring, map<wstring, com_translation> > translation_db;
typedef map<string, ZRCola::DBSource::normperm> normperm_db;
static set<ZRCola::DBSource::charseq> translate_inv(_In_ const translation_db &db_trans, _In_ const normperm_db &db_np, _In_z_ const wchar_t *str, _Inout_ set<translation_db::key_type> &path);
static inline set<ZRCola::DBSource::charseq> permutate_and_translate_inv(_In_ const translation_db &db_trans, _In_ const normperm_db &db_np, _In_z_ const wchar_t *str, _In_z_ const char *norm, _Inout_ set<translation_db::key_type> &path);
static set<ZRCola::DBSource::charseq> translate_inv(_In_ const translation_db &db_trans, _In_ const normperm_db &db_np, _In_z_ const wchar_t *str, _Inout_ set<translation_db::key_type> &path)
{
set<ZRCola::DBSource::charseq> res;
if (!*str) {
// Empty string results in empty inverse translation.
res.insert(ZRCola::DBSource::charseq(0, L""));
return res;
}
// Prepare inverse translate of the remainder string (without the first character).
auto res_rem = translate_inv(db_trans, db_np, str + 1, path);
if (res_rem.empty())
return res;
// See if first character is inverse translatable.
translation_db::key_type chr(1, *str);
auto const hit_trans = db_trans.find(chr);
if (hit_trans != db_trans.end()) {
// Current character is inverse translatable.
// Add the current character to the path before recursing.
auto hit_path = path.insert(chr);
if (!hit_path.second) {
// Path already contains this character: Cycle detected!
return res;
}
// Iterate all possible character inverse translations and combine them with the remainder string inverse translations.
for (auto d = hit_trans->second.cbegin(), d_end = hit_trans->second.cend(); d != d_end; ++d) {
auto res_chr = d->second.norm.empty() ?
translate_inv(db_trans, db_np, d->first.c_str(), path) :
permutate_and_translate_inv(db_trans, db_np, d->first.c_str(), d->second.norm.c_str(), path);
if (!res_chr.empty()) {
for (auto r_chr = res_chr.cbegin(), r_chr_end = res_chr.cend(); r_chr != r_chr_end; ++r_chr) {
for (auto r_rem = res_rem.cbegin(), r_rem_end = res_rem.cend(); r_rem != r_rem_end; ++r_rem)
res.insert(ZRCola::DBSource::charseq(d->second.rank_src + r_chr->rank + r_rem->rank, r_chr->str + r_rem->str));
}
} else {
// Cycle detected. Do not continue inverse translation.
for (auto r_rem = res_rem.cbegin(), r_end = res_rem.cend(); r_rem != r_end; ++r_rem)
res.insert(ZRCola::DBSource::charseq(r_rem->rank, chr + r_rem->str));
}
}
// Remove the current character from the path.
path.erase(hit_path.first);
} else {
// Empty string results in empty decomposition.
res.insert(L"");
// First character is non-inverse translatable. Combine it with the remainder(s).
for (auto r_rem = res_rem.cbegin(), r_end = res_rem.cend(); r_rem != r_end; ++r_rem)
res.insert(ZRCola::DBSource::charseq(r_rem->rank, chr + r_rem->str));
}
return res;
}
static inline set<ZRCola::DBSource::charseq> permutate_and_translate_inv(_In_ const translation_db &db_trans, _In_ const normperm_db &db_np, _In_z_ const wchar_t *str, _In_z_ const char *norm, _Inout_ set<translation_db::key_type> &path)
{
// Primary permutation inverse translate.
auto res = translate_inv(db_trans, db_np, str, path);
// Secondary permutation(s).
auto const hit_np = db_np.find(norm);
if (hit_np != db_np.end()) {
for (auto perm = hit_np->second.cbegin(), perm_end = hit_np->second.cend(); perm != perm_end; ++perm) {
// Prepare permutated string.
translation_db::mapped_type::key_type str_perm;
for (auto idx = perm->cbegin(), idx_end = perm->cend(); idx != idx_end; ++idx)
str_perm += str[*idx];
// Secondary permutation inverse translate.
auto res_perm = translate_inv(db_trans, db_np, str_perm.c_str(), path);
for (auto r = res_perm.cbegin(), r_end = res_perm.cend(); r != r_end; ++r)
res.insert(ZRCola::DBSource::charseq(r->rank + 1, r->str));
}
}
return res;
@@ -99,10 +236,10 @@ int _tmain(int argc, _TCHAR *argv[])
// Parse command line.
static const wxCmdLineEntryDesc cmdLineDesc[] =
{
{ wxCMD_LINE_SWITCH, "h" , "help", _("Show this help message"), wxCMD_LINE_VAL_NONE , wxCMD_LINE_OPTION_HELP },
{ wxCMD_LINE_PARAM , NULL, NULL , _("<input file>" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_PARAM , NULL, NULL , _("<output file>" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_PARAM , NULL, NULL , _("<output POT catalog>" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION },
{ wxCMD_LINE_SWITCH, "h" , "help" , _("Show this help message"), wxCMD_LINE_VAL_NONE , wxCMD_LINE_OPTION_HELP },
{ wxCMD_LINE_PARAM , NULL, NULL , _("<Input file>" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_PARAM , NULL, NULL , _("<Output file>" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_OPTION, NULL, "pot-cat", _("Output POT catalog" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
{ wxCMD_LINE_NONE }
};
@@ -145,12 +282,45 @@ int _tmain(int argc, _TCHAR *argv[])
bool has_errors = false;
// Set of strings to translate.
bool build_pot = parser.GetParamCount() > 2;
wxString filenamePot;
bool build_pot = parser.Found("pot-cat", &filenamePot);
set<wstring> pot;
// Open file ID.
streamoff dst_start = idrec::open<ZRCola::recordid_t, ZRCola::recordsize_t>(dst, ZRCOLA_DB_ID);
ZRCola::translation_db db_trans;
ZRCola::transet_db db_transset;
normperm_db db_np;
{
// Get normalization permutation sets.
com_obj<ADORecordset> rs;
if (src.SelectNormPermSets(rs)) {
size_t count = src.GetRecordsetCount(rs);
if (count < 0xffffffff) { // 4G check (-1 is reserved for error condition)
string norm;
ZRCola::DBSource::normperm np;
// Parse normalization permutation sets.
for (; !ZRCola::DBSource::IsEOF(rs); rs->MoveNext()) {
// Read normalization permutation set from the database.
if (src.GetNormPerm(rs, norm, np)) {
if (!np.empty())
db_np.insert(pair<string, ZRCola::DBSource::normperm>(norm, std::move(np)));
} else
has_errors = true;
}
} else {
_ftprintf(stderr, wxT("%s: error ZCC0009: Error getting translation set count from database or too many translation sets.\n"), (LPCTSTR)filenameIn.c_str());
has_errors = true;
}
} else {
_ftprintf(stderr, wxT("%s: error ZCC0008: Error getting translation sets from database. Please make sure the file is ZRCola.zrc compatible.\n"), (LPCTSTR)filenameIn.c_str());
has_errors = true;
}
}
{
// Get translations.
com_obj<ADORecordset> rs;
@@ -164,72 +334,63 @@ int _tmain(int argc, _TCHAR *argv[])
ZRCola::DBSource::translation trans;
if (src.GetTranslation(rs, trans)) {
// Add translation to temporary database.
auto const t = db_temp1.find(trans.chr);
if (t != db_temp1.end())
t->second.insert(std::move(trans.decomp));
pair<translation_db::mapped_type::key_type, translation_db::mapped_type::mapped_type> ctp(std::move(trans.src.str), translation_db::mapped_type::mapped_type(trans.src.rank, trans.dst.rank, std::move(trans.norm)));
auto hit = db_temp1.find(trans.dst.str);
if (hit != db_temp1.end())
hit->second.insert(std::move(ctp));
else {
translation_db::mapped_type d;
d.insert(std::move(trans.decomp));
db_temp1.insert(std::move(pair<translation_db::key_type, translation_db::mapped_type>(trans.chr, std::move(d))));
translation_db::mapped_type t;
t.insert(std::move(ctp));
db_temp1.insert(pair<translation_db::key_type, translation_db::mapped_type>(std::move(trans.dst.str), std::move(t)));
}
} else
has_errors = true;
}
// Decompose decompositions down to non-decomposable characters.
// Inverse translate source sequences down to non-inverse translatable characters.
translation_db db_temp2;
for (auto t1 = db_temp1.cbegin(), t1_end = db_temp1.cend(); t1 != t1_end; ++t1) {
auto t2 = db_temp2.insert(pair<translation_db::key_type, translation_db::mapped_type>(t1->first, translation_db::mapped_type())).first;
for (auto d1 = t1->second.cbegin(), d1_end = t1->second.cend(); d1 != d1_end; ++d1) {
set<wchar_t> path;
set<translation_db::key_type> path;
path.insert(t1->first);
auto str = decompose(db_temp1, d1->str.c_str(), path);
assert(!str.empty());
auto res = d1->second.norm.empty() ?
translate_inv(db_temp1, db_np, d1->first.c_str(), path) :
permutate_and_translate_inv(db_temp1, db_np, d1->first.c_str(), d1->second.norm.c_str(), path);
assert(!res.empty());
// Add translation to temporary database.
auto const t2 = db_temp2.find(t1->first);
if (t2 != db_temp2.end()) {
for (auto s = str.cbegin(), s_end = str.cend(); s != s_end; ++s)
t2->second.insert(std::move(ZRCola::DBSource::charseq(d1->rank, s->c_str())));
} else {
translation_db::mapped_type d2;
for (auto s = str.cbegin(), s_end = str.cend(); s != s_end; ++s)
d2.insert(std::move(ZRCola::DBSource::charseq(d1->rank, s->c_str())));
db_temp2.insert(std::move(pair<translation_db::key_type, translation_db::mapped_type>(t1->first, std::move(d2))));
for (auto r = res.cbegin(), r_end = res.cend(); r != r_end; ++r) {
translation_db::mapped_type::mapped_type ct(d1->second.rank_src + r->rank, d1->second.rank_dst);
auto hit = t2->second.find(r->str);
if (hit != t2->second.end()) {
hit->second.rank_src = std::min<int>(hit->second.rank_src, ct.rank_src);
hit->second.rank_dst = std::max<int>(hit->second.rank_dst, ct.rank_dst);
} else
t2->second.insert(pair<translation_db::mapped_type::key_type, translation_db::mapped_type::mapped_type>(r->str, std::move(ct)));
}
}
}
ZRCola::translation_db db;
// Preallocate memory.
db.idxComp .reserve(count);
db.idxDecomp.reserve(count);
db.data .reserve(count*4);
db_trans.idxSrc.reserve(count);
db_trans.idxDst.reserve(count);
db_trans.data .reserve(count*5);
// Parse translations and build index and data.
ZRCola::DBSource::translation trans;
trans.set = 0;
for (auto t = db_temp2.cbegin(), t_end = db_temp2.cend(); t != t_end; ++t) {
// Add translation to index and data.
trans.dst.str = t->first;
for (auto d = t->second.cbegin(), d_end = t->second.cend(); d != d_end; ++d) {
unsigned __int32 idx = db.data.size();
db.data.push_back(t->first);
wxASSERT_MSG((int)0xffff8000 <= d->rank && d->rank <= (int)0x00007fff, wxT("transformation rank out of bounds"));
db.data.push_back((unsigned __int16)d->rank);
wstring::size_type n = d->str.length();
wxASSERT_MSG(n <= 0xffff, wxT("transformation string too long"));
db.data.push_back((unsigned __int16)n);
for (wstring::size_type i = 0; i < n; i++)
db.data.push_back(d->str[i]);
db.idxComp .push_back(idx);
db.idxDecomp.push_back(idx);
trans.dst.rank = d->second.rank_dst;
trans.src.rank = d->second.rank_src;
trans.src.str = d->first;
db_trans << trans;
}
}
// Sort indices.
db.idxComp .sort();
db.idxDecomp.sort();
// Write translations to file.
dst << ZRCola::translation_rec(db);
} else {
_ftprintf(stderr, wxT("%s: error ZCC0004: Error getting translation count from database or too many translations.\n"), (LPCTSTR)filenameIn.c_str());
has_errors = true;
@@ -240,6 +401,127 @@ int _tmain(int argc, _TCHAR *argv[])
}
}
{
// Get translation sets.
com_obj<ADORecordset> rs;
if (src.SelectTranlationSets(rs)) {
size_t count = src.GetRecordsetCount(rs);
if (count < 0xffffffff) { // 4G check (-1 is reserved for error condition)
// Preallocate memory.
db_transset.idxTranSet.reserve((count+1));
db_transset.data .reserve((count+1)*4);
// Parse translation sets and build index and data.
for (; !ZRCola::DBSource::IsEOF(rs); rs->MoveNext()) {
// Read translation set from the database.
ZRCola::DBSource::transet ts;
if (src.GetTranslationSet(rs, ts)) {
if (ts.set <= (int)ZRCOLA_TRANSEQID_DEFAULT) {
_ftprintf(stderr, wxT("%s: error ZCC0008: Translation set is using reserved ID %i.\n"), (LPCTSTR)filenameIn.c_str(), ts.set);
has_errors = true;
continue;
}
if (build_pot) {
pot.insert(ts.src);
pot.insert(ts.dst);
}
// Add translation set to index and data.
db_transset << ts;
// Get translations.
com_obj<ADORecordset> rs_tran;
if (src.SelectTranslations(ts.set, rs_tran)) {
if (src.GetRecordsetCount(rs_tran) < 0xffffffff) { // 4G check (-1 is reserved for error condition)
// Parse translations and build temporary database.
ZRCola::DBSource::translation trans;
trans.set = ts.set;
for (; !ZRCola::DBSource::IsEOF(rs_tran); rs_tran->MoveNext()) {
// Read translation from the database.
if (src.GetTranslation(rs_tran, trans)) {
// Add translation to index and data.
db_trans << trans;
} else
has_errors = true;
}
} else {
_ftprintf(stderr, wxT("%s: error ZCC0004: Error getting translation count from database or too many translations.\n"), (LPCTSTR)filenameIn.c_str());
has_errors = true;
}
} else {
_ftprintf(stderr, wxT("%s: error ZCC0003: Error getting translations from database. Please make sure the file is ZRCola.zrc compatible.\n"), (LPCTSTR)filenameIn.c_str());
has_errors = true;
}
} else
has_errors = true;
}
} else {
_ftprintf(stderr, wxT("%s: error ZCC0009: Error getting translation set count from database or too many translation sets.\n"), (LPCTSTR)filenameIn.c_str());
has_errors = true;
}
} else {
_ftprintf(stderr, wxT("%s: error ZCC0008: Error getting translation sets from database. Please make sure the file is ZRCola.zrc compatible.\n"), (LPCTSTR)filenameIn.c_str());
has_errors = true;
}
}
// Sort indices.
db_transset.idxTranSet.sort();
// Write translation sets to file.
dst << ZRCola::transet_rec(db_transset);
// Sort indices.
db_trans.idxSrc.sort();
db_trans.idxDst.sort();
// Write translations to file.
dst << ZRCola::translation_rec(db_trans);
{
// Get translation sequences.
com_obj<ADORecordset> rs;
if (src.SelectTranlationSeqs(rs)) {
size_t count = src.GetRecordsetCount(rs);
if (count < 0xffffffff) { // 4G check (-1 is reserved for error condition)
ZRCola::transeq_db db;
// Preallocate memory.
db.idxTranSeq.reserve((count+1));
db.idxRank .reserve((count+1));
db.data .reserve((count+1)*4);
// Parse translation sequences and build index and data.
for (; !ZRCola::DBSource::IsEOF(rs); rs->MoveNext()) {
// Read translation sequence from the database.
ZRCola::DBSource::transeq ts;
if (src.GetTranslationSeq(rs, ts)) {
if (build_pot)
pot.insert(ts.name);
// Add translation sequence to index and data.
db << ts;
} else
has_errors = true;
}
// Sort indices.
db.idxTranSeq.sort();
db.idxRank .sort();
// Write translation sequences to file.
dst << ZRCola::transeq_rec(db);
} else {
_ftprintf(stderr, wxT("%s: error ZCC0025: Error getting translation sequence count from database or too many translation sequences.\n"), (LPCTSTR)filenameIn.c_str());
has_errors = true;
}
} else {
_ftprintf(stderr, wxT("%s: error ZCC0024: Error getting translation sequences from database. Please make sure the file is ZRCola.zrc compatible.\n"), (LPCTSTR)filenameIn.c_str());
has_errors = true;
}
}
{
// Get key sequences.
com_obj<ADORecordset> rs;
@@ -259,21 +541,7 @@ int _tmain(int argc, _TCHAR *argv[])
// Read key sequence from the database.
if (src.GetKeySequence(rs, ks)) {
// Add key sequence to index and data.
unsigned __int32 idx = db.data.size();
db.data.push_back(ks.chr);
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 (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);
db << ks;
} else
has_errors = true;
}
@@ -288,10 +556,14 @@ int _tmain(int argc, _TCHAR *argv[])
&ks1 = db.idxKey[i - 1],
&ks2 = db.idxKey[i ];
if (ZRCola::keyseq_db::keyseq::CompareSequence(ks1.seq, ks1.seq_len, ks2.seq, ks2.seq_len) == 0) {
if (ZRCola::keyseq_db::keyseq::CompareSequence(ks1.seq(), ks1.seq_len(), ks2.seq(), ks2.seq_len()) == 0) {
wxString seq_str;
ZRCola::keyseq_db::GetSequenceAsText(ks1.seq, ks1.seq_len, seq_str);
_ftprintf(stderr, wxT("%s: warning ZCC0007: Duplicate key sequence (%ls => %04X or %04X). The keyboard behaviour will be unpredictable.\n"), (LPCTSTR)filenameIn.c_str(), seq_str.c_str(), ks1.chr, ks2.chr);
ZRCola::keyseq_db::GetSequenceAsText(ks1.seq(), ks1.seq_len(), seq_str);
_ftprintf(stderr, wxT("%s: warning ZCC0007: Duplicate key sequence (%s => %s or %s). The keyboard behaviour will be unpredictable.\n"),
(LPCTSTR)filenameIn.c_str(),
(LPCTSTR)seq_str.c_str(),
ZRCola::GetUnicodeDump(ks1.chr(), ks1.chr_len()).c_str(),
ZRCola::GetUnicodeDump(ks2.chr(), ks2.chr_len()).c_str());
}
}
@@ -317,8 +589,8 @@ int _tmain(int argc, _TCHAR *argv[])
ZRCola::language_db db;
// Preallocate memory.
db.idxLng.reserve(count);
db.data .reserve(count*4);
db.idxLang.reserve(count);
db.data .reserve(count*4);
// Parse languages and build index and data.
for (; !ZRCola::DBSource::IsEOF(rs); rs->MoveNext()) {
@@ -328,21 +600,13 @@ int _tmain(int argc, _TCHAR *argv[])
pot.insert(lang.name);
// Add language to index and data.
unsigned __int32 idx = db.data.size();
for (wstring::size_type i = 0; i < sizeof(ZRCola::langid_t)/sizeof(unsigned __int16); i++)
db.data.push_back(((const unsigned __int16*)lang.id.data)[i]);
wstring::size_type n = lang.name.length();
wxASSERT_MSG(n <= 0xffff, wxT("language name too long"));
db.data.push_back((unsigned __int16)n);
for (wstring::size_type i = 0; i < n; i++)
db.data.push_back(lang.name[i]);
db.idxLng.push_back(idx);
db << lang;
} else
has_errors = true;
}
// Sort indices.
db.idxLng.sort();
db.idxLang.sort();
// Write languages to file.
dst << ZRCola::language_rec(db);
@@ -366,25 +630,18 @@ int _tmain(int argc, _TCHAR *argv[])
ZRCola::langchar_db db;
// Preallocate memory.
db.idxChr.reserve(count);
db.idxChr .reserve(count);
#ifdef ZRCOLA_LANGCHAR_LANG_IDX
db.idxLng.reserve(count);
db.idxLang.reserve(count);
#endif
db.data .reserve(count*4);
db.data .reserve(count*4);
// Parse language characters and build index and data.
for (; !ZRCola::DBSource::IsEOF(rs); rs->MoveNext()) {
// Read language characters from the database.
if (src.GetLanguageCharacter(rs, lc)) {
// Add language characters to index and data.
unsigned __int32 idx = db.data.size();
db.data.push_back(lc.chr);
for (wstring::size_type i = 0; i < sizeof(ZRCola::langid_t)/sizeof(unsigned __int16); i++)
db.data.push_back(((const unsigned __int16*)lc.lang.data)[i]);
db.idxChr.push_back(idx);
#ifdef ZRCOLA_LANGCHAR_LANG_IDX
db.idxLng.push_back(idx);
#endif
db << lc;
} else
has_errors = true;
}
@@ -392,7 +649,7 @@ int _tmain(int argc, _TCHAR *argv[])
// Sort indices.
db.idxChr .sort();
#ifdef ZRCOLA_LANGCHAR_LANG_IDX
db.idxLng.sort();
db.idxLang.sort();
#endif
// Write language characters to file.
@@ -417,8 +674,8 @@ int _tmain(int argc, _TCHAR *argv[])
ZRCola::chrgrp_db db;
// Preallocate memory.
db.idxRnk.reserve(count);
db.data .reserve(count*4);
db.idxRank.reserve(count);
db.data .reserve(count*4);
// Parse character groups and build index and data.
for (; !ZRCola::DBSource::IsEOF(rs); rs->MoveNext()) {
@@ -433,30 +690,13 @@ int _tmain(int argc, _TCHAR *argv[])
}
// Add character group to index and data.
unsigned __int32 idx = db.data.size();
wxASSERT_MSG((int)0xffff8000 <= cg.id && cg.id <= (int)0x00007fff, wxT("character group ID out of bounds"));
db.data.push_back((unsigned __int16)cg.id);
wxASSERT_MSG((int)0xffff8000 <= cg.rank && cg.rank <= (int)0x00007fff, wxT("character group rank out of bounds"));
db.data.push_back((unsigned __int16)cg.rank);
wstring::size_type n_name = cg.name.length();
wxASSERT_MSG(n_name <= 0xffff, wxT("character group name too long"));
db.data.push_back((unsigned __int16)n_name);
wstring::size_type n_char = cg.chars.length();
wxASSERT_MSG(n_char <= 0xffff, wxT("too many character group characters"));
db.data.push_back((unsigned __int16)n_char);
for (wstring::size_type i = 0; i < n_name; i++)
db.data.push_back(cg.name[i]);
for (wstring::size_type i = 0; i < n_char; i++)
db.data.push_back(cg.chars[i]);
for (std::vector<unsigned __int16>::size_type i = 0, n = cg.show.size(); i < n; i++)
db.data.push_back(cg.show[i]);
db.idxRnk.push_back(idx);
db << cg;
} else
has_errors = true;
}
// Sort indices.
db.idxRnk.sort();
db.idxRank.sort();
// Write character groups to file.
dst << ZRCola::chrgrp_rec(db);
@@ -485,11 +725,10 @@ int _tmain(int argc, _TCHAR *argv[])
// Phase 1: Parse characters and build indexes.
for (; !ZRCola::DBSource::IsEOF(rs); rs->MoveNext()) {
// Read character from the database.
unique_ptr<ZRCola::DBSource::character> c(new ZRCola::DBSource::character);
if (src.GetCharacter(rs, *c)) {
const auto &chr = *c.get();
chrs[chr.chr].swap(c);
} else
ZRCola::DBSource::character chr;
if (src.GetCharacter(rs, chr))
chrs[chr.first] = std::move(chr.second);
else
has_errors = true;
}
@@ -503,33 +742,16 @@ int _tmain(int argc, _TCHAR *argv[])
db.data .reserve(count*4);
// Phase 3: Parse characters and build index and data.
for (size_t i = 0, i_end = chrs.size(); i < i_end; i++) {
const auto &chr = *(chrs[i].get());
if (&chr == NULL) continue;
for (auto chr = chrs.cbegin(), chr_end = chrs.cend(); chr != chr_end; ++chr) {
// Add character to index and data.
unsigned __int32 idx = db.data.size();
db.data.push_back((unsigned __int16)chr.chr);
for (wstring::size_type i = 0; i < sizeof(ZRCola::chrcatid_t)/sizeof(unsigned __int16); i++)
db.data.push_back(((const unsigned __int16*)chr.cat.data)[i]);
wstring::size_type n_desc = chr.desc.length();
wxASSERT_MSG(n_desc <= 0xffff, wxT("character description too long"));
db.data.push_back((unsigned __int16)n_desc);
wstring::size_type n_rel = chr.rel.length();
wxASSERT_MSG(n_rel <= 0xffff, wxT("too many related characters"));
db.data.push_back((unsigned __int16)n_rel);
for (wstring::size_type i = 0; i < n_desc; i++)
db.data.push_back(chr.desc[i]);
for (wstring::size_type i = 0; i < n_rel; i++)
db.data.push_back(chr.rel[i]);
db.idxChr.push_back(idx);
db << *chr;
// Add description (and keywords) to index.
idxChrDsc .add_keywords(chr.terms, chr.chr, 0);
idxChrDscSub.add_keywords(chr.terms, chr.chr, 3);
idxChrDsc .add_keywords(chr->second.terms, chr->first, 0);
idxChrDscSub.add_keywords(chr->second.terms, chr->first, 3);
// Mark category used.
categories_used.insert(chr.cat);
categories_used.insert(chr->second.cat);
}
// Sort indices.
@@ -562,7 +784,7 @@ int _tmain(int argc, _TCHAR *argv[])
// Preallocate memory.
db.idxChrCat.reserve(count);
db.idxRnk .reserve(count);
db.idxRank .reserve(count);
db.data .reserve(count*4);
// Parse character categories and build index and data.
@@ -572,31 +794,20 @@ int _tmain(int argc, _TCHAR *argv[])
if (build_pot)
pot.insert(cc.name);
if (categories_used.find(cc.id) == categories_used.end()) {
if (categories_used.find(cc.cat) == categories_used.end()) {
// Skip empty character categories.
continue;
}
// Add character category to index and data.
unsigned __int32 idx = db.data.size();
for (wstring::size_type i = 0; i < sizeof(ZRCola::chrcatid_t)/sizeof(unsigned __int16); i++)
db.data.push_back(((const unsigned __int16*)cc.id.data)[i]);
wxASSERT_MSG((int)0xffff8000 <= cc.rank && cc.rank <= (int)0x00007fff, wxT("character category rank out of bounds"));
db.data.push_back((unsigned __int16)cc.rank);
wstring::size_type n_name = cc.name.length();
wxASSERT_MSG(n_name <= 0xffff, wxT("character category name too long"));
db.data.push_back((unsigned __int16)n_name);
for (wstring::size_type i = 0; i < n_name; i++)
db.data.push_back(cc.name[i]);
db.idxChrCat.push_back(idx);
db.idxRnk .push_back(idx);
db << cc;
} else
has_errors = true;
}
// Sort indices.
db.idxChrCat.sort();
db.idxRnk .sort();
db.idxRank .sort();
// Write character categories to file.
dst << ZRCola::chrcat_rec(db);
@@ -629,18 +840,13 @@ int _tmain(int argc, _TCHAR *argv[])
// Read characters tags from the database.
if (src.GetCharacterTag(rs, ct)) {
// Add characters tags to index and data.
unsigned __int32 idx = db.data.size();
db.data.push_back(ct.chr);
wxASSERT_MSG((int)0xffff8000 <= ct.tag && ct.tag <= (int)0x00007fff, wxT("tag out of bounds"));
db.data.push_back((unsigned __int16)ct.tag);
db.idxChr.push_back(idx);
db.idxTag.push_back(idx);
db << ct;
} else
has_errors = true;
}
// Sort indices.
db.idxChr .sort();
db.idxChr.sort();
db.idxTag.sort();
// Write characters tags to file.
@@ -674,22 +880,7 @@ int _tmain(int argc, _TCHAR *argv[])
// Read tag name from the database.
if (src.GetTagName(rs, tn)) {
// Add tag name to index and data.
for (auto ln = tn.names.cbegin(), ln_end = tn.names.cend(); ln != ln_end; ++ln) {
for (auto nm = ln->second.cbegin(), nm_end = ln->second.cend(); nm != nm_end; ++nm) {
unsigned __int32 idx = db.data.size();
wxASSERT_MSG((int)0xffff8000 <= tn.tag && tn.tag <= (int)0x00007fff, wxT("tag out of bounds"));
db.data.push_back((unsigned __int16)tn.tag);
db.data.push_back(LOWORD(ln->first));
db.data.push_back(HIWORD(ln->first));
wstring::size_type n = nm->length();
wxASSERT_MSG(n <= 0xffff, wxT("tag name too long"));
db.data.push_back((unsigned __int16)n);
for (wstring::size_type i = 0; i < n; i++)
db.data.push_back(nm->at(i));
db.idxName.push_back(idx);
db.idxTag .push_back(idx);
}
}
db << tn;
} else
has_errors = true;
}
@@ -718,10 +909,9 @@ int _tmain(int argc, _TCHAR *argv[])
}
if (!has_errors && build_pot) {
const wxString& filenamePot = parser.GetParam(2);
fstream dst((LPCTSTR)filenamePot, ios_base::out | ios_base::trunc);
if (dst.good()) {
dst << "msgid \"\"" << endl
fstream dst_pot((LPCTSTR)filenamePot, ios_base::out | ios_base::trunc);
if (dst_pot.good()) {
dst_pot << "msgid \"\"" << endl
<< "msgstr \"\"" << endl
<< "\"Project-Id-Version: ZRCola.zrcdb\\n\"" << endl
<< "\"Language: en\\n\"" << endl
@@ -731,9 +921,9 @@ int _tmain(int argc, _TCHAR *argv[])
<< "\"X-Generator: ZRColaCompile\\n\"" << endl;
wstring_convert<codecvt_utf8<wchar_t>> conv;
for (auto i = pot.cbegin(); i != pot.cend(); ++i) {
for (auto p = pot.cbegin(); p != pot.cend(); ++p) {
// Convert UTF-16 to UTF-8 and escape.
string t(conv.to_bytes(*i)), u;
string t(conv.to_bytes(*p)), u;
for (size_t i = 0, n = t.size(); i < n; i++) {
char c = t[i];
switch (c) {
@@ -744,17 +934,17 @@ int _tmain(int argc, _TCHAR *argv[])
default : u += c;
}
}
dst << endl
dst_pot << endl
<< "msgid \"" << u << "\"" << endl
<< "msgstr \"\"" << endl;
}
if (dst.fail()) {
if (dst_pot.fail()) {
_ftprintf(stderr, wxT("%s: error ZCC0013: Writing to POT catalog failed.\n"), (LPCTSTR)filenameOut.c_str());
has_errors = true;
}
dst.close();
dst_pot.close();
} else {
_ftprintf(stderr, wxT("%s: error ZCC0012: Error opening POT catalog.\n"), filenameOut.fn_str());
has_errors = true;

198
ZRColaCompile/parse.cpp Normal file
View File

@@ -0,0 +1,198 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2018-2021 Amebis
*/
#include "pch.h"
using namespace std;
using namespace stdex;
using namespace winstd;
//////////////////////////////////////////////////////////////////////////
// ZRCola::DecompParser
//////////////////////////////////////////////////////////////////////////
ZRCola::DecompParser::DecompParser(_In_ const std::wstring &decomposed) : m_decomposed(decomposed)
{
if (m_decomposed.empty()) {
m_sym = 0;
m_idx = 0;
} else {
m_sym = m_decomposed[0];
m_idx = 1;
}
}
void ZRCola::DecompParser::ParsePrefixes(_Inout_ std::vector<wchar_t> &prefix)
{
for (;;) {
if (
m_sym == 0x203F || // Undertie
0xE0F0 <= m_sym && m_sym <= 0xE0F3 || // 1st Set of Prefix Modifiers
m_sym == 0xE0F6 || // Above
m_sym == 0xE0F7 || // Below
0xE0F8 <= m_sym && m_sym <= 0xE0FC) // 2nd Set of Prefix Modifiers
{
// Prefix modifier
prefix.push_back(m_sym);
NextChar();
} else
break;
}
}
void ZRCola::DecompParser::ParseModifiers(_Inout_ std::vector<wchar_t> &mod)
{
for (;;) {
if (0xE000 <= m_sym && m_sym <= 0xE05B || // 1st Set of Modifiers
0xE063 <= m_sym && m_sym <= 0xE0BE || // 2nd Set of Modifiers
m_sym == 0x0023 || // Number Sign
m_sym == 0x003A || // Colon
m_sym == 0x02DE || // Rhotic Hook
m_sym == 0x2019 || // Right Single Quotation Mark
0x02B0 <= m_sym && m_sym <= 0x02FF || // Standard Unicode Modifiers
m_sym == 0xE0C0 || // Circle
m_sym == 0xE0C2 || // Square
m_sym == 0xE0CA || // Diamond
m_sym == 0xE0CD) // Not Circle
{
mod.push_back(m_sym);
NextChar();
} else
break;
}
}
ZRCola::DecompParser::Expression* ZRCola::DecompParser::ParseParentheses(_In_ wchar_t open, _In_ wchar_t close)
{
if (m_sym == open) {
// Parenthesis Start
NextChar();
if (m_sym == 0xE037) {
// EVA Parenthesis End
unique_ptr<Character> res(new Character(close));
NextChar();
return res.release();
} else {
unique_ptr<Parentheses> res(new Parentheses(open, close, ParseExpression()));
if (m_sym == close) {
// Parenthesis End
NextChar();
} else if (m_sym == open && m_idx < m_decomposed.length() && m_decomposed[m_idx] == 0xE037) {
// Decomposed Parenthesis End
NextChar();
NextChar();
} else
throw invalid_argument(string_printf("%lc is unexpected. Should end with %lc.", m_sym, close));
return res.release();
}
} else
return NULL;
}
ZRCola::DecompParser::Expression* ZRCola::DecompParser::ParseCharacter()
{
Expression *res_p;
if ((res_p = ParseParentheses(0xE0C5, 0xE0C6)) != NULL || // Superscript
(res_p = ParseParentheses(0xE0CE, 0xE0CF)) != NULL || // Subscript
(res_p = ParseParentheses(0xE2E0, 0xE2E1)) != NULL || // EVA Double
(res_p = ParseParentheses(0xE2E2, 0xE2E3)) != NULL || // EVA Condensed
(res_p = ParseParentheses(0xE2E4, 0xE2E5)) != NULL || // EVA Emphasis
(res_p = ParseParentheses(0xE2E6, 0xE2E7)) != NULL || // EVA Strike
(res_p = ParseParentheses(0xE2E8, 0xE2E9)) != NULL || // EVA Undeal
(res_p = ParseParentheses(0xE2EA, 0xE2EB)) != NULL || // EVA Italic
(res_p = ParseParentheses(0xE2EC, 0xE2ED)) != NULL || // EVA Superscript
(res_p = ParseParentheses(0xE2EE, 0xE2EF)) != NULL) // EVA Subscript
{
return res_p;
}
unique_ptr<Character> res(new Character());
ParsePrefixes(res->m_prefix);
if (m_sym < 0xE000 || 0xE0FC < m_sym ||
m_sym == 0xE0D6 || // Clockwise Top Semicircle Arrow
m_sym == 0xE0D7) // Anticlockwise Top Semicircle Arrow
{
// Base Character
res->m_char = m_sym;
NextChar();
}
ParseModifiers(res->m_mod);
return res.release();
}
ZRCola::DecompParser::Expression* ZRCola::DecompParser::ParseTerm()
{
unique_ptr<Ligature> res(new Ligature(ParseCharacter()));
while (m_sym == 0xE0C4) {
// Ligature
std::unique_ptr<Ligature::Element> res2(new Ligature::Element(m_sym));
NextChar();
ParseModifiers(res2->m_mod);
res2->m_el.reset(ParseCharacter());
res->m_rest.push_back(std::move(res2));
}
if (res->m_rest.empty()) {
// A ligature of, well one single character, is rather a character alone.
return res->m_first.release();
} else
return res.release();
}
ZRCola::DecompParser::Expression* ZRCola::DecompParser::ParseExpression()
{
unique_ptr<Expression> res(ParseTerm());
if (0xE05C <= m_sym && m_sym <= 0xE062 ||
m_sym == 0xE0C1 || // Two Characters in Circle
m_sym == 0xE0C3 || // Two Characters in Square
m_sym == 0xE0C7 || // Breved below
m_sym == 0xE0CB || // Inverse tilded
m_sym == 0xE0CC || // Diagonally Barred
0xE0D0 <= m_sym && m_sym <= 0xE0D5)
{
// Joiner of two terms
unique_ptr<Joined2> res_j(new Joined2(m_sym, res.release()));
NextChar();
ParseModifiers(res_j->m_mod);
res_j->m_second.reset(ParseTerm());
return res_j.release();
} else if (
m_sym == 0xE0C8 || // Inverse breved
m_sym == 0xE0C9) // Breved below
{
// Joiner of three terms
unique_ptr<Joined3> res_j(new Joined3(m_sym, res.release()));
NextChar();
ParseModifiers(res_j->m_mod);
res_j->m_second.reset(ParseTerm());
res_j->m_third.reset(ParseTerm());
return res_j.release();
} else
return res.release();
}
ZRCola::DecompParser::Expression* ZRCola::DecompParser::Parse()
{
unique_ptr<Expression> res(ParseExpression());
if (m_sym)
throw invalid_argument("Unexpected trailing character(s).");
return res.release();
}

140
ZRColaCompile/parse.h Normal file
View File

@@ -0,0 +1,140 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2018-2021 Amebis
*/
#pragma once
#include <sal.h>
#include <list>
#include <memory>
#include <string>
#include <vector>
namespace ZRCola {
///
/// Decomposed sequence parser
///
class DecompParser
{
public:
///
/// Base class for expressions
///
class Expression
{
};
///
/// Expression in "parentheses"
///
class Parentheses : public Expression
{
public:
inline Parentheses(_In_opt_ wchar_t open = 0, _In_opt_ wchar_t close = 0, _In_opt_ Expression *expr = NULL) : m_open(open), m_close(close), m_expr(expr) {}
public:
wchar_t m_open, m_close;
std::unique_ptr<Expression> m_expr;
};
///
/// Operator
///
class Operator : public Expression
{
public:
inline Operator(_In_opt_ wchar_t chr = 0) : m_char(chr) {}
wchar_t m_char;
std::vector<wchar_t> m_mod;
};
///
/// Character
///
class Character : public Operator
{
public:
inline Character(_In_opt_ wchar_t chr = 0) : Operator(chr) {}
std::vector<wchar_t> m_prefix;
};
///
/// Ligature
///
class Ligature : public Expression
{
public:
class Element : public Operator
{
public:
inline Element(_In_opt_ wchar_t chr = 0) : Operator(chr) {}
std::unique_ptr<Expression> m_el;
};
inline Ligature(_In_opt_ Expression *first = NULL) : m_first(first) {}
std::unique_ptr<Expression> m_first;
std::list<std::unique_ptr<Element> > m_rest;
};
///
/// Two joined terms
///
class Joined2 : public Operator
{
public:
Joined2(_In_opt_ wchar_t chr = 0, _In_opt_ Expression *first = NULL) : Operator(chr), m_first(first) {}
std::unique_ptr<Expression> m_first, m_second;
};
///
/// Three joined terms
///
class Joined3 : public Joined2
{
public:
Joined3(_In_opt_ wchar_t chr = 0, _In_opt_ Expression *first = NULL) : Joined2(chr, first) {}
std::unique_ptr<Expression> m_third;
};
public:
DecompParser(_In_ const std::wstring &decomposed);
protected:
inline void NextChar();
void ParsePrefixes(_Inout_ std::vector<wchar_t> &prefix);
void ParseModifiers(_Inout_ std::vector<wchar_t> &mod);
Expression* ParseParentheses(_In_ wchar_t open, _In_ wchar_t close);
Expression* ParseCharacter();
Expression* ParseTerm();
Expression* ParseExpression();
public:
Expression* Parse();
protected:
std::wstring::size_type m_idx; ///< Index of current character
const std::wstring &m_decomposed; ///< Decomposed character sequence to analyse
wchar_t m_sym; ///< Current character
};
}
inline void ZRCola::DecompParser::NextChar()
{
m_sym = m_idx < m_decomposed.length() ? m_decomposed[m_idx++] : 0;
}

6
ZRColaCompile/pch.cpp Normal file
View File

@@ -0,0 +1,6 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#include "pch.h"

45
ZRColaCompile/pch.h Normal file
View File

@@ -0,0 +1,45 @@
/*
SPDX-License-Identifier: GPL-3.0-or-later
Copyright © 2015-2021 Amebis
*/
#pragma once
#include "../include/version.h"
#include "dbsource.h"
#include "parse.h"
#include <wxex/common.h>
#include <wxex/comutils.h>
#pragma warning(push)
#pragma warning(disable: WXWIDGETS_CODE_ANALYSIS_WARNINGS)
#include <wx/app.h>
#include <wx/cmdline.h>
#include <wx/config.h>
#include <wx/intl.h>
#pragma warning(pop)
#include <stdex/idrec.h>
#include <WinStd/Common.h>
#include <initguid.h> // GUID helper to prevent LNK2001 errors (unresolved external symbol IID_IADO...)
#pragma warning(push)
#pragma warning(disable: 4091)
#include <adoint.h>
#include <adoid.h>
#pragma warning(pop)
#include <process.h>
#include <tchar.h>
#include <stdlib.h>
#include <algorithm>
#include <codecvt>
#include <cwctype>
#include <fstream>
#include <memory>
#include <set>
#include <vector>

View File

@@ -1,20 +0,0 @@
/*
Copyright 2015-2017 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"

View File

@@ -1,58 +0,0 @@
/*
Copyright 2015-2017 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 "../include/version.h"
#include "dbsource.h"
#include <zrcola/language.h>
#include <zrcola/translate.h>
#include <zrcola/tag.h>
#include <zrcolaui/chargroup.h>
#include <zrcolaui/keyboard.h>
#include <wx/app.h>
#include <wx/cmdline.h>
#include <wx/config.h>
#include <wx/intl.h>
#include <wxex/common.h>
#include <wxex/comutils.h>
#include <stdex/idrec.h>
#include <WinStd/Common.h>
#include <initguid.h> // GUID helper to prevent LNK2001 errors (unresolved external symbol IID_IADO...)
#include <adoint.h>
#include <adoid.h>
#include <process.h>
#include <tchar.h>
#include <stdlib.h>
#include <algorithm>
#include <codecvt>
#include <cwctype>
#include <fstream>
#include <memory>
#include <set>
#include <vector>

View File

@@ -1,46 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets">
<Import Project="..\include\$(Platform).props" />
<Import Project="..\include\$(Configuration).props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>..\output\$(Platform).$(Configuration)\</OutDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<CompileAsManaged>false</CompileAsManaged>
<BufferSecurityCheck>false</BufferSecurityCheck>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<SmallerTypeCheck>false</SmallerTypeCheck>
</ClCompile>
<Link>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ZRColaInstall.rc" />
</ItemGroup>
</Project>

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More