mirror of
https://github.com/keymanapp/keyman.git
synced 2026-10-22 05:47:41 +00:00
1430 lines
41 KiB
ObjectPascal
1430 lines
41 KiB
ObjectPascal
(*
|
|
Name: UframeOnScreenKeyboardEditor
|
|
Copyright: Copyright (C) SIL International.
|
|
Documentation:
|
|
Description:
|
|
Create Date: 4 Dec 2006
|
|
|
|
Modified Date: 3 Aug 2015
|
|
Authors: mcdurdin
|
|
Related Files:
|
|
Dependencies:
|
|
|
|
Bugs:
|
|
Todo:
|
|
Notes:
|
|
History: 04 Dec 2006 - mcdurdin - Initial version (split from UfrmKeymanWizard)
|
|
04 Jan 2007 - mcdurdin - Fix OSK AltGr flag bug
|
|
15 Jan 2007 - mcdurdin - Use correct key cap when no key cap character on selected shift state
|
|
22 Jan 2007 - mcdurdin - Support export to BMP and PNG
|
|
19 Mar 2007 - mcdurdin - I712 - Fix character map should follow selected character in OSK and kbd editors
|
|
30 May 2007 - mcdurdin - I726 - Fixed 102 key not displaying when it should
|
|
30 May 2007 - mcdurdin - I674 - Fixed crash when attempting to import invalid OSK XML file
|
|
13 Jul 2007 - mcdurdin - I905 - Stop keys moving around on the keyboard designer
|
|
19 Nov 2007 - mcdurdin - I1157 - const string parameters
|
|
14 Jun 2008 - mcdurdin - Fixup VK dirty state
|
|
10 Sep 2008 - mcdurdin - I1471 - Add key caps to all non-matched keys (option)
|
|
29 Sep 2008 - mcdurdin - I1658 - Add options for graphic location and usage
|
|
16 Jan 2009 - mcdurdin - Support HTML graphic and folder export options
|
|
18 Mar 2011 - mcdurdin - I1471 - Alt+LShift characters incorrectly added
|
|
18 Mar 2011 - mcdurdin - I2794 - Tike has some handle leaks
|
|
19 Aug 2011 - mcdurdin - I3022 - When using OSK editor with a Euro layout, key caps move around unexpectedly
|
|
18 May 2012 - mcdurdin - I3306 - V9.0 - Remove TntControls + Win9x support
|
|
11 Aug 2013 - mcdurdin - I3885 - V9.0 - Touch Layout Editor
|
|
21 Feb 2014 - mcdurdin - I4057 - V9.0 - Keyman Developer Keyboard Font dialog helpful to reduce font confusion
|
|
27 Feb 2014 - mcdurdin - I4085 - V9.0 - Remove old font selection controls from wizard
|
|
01 May 2014 - mcdurdin - I4181 - V9.0 - Stop using DeleteFileAlways, MOVEFILE_DELAY_UNTIL_REBOOT
|
|
27 May 2015 - mcdurdin - I4599 - Developer crashes if user tries importing an invalid KVK XML file [CrashID:tike.exe_9.0.481.0_005EB6B7_EDOMParseError
|
|
30 May 2015 - mcdurdin - I4730 - Loading a kvk file in a keyboard, where content is invalid, crashes developer [CrashID:tike.exe_9.0.504.0_0078D23F_EVisualKeyboardLoader]
|
|
24 Jul 2015 - mcdurdin - I4796 - Refresh Keyman Developer look and feel for release
|
|
03 Aug 2015 - mcdurdin - I4807 - Add Character Identifier to Keyman Developer
|
|
*)
|
|
unit UframeOnScreenKeyboardEditor; // I3885 // I4085 // I4796
|
|
|
|
interface
|
|
|
|
uses
|
|
System.Classes,
|
|
System.Contnrs,
|
|
System.SysUtils,
|
|
System.Types,
|
|
System.UITypes,
|
|
System.Variants,
|
|
Vcl.ComCtrls,
|
|
Vcl.Controls,
|
|
Vcl.Dialogs,
|
|
Vcl.ExtCtrls,
|
|
Vcl.ExtDlgs,
|
|
Vcl.Forms,
|
|
Vcl.Graphics,
|
|
Vcl.StdCtrls,
|
|
Winapi.Messages,
|
|
Winapi.Windows,
|
|
|
|
OnScreenKeyboard,
|
|
OnScreenKeyboardData,
|
|
KeyBtn,
|
|
VisualKeyboard,
|
|
CharacterDragObject,
|
|
VisualKeyboardParameters,
|
|
UfrmTike,
|
|
UframeTextEditor,
|
|
TextFileFormat,
|
|
TempFileManager;
|
|
|
|
type
|
|
TImportKMXEvent = procedure(Sender: TObject; var KMXFileName: TTempFile) of object; // I4181
|
|
TImportKMXFinishedEvent = procedure(Sender: TObject; KMXFileName: TTempFile) of object; // I4181
|
|
|
|
TframeOnScreenKeyboardEditor = class(TTikeForm)
|
|
panVK: TPanel;
|
|
panBottom: TPanel;
|
|
panKeyContent: TPanel;
|
|
panKeyText: TPanel;
|
|
editVKKeyText: TEdit;
|
|
rbKeyText: TRadioButton;
|
|
panKeyBitmap: TPanel;
|
|
rbKeyBitmap: TRadioButton;
|
|
cmdBrowseKeyBitmap: TButton;
|
|
panKeyPreview: TPanel;
|
|
panVKKey: TPanel;
|
|
Label4: TLabel;
|
|
VKkeySample: TKeyBtn;
|
|
VKkeySampleCtrl: TKeyBtn;
|
|
VKkeySampleShift: TKeyBtn;
|
|
VKkeySampleAlt: TKeyBtn;
|
|
panOptions: TPanel;
|
|
chkVKDisplayUnderlyingChars: TCheckBox;
|
|
chkVKSplitCtrlAlt: TCheckBox;
|
|
chkVKOnlyUseWithUnderlyingLayout: TCheckBox;
|
|
chkVKInclude102key: TCheckBox;
|
|
cmdVKSelectLayout: TButton;
|
|
kbdOnScreen: TOnScreenKeyboard;
|
|
dlgVKImportXML: TOpenDialog;
|
|
dlgVKSaveExport: TSaveDialog;
|
|
dlgBrowseForKeyBitmap: TOpenPictureDialog;
|
|
dlgFont: TFontDialog;
|
|
dlgSaveVisualKeyboard: TSaveDialog;
|
|
tmrUpdateCharacterMap: TTimer;
|
|
chkFillUnderlyingLayout: TCheckBox;
|
|
pages: TPageControl;
|
|
pageDesign: TTabSheet;
|
|
pageCode: TTabSheet;
|
|
panTop: TPanel;
|
|
cmdVKImportKMX: TButton;
|
|
cmdExportOnScreenKeyboard: TButton;
|
|
cmdImportOnScreenKeyboard: TButton;
|
|
procedure kbdOnScreenDragDrop(Sender, Source: TObject; X, Y: Integer);
|
|
procedure kbdOnScreenDragOver(Sender, Source: TObject; X, Y: Integer;
|
|
State: TDragState; var Accept: Boolean);
|
|
procedure kbdOnScreenSelectionChange(Sender: TObject);
|
|
procedure kbdOnScreenShiftChange(Sender: TObject);
|
|
procedure chkVKSplitCtrlAltClick(Sender: TObject);
|
|
procedure chkVKDisplayUnderlyingCharsClick(Sender: TObject);
|
|
procedure chkVKInclude102keyClick(Sender: TObject);
|
|
procedure chkVKOnlyUseWithUnderlyingLayoutClick(Sender: TObject);
|
|
procedure rbKeyTextClick(Sender: TObject);
|
|
procedure rbKeyBitmapClick(Sender: TObject);
|
|
procedure cmdBrowseKeyBitmapClick(Sender: TObject);
|
|
procedure editVKKeyTextChange(Sender: TObject);
|
|
procedure cmdVKSelectLayoutClick(Sender: TObject);
|
|
procedure lblVKFontClick(Sender: TObject);
|
|
procedure cmdImportOnScreenKeyboardClick(Sender: TObject);
|
|
procedure cmdExportOnScreenKeyboardClick(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure cmdVKImportKMXClick(Sender: TObject);
|
|
procedure lblVKCharacterSetClick(Sender: TObject);
|
|
procedure editVKKeyTextClick(Sender: TObject);
|
|
procedure editVKKeyTextKeyUp(Sender: TObject; var Key: Word;
|
|
Shift: TShiftState);
|
|
procedure tmrUpdateCharacterMapTimer(Sender: TObject);
|
|
procedure TntFormDestroy(Sender: TObject);
|
|
procedure pagesChanging(Sender: TObject; var AllowChange: Boolean);
|
|
procedure pagesChange(Sender: TObject);
|
|
private
|
|
FVKSetup: Boolean;
|
|
|
|
FVK: TVisualKeyboard;
|
|
FVKModified: Boolean;
|
|
FVKCurrentKey: TVisualKeyboardKey;
|
|
|
|
FVKUnicode: Boolean;
|
|
FOnModified: TNotifyEvent;
|
|
FKMXFileName: WideString;
|
|
FFileName: WideString;
|
|
FOnImportingKMX: TImportKMXEvent;
|
|
FOnImportingKMXFinished: TImportKMXFinishedEvent;
|
|
FVKLoading: Boolean;
|
|
frameSource: TframeTextEditor;
|
|
|
|
procedure SourceChanged(Sender: TObject);
|
|
procedure VK_SetAllKeyDetails;
|
|
procedure VK_UpdateKeyFont;
|
|
function VK_GetCurrentKey: TVisualKeyboardKey;
|
|
procedure VK_SelectVKey;
|
|
procedure VK_UpdateSelectedKeyDetails;
|
|
procedure VK_UpdateData;
|
|
procedure ExportToFile(FileName: string);
|
|
function GetBMPExportParams(FFileName: string; var FMulti, FANSI,
|
|
FUnicode: Boolean; var FPixelWidth: Integer): Boolean;
|
|
procedure EnableControls;
|
|
procedure VK_UpdateCharacterSet(FMoveRules: Boolean);
|
|
procedure SetVKModified(const Value: Boolean);
|
|
procedure SetVKUnicode(const Value: Boolean);
|
|
function GetUnderlyingLayout: HKL;
|
|
procedure SetUnderlyingLayout(const Value: HKL);
|
|
procedure VK_FocusKey;
|
|
procedure SetKMXFileName(Value: WideString);
|
|
procedure DoUpdateCharacterMap;
|
|
function GetHTMLExportParams(FFileName: string; var FFolders,
|
|
FGraphical: Boolean): Boolean;
|
|
function GetKeyFont: TFont; // I4057
|
|
procedure SetKeyFont(const Value: TFont);
|
|
function DoesKeyboardSupportXMLVisualKeyboard: Boolean;
|
|
function TransferDesignToSource: Boolean;
|
|
function TransferSourceToDesign(ASilent: Boolean): Boolean; // I4057
|
|
protected
|
|
function GetHelpTopic: string; override;
|
|
public
|
|
|
|
procedure Load;
|
|
procedure Save;
|
|
procedure UpdateControls;
|
|
procedure SetFocus; override;
|
|
property UnderlyingLayout: HKL read GetUnderlyingLayout write SetUnderlyingLayout;
|
|
property KeyFont: TFont read GetKeyFont write SetKeyFont; // I4057
|
|
property VKModified: Boolean read FVKModified write SetVKModified;
|
|
property VKUnicode: Boolean read FVKUnicode write SetVKUnicode;
|
|
property OnModified: TNotifyEvent read FOnModified write FOnModified;
|
|
property OnImportingKMX: TImportKMXEvent read FOnImportingKMX write FOnImportingKMX;
|
|
property OnImportingKMXFinished: TImportKMXFinishedEvent read FOnImportingKMXFinished write FOnImportingKMXFinished;
|
|
property FileName: WideString read FFileName write FFileName;
|
|
property KMXFileName: WideString read FKMXFileName write SetKMXFileName;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Xml.Xmldom,
|
|
|
|
Keyman.Developer.System.HelpTopics,
|
|
|
|
CharacterInfo,
|
|
CharMapInsertMode,
|
|
ExtShiftState,
|
|
KeymanDeveloperOptions,
|
|
kmxfile,
|
|
UfrmVisualKeyboardExportBMPParams,
|
|
UfrmVisualKeyboardExportHTMLParams,
|
|
UfrmVisualKeyboardImportKMX,
|
|
utilstr,
|
|
VisualKeyboardImportXML,
|
|
VisualKeyboardExportBMP,
|
|
VisualKeyboardExportPNG,
|
|
VisualKeyboardExportHTML,
|
|
VisualKeyboardExportXML;
|
|
|
|
{$R *.dfm}
|
|
|
|
procedure TframeOnScreenKeyboardEditor.FormCreate(Sender: TObject);
|
|
begin
|
|
inherited;
|
|
|
|
pages.ActivePage := pageDesign;
|
|
|
|
FVKUnicode := True;
|
|
|
|
kbdOnScreen.SelectedKey := kbdOnScreen.Keys[0];
|
|
|
|
FVK := TVisualKeyboard.Create;
|
|
FVK.Header.Flags := [kvkhDisplayUnderlying];
|
|
|
|
FVKCurrentKey := nil;
|
|
kbdOnScreen.DisplayUnderlyingChar := True;
|
|
|
|
frameSource := TframeTextEditor.Create(Self);
|
|
frameSource.Parent := pageCode;
|
|
frameSource.Align := alClient;
|
|
frameSource.EditorFormat := efXML;
|
|
frameSource.Visible := True;
|
|
frameSource.OnChanged := SourceChanged;
|
|
frameSource.TextFileFormat := tffUTF8; // Only UTF-8 supported for KVK XML
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.TntFormDestroy(Sender: TObject);
|
|
begin
|
|
inherited;
|
|
FreeAndNil(FVK); // I2794
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.SetFocus;
|
|
begin
|
|
inherited;
|
|
if pages.ActivePage = pageCode then
|
|
frameSource.SetFocus;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.SetKeyFont(const Value: TFont); // I4057
|
|
begin
|
|
if not FVKUnicode
|
|
then FVK.Header.ANSIFont := Value
|
|
else FVK.Header.UnicodeFont := Value;
|
|
|
|
VK_UpdateKeyFont;
|
|
VKModified := True;
|
|
|
|
if pages.ActivePage = pageDesign then
|
|
TransferDesignToSource;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.SetKMXFileName(Value: WideString);
|
|
begin
|
|
FKMXFileName := Value;
|
|
VK_UpdateData;
|
|
|
|
if pages.ActivePage = pageDesign then
|
|
TransferDesignToSource;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.SetUnderlyingLayout(const Value: HKL);
|
|
begin
|
|
kbdOnScreen.UnderlyingLayout := Value;
|
|
kbdOnScreen.Repaint;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.SetVKModified(const Value: Boolean);
|
|
begin
|
|
if FVKModified <> Value then
|
|
begin
|
|
FVKModified := Value;
|
|
if FVKModified then
|
|
if Assigned(FOnModified) then FOnModified(Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.SetVKUnicode(const Value: Boolean);
|
|
begin
|
|
if FVKUnicode <> Value then
|
|
begin
|
|
FVKUnicode := Value;
|
|
VK_UpdateKeyFont;
|
|
VK_SetAllKeyDetails;
|
|
VK_UpdateSelectedKeyDetails;
|
|
VK_UpdateCharacterSet(False);
|
|
end;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.tmrUpdateCharacterMapTimer(Sender: TObject);
|
|
begin
|
|
tmrUpdateCharacterMap.Enabled := False;
|
|
UpdateCharacterMap(False, editVKKeyText.Text, 0, 0, True);
|
|
end;
|
|
|
|
{ ---------------------------------------------------------------------------- }
|
|
{ - Tab interactions - }
|
|
{ ---------------------------------------------------------------------------- }
|
|
|
|
procedure TframeOnScreenKeyboardEditor.pagesChange(Sender: TObject);
|
|
begin
|
|
if pages.ActivePage = pageCode then
|
|
frameSource.SetFocus;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.pagesChanging(Sender: TObject;
|
|
var AllowChange: Boolean);
|
|
begin
|
|
if pages.ActivePage = pageCode
|
|
then AllowChange := TransferSourceToDesign(False)
|
|
else AllowChange := TransferDesignToSource;
|
|
end;
|
|
|
|
function TframeOnScreenKeyboardEditor.TransferSourceToDesign(ASilent: Boolean): Boolean;
|
|
var
|
|
stream: TStringStream;
|
|
begin
|
|
stream := TStringStream.Create(frameSource.EditorText, TEncoding.UTF8);
|
|
try
|
|
try
|
|
with TVisualKeyboard.Create do
|
|
try
|
|
LoadFromStream(stream);
|
|
finally
|
|
Free;
|
|
end;
|
|
except
|
|
on E:EVisualKeyboardLoader do
|
|
begin
|
|
ShowMessage(E.Message);
|
|
Exit(False);
|
|
end;
|
|
end;
|
|
|
|
stream.Position := 0;
|
|
FVKLoading := True;
|
|
try
|
|
FVK.LoadFromStream(stream);
|
|
VK_UpdateData;
|
|
VK_UpdateKeyFont;
|
|
FVKCurrentKey := nil;
|
|
VK_SelectVKey;
|
|
finally
|
|
FVKLoading := False;
|
|
end;
|
|
|
|
finally
|
|
stream.Free;
|
|
end;
|
|
Result := True;
|
|
end;
|
|
|
|
function TframeOnScreenKeyboardEditor.TransferDesignToSource: Boolean;
|
|
var
|
|
stream: TStringStream;
|
|
begin
|
|
stream := TStringStream.Create('', TEncoding.UTF8);
|
|
try
|
|
FVK.SaveToStream(stream, kvksfXML);
|
|
frameSource.EditorText := stream.DataString;
|
|
finally
|
|
stream.Free;
|
|
end;
|
|
Result := True;
|
|
end;
|
|
|
|
{ ---------------------------------------------------------------------------- }
|
|
{ - Design tab - }
|
|
{ ---------------------------------------------------------------------------- }
|
|
|
|
procedure TframeOnScreenKeyboardEditor.chkVKDisplayUnderlyingCharsClick(
|
|
Sender: TObject);
|
|
begin
|
|
if not FVKLoading then VKModified := True;
|
|
kbdOnScreen.DisplayUnderlyingChar := chkVKDisplayUnderlyingChars.Checked;
|
|
if chkVKDisplayUnderlyingChars.Checked
|
|
then FVK.Header.Flags := FVK.Header.Flags + [kvkhDisplayUnderlying]
|
|
else FVK.Header.Flags := FVK.Header.Flags - [kvkhDisplayUnderlying];
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.chkVKInclude102keyClick(Sender: TObject);
|
|
begin
|
|
if not FVKLoading then VKModified := True;
|
|
kbdOnScreen.Display102Key := chkVKInclude102key.Checked;
|
|
if chkVKInclude102key.Checked
|
|
then FVK.Header.Flags := FVK.Header.Flags + [kvkh102]
|
|
else FVK.Header.Flags := FVK.Header.Flags - [kvkh102];
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.chkVKOnlyUseWithUnderlyingLayoutClick(
|
|
Sender: TObject);
|
|
begin
|
|
if not FVKLoading then VKModified := True;
|
|
if chkVKOnlyUseWithUnderlyingLayout.Checked
|
|
then FVK.Header.Flags := FVK.Header.Flags + [kvkhUseUnderlying]
|
|
else FVK.Header.Flags := FVK.Header.Flags - [kvkhUseUnderlying];
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.chkVKSplitCtrlAltClick(Sender: TObject);
|
|
var
|
|
i, j: Integer;
|
|
Found: Boolean;
|
|
begin
|
|
if FVKSetup then Exit;
|
|
|
|
FVKSetup := True;
|
|
try
|
|
if not chkVKSplitCtrlAlt.Checked then
|
|
begin
|
|
{ Check if any lctrl/lalt/rctrl/alt are currently defined, }
|
|
{ warn that they will all be merged and some entries may be }
|
|
{ lost if they conflict }
|
|
|
|
Found := False;
|
|
for i := 0 to FVK.Keys.Count - 1 do
|
|
if FVK.Keys[i].HasShift(KVKS_LCTRL or KVKS_RCTRL or KVKS_LALT or KVKS_RALT) then
|
|
begin
|
|
Found := True;
|
|
Break;
|
|
end;
|
|
|
|
if Found and (MessageDlg('You have already defined some keys to have left or right-specific states.'+
|
|
' If you continue, these shift states will be merged and you may lose some key states.'#13#10#13#10 +
|
|
'Continue and merge shift states?', mtConfirmation, mbOkCancel, 0) = mrCancel) then
|
|
begin
|
|
chkVKSplitCtrlAlt.Checked := True;
|
|
Exit;
|
|
end;
|
|
|
|
FVK.Header.Flags := FVK.Header.Flags - [kvkhAltGr];
|
|
kbdOnScreen.LRShift := False;
|
|
i := 0;
|
|
while i < FVK.Keys.Count do
|
|
begin
|
|
Found := False;
|
|
if FVK.Keys[i].HasShift(KVKS_LCTRL or KVKS_RCTRL) then
|
|
begin
|
|
FVK.Keys[i].Shift := (FVK.Keys[i].Shift and not (KVKS_LCTRL or KVKS_RCTRL)) or KVKS_CTRL;
|
|
Found := True;
|
|
end;
|
|
if FVK.Keys[i].HasShift(KVKS_LALT or KVKS_RALT) then
|
|
begin
|
|
FVK.Keys[i].Shift := (FVK.Keys[i].Shift and not (KVKS_LALT or KVKS_RALT)) or KVKS_ALT;
|
|
Found := True;
|
|
end;
|
|
if Found then
|
|
begin
|
|
Found := False;
|
|
for j := 0 to i-1 do
|
|
begin
|
|
if (FVK.Keys[j].Shift = FVK.Keys[i].Shift) and (FVK.Keys[j].VKey = FVK.Keys[i].VKey) then
|
|
begin
|
|
Found := True;
|
|
FVK.Keys.Delete(i);
|
|
Break;
|
|
end;
|
|
end;
|
|
end;
|
|
if not Found then Inc(i);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
{ Warn that all ctrl/alt will be set to lctrl/alt }
|
|
|
|
Found := False;
|
|
for i := 0 to FVK.Keys.Count - 1 do
|
|
if FVK.Keys[i].HasShift(KVKS_CTRL or KVKS_ALT) then
|
|
begin
|
|
Found := True;
|
|
Break;
|
|
end;
|
|
|
|
if Found and (MessageDlg('You have already defined some keys to have alt or ctrl states.'+
|
|
' If you continue, these shift states will be converted to left-alt and left-ctrl respectively.'#13#10#13#10 +
|
|
'Continue and convert shift states?', mtConfirmation, mbOkCancel, 0) = mrCancel) then
|
|
begin
|
|
chkVKSplitCtrlAlt.Checked := False;
|
|
Exit;
|
|
end;
|
|
|
|
FVK.Header.Flags := FVK.Header.Flags + [kvkhAltGr];
|
|
kbdOnScreen.LRShift := True;
|
|
i := 0;
|
|
while i < FVK.Keys.Count do
|
|
begin
|
|
if FVK.Keys[i].HasShift(KVKS_CTRL) then
|
|
FVK.Keys[i].Shift := (FVK.Keys[i].Shift and not KVKS_CTRL) or KVKS_LCTRL;
|
|
if FVK.Keys[i].HasShift(KVKS_ALT) then
|
|
FVK.Keys[i].Shift := (FVK.Keys[i].Shift and not KVKS_ALT) or KVKS_LALT;
|
|
Inc(i);
|
|
end;
|
|
end;
|
|
|
|
VK_SetAllKeyDetails;
|
|
if not FVKLoading then VKModified := True;
|
|
finally
|
|
FVKSetup := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.cmdBrowseKeyBitmapClick(Sender: TObject);
|
|
var
|
|
k: TVisualKeyboardKey;
|
|
FBitmap: Vcl.Graphics.TBitmap;
|
|
FPicture: TPicture;
|
|
begin
|
|
if dlgBrowseForKeyBitmap.Execute then
|
|
begin
|
|
VKModified := True;
|
|
k := VK_GetCurrentKey;
|
|
if not Assigned(k) then
|
|
begin
|
|
k := TVisualKeyboardKey.Create;
|
|
k.VKey := kbdOnScreen.SelectedKey.USVKey;
|
|
k.Shift := ExtShiftStateToVkShiftState(kbdOnScreen.ShiftState);
|
|
if FVKUnicode then k.Flags := [kvkkUnicode];
|
|
FVK.Keys.Add(k);
|
|
end;
|
|
|
|
FBitmap := Vcl.Graphics.TBitmap.Create;
|
|
try
|
|
FPicture := TPicture.Create;
|
|
try
|
|
FPicture.LoadFromFile(dlgBrowseForKeyBitmap.FileName);
|
|
FBitmap.Width := FPicture.Width;
|
|
FBitmap.Height := FPicture.Height;
|
|
FBitmap.Canvas.Draw(0, 0, FPicture.Graphic);
|
|
finally
|
|
FPicture.Free;
|
|
end;
|
|
k.Bitmap := FBitmap;
|
|
finally
|
|
FBitmap.Free;
|
|
end;
|
|
k.Flags := k.Flags + [kvkkBitmap];
|
|
rbKeyBitmap.Checked := True;
|
|
end;
|
|
|
|
VK_UpdateSelectedKeyDetails;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.cmdExportOnScreenKeyboardClick(
|
|
Sender: TObject);
|
|
begin
|
|
dlgVKSaveExport.Filter := 'Web page (*.html)|*.htm?|Image (*.bmp)|*.bmp|Image (*.png)|*.png|XML file (*.xml)|*.xml';
|
|
if dlgVKSaveExport.Execute then
|
|
ExportToFile(dlgVKSaveExport.FileName);
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.cmdImportOnScreenKeyboardClick(
|
|
Sender: TObject);
|
|
begin
|
|
if dlgVKImportXML.Execute then
|
|
with TVisualKeyboardImportXML.Create(FVK) do
|
|
try
|
|
try
|
|
ImportFromFile(dlgVKImportXML.FileName);
|
|
except
|
|
on E:EDOMParseError do // I4599
|
|
begin
|
|
ShowMessage(E.Message);
|
|
Exit;
|
|
end;
|
|
on E:EVisualKeyboardImportXML do
|
|
begin
|
|
ShowMessage(E.Message);
|
|
Exit;
|
|
end;
|
|
end;
|
|
VK_UpdateData;
|
|
EnableControls;
|
|
VKModified := True;
|
|
finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.cmdVKImportKMXClick(Sender: TObject);
|
|
(*function DoesKeyboardHaveAltGr(const AFileName: WideString): Boolean;
|
|
var
|
|
ki: TKeyboardInfo;
|
|
kfh: PKeyboardFileHeader;
|
|
kg: PKeyboardFileGroup;
|
|
kk: PKeyboardFileKey;
|
|
i: Integer;
|
|
j: Integer;
|
|
begin
|
|
Result := False;
|
|
GetKeyboardInfo(AFilename, True, ki, False);
|
|
try
|
|
kfh := PKeyboardFileHeader(ki.MemoryDump.Memory);
|
|
|
|
if kfh.dpGroupArray > ki.MemoryDump.Size - SizeOf(TKeyboardFileGroup)*kfh.cxGroupArray then Exit;
|
|
|
|
kg := PKeyboardFileGroup(Dword(kfh)+kfh.dpGroupArray);
|
|
for i := 0 to kfh.cxGroupArray - 1 do
|
|
begin
|
|
if kg.fUsingKeys then
|
|
begin
|
|
if kg.dpKeyArray > ki.MemoryDump.Size - SizeOf(TKeyboardFileKey)*kg.cxKeyArray then Exit;
|
|
kk := PKeyboardFileKey(DWord(kfh)+kg.dpKeyArray);
|
|
for j := 0 to kg.cxKeyArray - 1 do
|
|
begin
|
|
if (kk.Key and (KMX_LCTRLFLAG or KMX_RCTRLFLAG or KMX_LALTFLAG or KMX_RALTFLAG)) <> 0 then
|
|
begin
|
|
Result := True;
|
|
Exit;
|
|
end;
|
|
Inc(kk);
|
|
end;
|
|
end;
|
|
Inc(kg);
|
|
end;
|
|
finally
|
|
ki.MemoryDump.Free;
|
|
end;
|
|
end;*)
|
|
|
|
procedure AddUnderlyingLayoutKeys;
|
|
var
|
|
i: Integer;
|
|
k: TVisualKeyboardKey;
|
|
j: Integer;
|
|
begin
|
|
for i := 0 to kbdOnScreen.Keys.Count - 1 do
|
|
begin
|
|
if kbdOnScreen.Keys[i].KeyType = kktNormal then
|
|
begin
|
|
for j := 0 to High(ValidExtShiftStates) do
|
|
begin
|
|
if chkVKSplitCtrlAlt.Checked then
|
|
begin
|
|
if ValidExtShiftStates[j] * [essCtrl, essAlt] <> [] then Continue;
|
|
end
|
|
else
|
|
if ValidExtShiftStates[j] * [essLCtrl, essRCtrl, essLAlt, essRAlt] <> [] then Continue;
|
|
|
|
if ValidExtShiftStates[j] = [essAlt] then Continue;
|
|
if ValidExtShiftStates[j] = [essShift, essAlt] then Continue; // I1471:9011
|
|
|
|
if (kbdOnScreen.Keys[i].KeyCaps[j] <> '') and
|
|
(kbdOnScreen.Keys[i].KeyCaps[j][1] >= #32) then
|
|
begin
|
|
k := TVisualKeyboardKey.Create;
|
|
k.VKey := kbdOnScreen.Keys[i].VKey;
|
|
k.Shift := ExtShiftStateToVkShiftState(ValidExtShiftStates[j]);
|
|
k.Text := kbdOnScreen.Keys[i].KeyCaps[j];
|
|
if FVKUnicode then k.Flags := [kvkkUnicode] else k.Flags := [];
|
|
FVK.Keys.Add(k);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure ImportKMX(AFileName: WideString);
|
|
begin
|
|
with TfrmVisualKeyboardImportKMX.Create(Application.MainForm) do
|
|
try
|
|
Self.FVK.Keys.Clear;
|
|
|
|
if chkFillUnderlyingLayout.Checked then
|
|
AddUnderlyingLayoutKeys;
|
|
|
|
VK := Self.FVK;
|
|
|
|
FileName := AFileName;
|
|
if ShowModal = mrOk then
|
|
begin
|
|
Self.FVK.Header.AssociatedKeyboard := ChangeFileExt(ExtractFileName(AFileName), '');
|
|
if LeftRightCtrlAlt
|
|
then Self.FVK.Header.Flags := Self.FVK.Header.Flags + [kvkhAltGr]
|
|
else Self.FVK.Header.Flags := Self.FVK.Header.Flags - [kvkhAltGr];
|
|
if Show102Key
|
|
then Self.FVK.Header.Flags := Self.FVK.Header.Flags + [kvkh102]
|
|
else Self.FVK.Header.Flags := Self.FVK.Header.Flags - [kvkh102];
|
|
|
|
Self.VK_UpdateData;
|
|
Self.VKModified := True;
|
|
end;
|
|
finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
FTempKMXFileName: TTempFile; // I4181
|
|
FLocalKMXFileName: string; // I4181
|
|
begin
|
|
if Assigned(FOnImportingKMX) then
|
|
begin
|
|
FTempKMXFileName := nil;
|
|
FOnImportingKMX(Self, FTempKMXFileName);
|
|
if not Assigned(FTempKMXFileName) then Exit;
|
|
FLocalKMXFileName := FTempKMXFileName.Name; // I4181
|
|
end
|
|
else
|
|
FLocalKMXFileName := FKMXFileName;
|
|
|
|
if FLocalKMXFileName = '' then Exit;
|
|
|
|
if not FileExists(FLocalKMXFileName) then
|
|
begin
|
|
ShowMessage('You must compile the keyboard before you can import it into the on-screen keyboard.');
|
|
Exit;
|
|
end;
|
|
|
|
if FVK.Keys.Count > 0 then
|
|
if MessageDlg('Importing '+ExtractFileName(FLocalKMXFileName)+' will overwrite the existing keys defined in the Visual Keyboard.'+
|
|
' Continue and overwrite?',mtConfirmation, mbOkCancel, 0) = mrCancel then Exit;
|
|
|
|
ImportKMX(FLocalKMXFileName);
|
|
|
|
if Assigned(FOnImportingKMXFinished) and Assigned(FOnImportingKMX) then
|
|
FOnImportingKMXFinished(Self, FTempKMXFileName);
|
|
|
|
VKModified := True;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.cmdVKSelectLayoutClick(Sender: TObject);
|
|
{var
|
|
FLoadedSystemKeyboard: Boolean;
|
|
FSystemKeyboardName: string;}
|
|
begin
|
|
(* FLoadedSystemKeyboard := VKkbd.LoadedSystemKeyboard;
|
|
FSystemKeyboardName := VKkbd.SystemKeyboardName;
|
|
if SelectSystemKeyboard(frmKeymanDeveloper, FLoadedSystemKeyboard, FSystemKeyboardName) then
|
|
begin
|
|
VKkbd.SetUnderlyingLayout(LoadKeyboardLayout(PChar(FSystemKeyboardName), 0),
|
|
FLoadedSystemKeyboard, FSystemKeyboardName);
|
|
FVK.Header.UnderlyingLayout := FSystemKeyboardName;
|
|
VK_UpdateUnderlyingLayoutCaption;
|
|
end; *)
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.editVKKeyTextChange(Sender: TObject);
|
|
var
|
|
w: WideString;
|
|
k: TVisualKeyboardKey;
|
|
begin
|
|
if FVKSetup then Exit;
|
|
|
|
if not Assigned(kbdOnScreen.SelectedKey) then Exit;
|
|
|
|
rbKeyText.Checked := True;
|
|
|
|
if not FVKLoading then VKModified := True;
|
|
|
|
w := editVKKeyText.Text;
|
|
k := VK_GetCurrentKey;
|
|
if w <> '' then
|
|
begin
|
|
if not Assigned(k) then
|
|
begin
|
|
k := TVisualKeyboardKey.Create;
|
|
k.VKey := kbdOnScreen.SelectedKey.USVKey;
|
|
k.Shift := ExtShiftStateToVkShiftState(kbdOnScreen.ShiftState);
|
|
if FVKUnicode then k.Flags := [kvkkUnicode];
|
|
FVK.Keys.Add(k);
|
|
end;
|
|
|
|
k.Flags := k.Flags - [kvkkBitmap];
|
|
k.Bitmap := nil;
|
|
k.Text := w;
|
|
end
|
|
else if Assigned(k) then
|
|
begin
|
|
k.Text := '';
|
|
VK_UpdateSelectedKeyDetails;
|
|
FVK.Keys.Remove(k);
|
|
FVKCurrentKey := nil;
|
|
end;
|
|
|
|
VK_UpdateSelectedKeyDetails;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.editVKKeyTextClick(Sender: TObject);
|
|
begin
|
|
DoUpdateCharacterMap;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.editVKKeyTextKeyUp(Sender: TObject;
|
|
var Key: Word; Shift: TShiftState);
|
|
begin
|
|
DoUpdateCharacterMap;
|
|
end;
|
|
|
|
|
|
procedure TframeOnScreenKeyboardEditor.DoUpdateCharacterMap;
|
|
begin
|
|
tmrUpdateCharacterMap.Enabled := False;
|
|
tmrUpdateCharacterMap.Enabled := True;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.kbdOnScreenDragDrop(Sender,
|
|
Source: TObject; X, Y: Integer);
|
|
var
|
|
i: Integer;
|
|
k: TOnScreenKeyboardKey;
|
|
FKey: TVisualKeyboardKey;
|
|
s: WideString;
|
|
ss: Word;
|
|
begin
|
|
inherited;
|
|
k := kbdOnScreen.GetKeyAtPoint(X, Y);
|
|
if not Assigned(k) or (k.KeyType <> kktNormal) then Exit;
|
|
|
|
FKey := nil;
|
|
|
|
ss := ExtShiftStateToVkShiftState(kbdOnScreen.ShiftState);
|
|
|
|
for i := 0 to FVK.Keys.Count - 1 do
|
|
if (FVK.Keys[i].VKey = k.USVKey) and (FVK.Keys[i].Shift = ss) and
|
|
(((kvkkUnicode in FVK.Keys[i].Flags) and (FVKUnicode)) or
|
|
(not (kvkkUnicode in FVK.Keys[i].Flags) and (not FVKUnicode))) then
|
|
begin
|
|
FKey := FVK.Keys[i];
|
|
Break;
|
|
end;
|
|
|
|
if not Assigned(FKey) then
|
|
begin
|
|
FKey := TVisualKeyboardKey.Create;
|
|
FKey.VKey := k.USVKey;
|
|
FKey.Shift := ExtShiftStateToVkShiftState(kbdOnScreen.ShiftState);
|
|
if FVKUnicode then FKey.Flags := [kvkkUnicode];
|
|
FVK.Keys.Add(FKey);
|
|
end;
|
|
|
|
FKey.Bitmap := nil;
|
|
|
|
with Source as TCharacterDragObject do
|
|
s := Text[cmimCharacter];
|
|
|
|
if GetAsyncKeyState(VK_CONTROL) < 0
|
|
then FKey.Text := FKey.Text + s
|
|
else FKey.Text := s;
|
|
|
|
k.KeyGlyph := FKey.Bitmap;
|
|
k.KeyValue := FKey.Text;
|
|
|
|
if k = kbdOnScreen.SelectedKey then VK_SelectVKey;
|
|
|
|
VKModified := True;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.kbdOnScreenDragOver(Sender,
|
|
Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
|
|
var
|
|
k: TOnScreenKeyboardKey;
|
|
begin
|
|
Accept := Source is TCharacterDragObject;
|
|
|
|
if Accept then
|
|
begin
|
|
k := kbdOnScreen.GetKeyAtPoint(X, Y);
|
|
if not Assigned(k) or (k.KeyType <> kktNormal) then Accept := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.kbdOnScreenSelectionChange(Sender: TObject);
|
|
begin
|
|
VK_SelectVKey;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.kbdOnScreenShiftChange(Sender: TObject);
|
|
begin
|
|
FVKCurrentKey := nil;
|
|
VK_SetAllKeyDetails;
|
|
VK_SelectVKey;
|
|
VK_FocusKey;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.lblVKCharacterSetClick(Sender: TObject);
|
|
begin
|
|
VKUnicode := not VKUnicode;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.lblVKFontClick(Sender: TObject);
|
|
begin
|
|
if not FVKUnicode
|
|
then dlgFont.Font := FVK.Header.ANSIFont
|
|
else dlgFont.Font := FVK.Header.UnicodeFont;
|
|
|
|
if dlgFont.Execute then
|
|
begin
|
|
if not FVKUnicode
|
|
then FVK.Header.ANSIFont := dlgFont.Font
|
|
else FVK.Header.UnicodeFont := dlgFont.Font;
|
|
VK_UpdateKeyFont;
|
|
VKModified := True;
|
|
end;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.rbKeyBitmapClick(Sender: TObject);
|
|
begin
|
|
rbKeyText.Checked := False;
|
|
EnableControls;
|
|
VK_FocusKey;
|
|
if not FVKSetup and not FVKLoading then VKModified := True;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.rbKeyTextClick(Sender: TObject);
|
|
var
|
|
k: TVisualKeyboardKey;
|
|
begin
|
|
rbKeyBitmap.Checked := False;
|
|
k := VK_GetCurrentKey;
|
|
if Assigned(k) and (kvkkBitmap in k.Flags) then
|
|
begin
|
|
FVK.Keys.Remove(k);
|
|
FVKCurrentKey := nil;
|
|
end;
|
|
EnableControls;
|
|
VK_FocusKey;
|
|
if not FVKSetup and not FVKLoading then VKModified := True;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.VK_SetAllKeyDetails;
|
|
var
|
|
k: TOnScreenKeyboardKey;
|
|
i: Integer;
|
|
ss: Word;
|
|
begin
|
|
kbdOnScreen.Keys.ClearValues;
|
|
|
|
ss := ExtShiftStateToVkShiftState(kbdOnScreen.ShiftState);
|
|
for i := 0 to FVK.Keys.Count - 1 do
|
|
begin
|
|
if (FVK.Keys[i].Shift = ss) and
|
|
(((kvkkUnicode in FVK.Keys[i].Flags) and (FVKUnicode)) or
|
|
(not (kvkkUnicode in FVK.Keys[i].Flags) and (not FVKUnicode))) then
|
|
begin
|
|
k := kbdOnScreen.Keys.ItemsByUSVK[FVK.Keys[i].VKey]; // I3022
|
|
if Assigned(k) then
|
|
begin
|
|
k.KeyValue := FVK.Keys[i].Text;
|
|
k.KeyGlyph := FVK.Keys[i].Bitmap;
|
|
end;
|
|
end;
|
|
end;
|
|
// UpdateSelectedKeyDetails;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.VK_UpdateKeyFont;
|
|
var
|
|
FFont: TFont;
|
|
begin
|
|
if not FVKUnicode
|
|
then FFont := FVK.Header.ANSIFont
|
|
else FFont := FVK.Header.UnicodeFont;
|
|
|
|
editVKKeyText.Font := FFont;
|
|
|
|
kbdOnScreen.DataFont := FFont;
|
|
|
|
VKkeySample.DataFont := FFont;
|
|
VKkeySample.DataFont.Color := clBlack;
|
|
VKkeySample.Repaint;
|
|
end;
|
|
|
|
function TframeOnScreenKeyboardEditor.VK_GetCurrentKey: TVisualKeyboardKey;
|
|
var
|
|
i: Integer;
|
|
ss: Word;
|
|
begin
|
|
if Assigned(FVKCurrentKey) then
|
|
begin
|
|
Result := FVKCurrentKey;
|
|
Exit;
|
|
end;
|
|
|
|
if kbdOnScreen.SelectedKey = nil then
|
|
begin
|
|
Result := nil;
|
|
Exit;
|
|
end;
|
|
|
|
ss := ExtShiftStateToVkShiftState(kbdOnScreen.ShiftState);
|
|
for i := 0 to FVK.Keys.Count - 1 do
|
|
begin
|
|
if (FVK.Keys[i].VKey = kbdOnScreen.SelectedKey.USVKey) and (FVK.Keys[i].Shift = ss) and
|
|
(((kvkkUnicode in FVK.Keys[i].Flags) and (FVKUnicode)) or
|
|
(not (kvkkUnicode in FVK.Keys[i].Flags) and (not FVKUnicode))) then
|
|
begin
|
|
FVKCurrentKey := FVK.Keys[i];
|
|
Result := FVK.Keys[i];
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
FVKCurrentKey := nil;
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.VK_UpdateSelectedKeyDetails;
|
|
procedure SetKeyText(key: TOnScreenKeyboardKey);
|
|
begin
|
|
if key <> nil then
|
|
begin
|
|
if (key.ActiveKeyCap = '') or (key.ActiveKeyCap[1] < #32)
|
|
then VKkeySample.KeyText := key.KeyCaps[0]
|
|
else VKkeySample.KeyText := key.ActiveKeyCap;
|
|
end
|
|
else
|
|
VKkeySample.KeyText := '';
|
|
end;
|
|
var
|
|
k: TVisualKeyboardKey;
|
|
osk: TOnScreenKeyboardKey;
|
|
x: Integer;
|
|
begin
|
|
k := VK_GetCurrentKey;
|
|
if not Assigned(k) then
|
|
begin
|
|
VKkeySample.KeyData := '';
|
|
VKkeySample.KeyGlyph := nil;
|
|
SetKeyText(kbdOnScreen.SelectedKey);
|
|
end
|
|
else
|
|
begin
|
|
osk := kbdOnScreen.Keys.ItemsByUSVK[k.VKey]; // I3022
|
|
if Assigned(osk) then
|
|
begin
|
|
SetKeyText(osk);
|
|
VKkeySample.KeyData := k.Text;
|
|
VKkeySample.KeyGlyph := k.Bitmap;
|
|
osk.KeyGlyph := k.Bitmap;
|
|
osk.KeyValue := k.Text;
|
|
end;
|
|
end;
|
|
|
|
x := VKkeySample.Left;
|
|
if kbdOnScreen.ShiftState * [essAlt, essLAlt, essRAlt] <> [] then
|
|
begin
|
|
if essLAlt in kbdOnScreen.ShiftState then VKkeySampleAlt.KeyText := 'L Alt'
|
|
else if essRAlt in kbdOnScreen.ShiftState then VKkeySampleAlt.KeyText := 'R Alt'
|
|
else VKkeySampleAlt.KeyText := 'Alt';
|
|
VKkeySampleAlt.Left := x - 3 - VKkeySampleAlt.Width;
|
|
x := VKkeySampleAlt.Left;
|
|
VKkeySampleAlt.Visible := True;
|
|
end
|
|
else
|
|
VKkeySampleAlt.Visible := False;
|
|
|
|
if kbdOnScreen.ShiftState * [essCtrl, essLCtrl, essRCtrl] <> [] then
|
|
begin
|
|
if essLCtrl in kbdOnScreen.ShiftState then VKkeySampleCtrl.KeyText := 'L Ctrl'
|
|
else if essRCtrl in kbdOnScreen.ShiftState then VKkeySampleCtrl.KeyText := 'R Ctrl'
|
|
else VKkeySampleCtrl.KeyText := 'Ctrl';
|
|
VKkeySampleCtrl.Left := x - 3 - VKkeySampleCtrl.Width;
|
|
x := VKkeySampleCtrl.Left;
|
|
VKkeySampleCtrl.Visible := True;
|
|
end
|
|
else
|
|
VKkeySampleCtrl.Visible := False;
|
|
|
|
if essShift in kbdOnScreen.ShiftState then
|
|
begin
|
|
VKkeySampleShift.Left := x - 3 - VKkeySampleShift.Width;
|
|
VKkeySampleShift.Visible := True;
|
|
VKkeySampleShift.Invalidate;
|
|
end
|
|
else
|
|
VKkeySampleShift.Visible := False;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.VK_SelectVKey;
|
|
var
|
|
k: TVisualKeyboardKey;
|
|
begin
|
|
FVKSetup := True;
|
|
try
|
|
FVKCurrentKey := nil;
|
|
k := VK_GetCurrentKey;
|
|
if Assigned(k) then
|
|
begin
|
|
if kvkkBitmap in k.Flags then
|
|
begin
|
|
editVKKeyText.Text := '';
|
|
rbKeyBitmap.Checked := True;
|
|
end
|
|
else
|
|
begin
|
|
rbKeyText.Checked := True;
|
|
editVKKeyText.Text := k.Text;
|
|
editVKKeyText.SelectAll;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
rbKeyText.Checked := True;
|
|
editVKKeyText.Text := '';
|
|
end;
|
|
|
|
VK_UpdateSelectedKeyDetails;
|
|
EnableControls;
|
|
VK_FocusKey;
|
|
|
|
DoUpdateCharacterMap;
|
|
finally
|
|
FVKSetup := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.VK_UpdateData;
|
|
begin
|
|
VK_SetAllKeyDetails;
|
|
|
|
if FVK.Header.AssociatedKeyboard <> ChangeFileExt(ExtractFileName(FKMXFileName), '') then
|
|
begin
|
|
FVK.Header.AssociatedKeyboard := ChangeFileExt(ExtractFileName(FKMXFileName), '');
|
|
if not FVKLoading then VKModified := True;
|
|
end;
|
|
|
|
chkVKSplitCtrlAlt.Checked := kvkhAltGr in FVK.Header.Flags;
|
|
chkVKInclude102Key.Checked := kvkh102 in FVK.Header.Flags;
|
|
chkVKDisplayUnderlyingChars.Checked := kvkhDisplayUnderlying in FVK.Header.Flags;
|
|
chkVKOnlyUseWithUnderlyingLayout.Checked := kvkhUseUnderlying in FVK.Header.Flags;
|
|
|
|
kbdOnScreen.Display102Key := chkVKInclude102key.Checked;
|
|
kbdOnScreen.DisplayUnderlyingChar := chkVKDisplayUnderlyingChars.Checked;
|
|
kbdOnScreen.LRShift := chkVKSplitCtrlAlt.Checked;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.Load;
|
|
var
|
|
stream: TStream;
|
|
begin
|
|
FVKLoading := True;
|
|
try
|
|
FVK.Clear;
|
|
|
|
if (FileName <> '') and FileExists(FileName) then
|
|
begin
|
|
stream := TFileStream.Create(Filename, fmOpenRead or fmShareDenyWrite);
|
|
try
|
|
try
|
|
FVK.LoadFromStream(stream);
|
|
except
|
|
on E:EVisualKeyboardLoader do // I4730
|
|
begin
|
|
stream.Position := 0;
|
|
if not TVisualKeyboard.IsBinaryFile(stream) then
|
|
begin
|
|
// Load the keyboard in the source tab
|
|
pages.ActivePage := pageCode;
|
|
frameSource.LoadFromStream(stream);
|
|
Exit; // Avoids transferring empty keyboard to source
|
|
end
|
|
else
|
|
ShowMessage(E.Message);
|
|
FVK.Clear;
|
|
end;
|
|
end;
|
|
finally
|
|
stream.Free;
|
|
end;
|
|
end;
|
|
|
|
VK_UpdateData;
|
|
VK_UpdateKeyFont;
|
|
finally
|
|
FVKModified := False;
|
|
FVKLoading := False;
|
|
end;
|
|
|
|
if pages.ActivePage = pageCode then
|
|
TransferDesignToSource;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.UpdateControls;
|
|
begin
|
|
VK_UpdateCharacterSet(False);
|
|
VK_SetAllKeyDetails;
|
|
end;
|
|
|
|
function TframeOnScreenKeyboardEditor.DoesKeyboardSupportXMLVisualKeyboard: Boolean;
|
|
begin
|
|
Result := SameText(ExtractFileExt(FFileName), '.kvks');
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.Save;
|
|
begin
|
|
if FFileName = '' then
|
|
begin
|
|
if KMXFileName = '' then
|
|
begin
|
|
if dlgSaveVisualKeyboard.Execute
|
|
then FFileName := dlgSaveVisualKeyboard.FileName
|
|
else Exit;
|
|
end
|
|
else
|
|
FFileName := ChangeFileExt(KMXFileName, '.kvks');
|
|
end;
|
|
|
|
if DoesKeyboardSupportXMLVisualKeyboard then
|
|
begin
|
|
if pages.ActivePage = pageDesign then
|
|
if not TransferDesignToSource then
|
|
begin
|
|
ShowMessage('Could not transfer design page to source');
|
|
Exit;
|
|
end;
|
|
frameSource.SaveToFile(FFileName);
|
|
end
|
|
else
|
|
begin
|
|
if pages.ActivePage = pageCode then
|
|
if not TransferSourceToDesign(False) then
|
|
Exit;
|
|
FVK.SaveToFile(FFileName, kvksfBinary);
|
|
end;
|
|
|
|
// if IsKMXVersion10OrLater then
|
|
//else
|
|
FVKModified := False;
|
|
end;
|
|
|
|
function TframeOnScreenKeyboardEditor.GetBMPExportParams(FFileName: string;
|
|
var FMulti, FANSI, FUnicode: Boolean; var FPixelWidth: Integer): Boolean;
|
|
begin
|
|
Result := False;
|
|
with TfrmVisualKeyboardExportBMPParams.Create(Application.MainForm) do
|
|
try
|
|
FileName := FFileName;
|
|
if ShowModal = mrOk then
|
|
begin
|
|
Result := True;
|
|
FMulti := MultiFile;
|
|
FANSI := OutputANSI;
|
|
FUnicode := OutputUnicode;
|
|
FPixelWidth := PixelWidth;
|
|
end;
|
|
finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
function TframeOnScreenKeyboardEditor.GetHelpTopic: string;
|
|
begin
|
|
Result := SHelpTopic_Context_OnScreenKeyboardEditor;
|
|
end;
|
|
|
|
function TframeOnScreenKeyboardEditor.GetHTMLExportParams(FFileName: string;
|
|
var FFolders, FGraphical: Boolean): Boolean;
|
|
begin
|
|
Result := False;
|
|
with TfrmVisualKeyboardExportHTMLParams.Create(Application.MainForm) do
|
|
try
|
|
FileName := FFileName;
|
|
if ShowModal = mrOk then
|
|
begin
|
|
Result := True;
|
|
FFolders := Folders;
|
|
FGraphical := Graphical;
|
|
end;
|
|
finally
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
function TframeOnScreenKeyboardEditor.GetKeyFont: TFont; // I4057
|
|
begin
|
|
if not FVKUnicode
|
|
then Result := FVK.Header.ANSIFont
|
|
else Result := FVK.Header.UnicodeFont;
|
|
end;
|
|
|
|
function TframeOnScreenKeyboardEditor.GetUnderlyingLayout: HKL;
|
|
begin
|
|
Result := kbdOnScreen.UnderlyingLayout;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.ExportToFile(FileName: string);
|
|
var
|
|
FVKE: TVisualKeyboardExport;
|
|
ext: string;
|
|
FMulti, FANSI, FUnicode: Boolean;
|
|
FPixelWidth: Integer;
|
|
FFolders, FGraphical: Boolean;
|
|
begin
|
|
ext := LowerCase(ExtractFileExt(FileName));
|
|
FMulti := False;
|
|
FANSI := False;
|
|
FUnicode := False;
|
|
|
|
if (ext = '.bmp') or (ext = '.png') then
|
|
begin
|
|
if not GetBMPExportParams(FileName, FMulti, FANSI, FUnicode, FPixelWidth) then Exit;
|
|
end
|
|
else if (ext = '.html') or (ext = '.htm') then
|
|
if not GetHTMLExportParams(FileName, FFolders, FGraphical) then Exit;
|
|
|
|
Update;
|
|
|
|
Screen.Cursor := crHourglass;
|
|
try
|
|
if (ext = '.html') or (ext = '.htm') then FVKE := TVisualKeyboardExportHTML.Create(FVK, FFolders, FGraphical)
|
|
else if ext = '.bmp' then FVKE := TVisualKeyboardExportBMP.Create(FVK, FMulti, FANSI, FUnicode, FPixelWidth)
|
|
else if ext = '.png' then FVKE := TVisualKeyboardExportPNG.Create(FVK, FMulti, FANSI, FUnicode, FPixelWidth)
|
|
else if ext = '.xml' then
|
|
begin
|
|
FVKE := TVisualKeyboardExportXML.Create(FVK)
|
|
end
|
|
else
|
|
begin
|
|
ShowMessage('The export file type was not recognised. Please use HTML, BMP, PNG or XML.');
|
|
Exit;
|
|
end;
|
|
|
|
with FVKE do
|
|
try
|
|
ExportToFile(FileName);
|
|
finally
|
|
Free;
|
|
end;
|
|
finally
|
|
Screen.Cursor := crDefault;
|
|
end;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.EnableControls;
|
|
var
|
|
e: Boolean;
|
|
begin
|
|
e := True;
|
|
cmdVKImportKMX.Enabled := e;
|
|
cmdImportOnScreenKeyboard.Enabled := e;
|
|
cmdExportOnScreenKeyboard.Enabled := e;
|
|
panVK.Visible := e;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.VK_UpdateCharacterSet(FMoveRules: Boolean);
|
|
var
|
|
i, n: Integer;
|
|
FKey: TVisualKeyboardKey;
|
|
begin
|
|
{if FVKUnicode then
|
|
begin
|
|
lblVKCharacterSet.Font.Color := clBlue;
|
|
lblVKCharacterSet.Font.Style := [fsUnderline];
|
|
lblVKCharacterSet.Cursor := crHandPoint;
|
|
end
|
|
else
|
|
begin
|
|
}
|
|
// end;
|
|
|
|
if FMoveRules then
|
|
begin
|
|
if FVKUnicode then
|
|
|
|
// Delete existing keys in the destination layout
|
|
for i := FVK.Keys.Count - 1 downto 0 do
|
|
if FVKUnicode then
|
|
begin
|
|
if kvkkUnicode in FVK.Keys[i].Flags then FVK.Keys.Delete(i);
|
|
end
|
|
else
|
|
if not (kvkkUnicode in FVK.Keys[i].Flags) then FVK.Keys.Delete(i);
|
|
|
|
// Copy keys
|
|
n := FVK.Keys.Count;
|
|
for i := 0 to n - 1 do
|
|
begin
|
|
FKey := TVisualKeyboardKey.Create;
|
|
FKey.VKey := FVK.Keys[i].VKey;
|
|
FKey.Flags := FVK.Keys[i].Flags;
|
|
FKey.Shift := FVK.Keys[i].Shift;
|
|
FKey.Text := FVK.Keys[i].Text;
|
|
if Assigned(FVK.Keys[i].Bitmap) then
|
|
begin
|
|
FKey.Bitmap := Vcl.Graphics.TBitmap.Create;
|
|
FKey.Bitmap.Assign(FVK.Keys[i].Bitmap);
|
|
end;
|
|
if FVKUnicode
|
|
then FKey.Flags := FKey.Flags + [kvkkUnicode]
|
|
else FKey.Flags := FKey.Flags - [kvkkUnicode];
|
|
FVK.Keys.Add(FKey);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TframeOnScreenKeyboardEditor.VK_FocusKey;
|
|
begin
|
|
if editVKKeyText.CanFocus then
|
|
if rbKeyText.Checked
|
|
then editVKKeyText.SetFocus
|
|
else cmdBrowseKeyBitmap.SetFocus;
|
|
end;
|
|
|
|
{ ---------------------------------------------------------------------------- }
|
|
{ - Source tab - }
|
|
{ ---------------------------------------------------------------------------- }
|
|
|
|
procedure TframeOnScreenKeyboardEditor.SourceChanged(Sender: TObject);
|
|
begin
|
|
VKModified := True;
|
|
end;
|
|
|
|
end.
|