View Issue Details

IDProjectCategoryView StatusLast Update
0023082LazarusLCLpublic2018-09-13 18:10
ReporterAndrey ZubarevAssigned ToMaxim Ganetsky 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version1.0.1 (SVN)Product Build 
Target VersionFixed in Version1.10 
Summary0023082: Shortcuts and i18n
DescriptionEnglish names of shortcuts do not work after you localize your application. For example, "Up", "Down" ... etc. Work only their localized names
TagsNo tags attached.
Fixed in Revision58700
LazTarget-
Widgetset
Attached Files
  • shortcut.7z (73,068 bytes)
  • lclproc.pas.patch (4,627 bytes)
    Index: lcl/lclproc.pas
    ===================================================================
    --- lcl/lclproc.pas	(revision 55724)
    +++ lcl/lclproc.pas	(working copy)
    @@ -462,6 +462,28 @@
     //-----------------------------------------------------------------------------
     // Keys and shortcuts
     
    +const
    +    // not translated copy of menu key captions consts {SmkcXXXX} from LCLStrConsts
    +  SmkcBkSpNT = 'BkSp';
    +  SmkcTabNT = 'Tab';
    +  SmkcEscNT = 'Esc';
    +  SmkcEnterNT = 'Enter';
    +  SmkcSpaceNT = 'Space';
    +  SmkcPgUpNT = 'PgUp';
    +  SmkcPgDnNT = 'PgDn';
    +  SmkcEndNT = 'End';
    +  SmkcHomeNT = 'Home';
    +  SmkcLeftNT = 'Left';
    +  SmkcUpNT = 'Up';
    +  SmkcRightNT = 'Right';
    +  SmkcDownNT = 'Down';
    +  SmkcInsNT = 'Ins';
    +  SmkcDelNT = 'Del';
    +  SmkcShiftNT = 'Shift+';
    +  SmkcCtrlNT = 'Ctrl+';
    +  SmkcAltNT = 'Alt+';
    +  SmkcMetaNT = 'Meta+';
    +
     type
       TMenuKeyCap = (mkcBkSp, mkcTab, mkcEsc, mkcEnter, mkcSpace, mkcPgUp,
         mkcPgDn, mkcEnd, mkcHome, mkcLeft, mkcUp, mkcRight, mkcDown, mkcIns,
    @@ -469,6 +491,7 @@
     
     var
       MenuKeyCaps: array[TMenuKeyCap] of string;
    +  MenuKeyCapsNT: array[TMenuKeyCap] of string;
       MenuKeyCapsInited: boolean = false;
     
     procedure InitializeMenuKeyCaps;
    @@ -494,6 +517,27 @@
         MenuKeyCaps[mkcCtrl]:=SmkcCtrl;
         MenuKeyCaps[mkcAlt]:=SmkcAlt;
         MenuKeyCaps[mkcMeta]:=SmkcMeta;
    +
    +    MenuKeyCapsNT[mkcBkSp]:=SmkcBkSpNT;
    +    MenuKeyCapsNT[mkcTab]:=SmkcTabNT;
    +    MenuKeyCapsNT[mkcEsc]:=SmkcEscNT;
    +    MenuKeyCapsNT[mkcEnter]:=SmkcEnterNT;
    +    MenuKeyCapsNT[mkcSpace]:=SmkcSpaceNT;
    +    MenuKeyCapsNT[mkcPgUp]:=SmkcPgUpNT;
    +    MenuKeyCapsNT[mkcPgDn]:=SmkcPgDnNT;
    +    MenuKeyCapsNT[mkcEnd]:=SmkcEndNT;
    +    MenuKeyCapsNT[mkcHome]:=SmkcHomeNT;
    +    MenuKeyCapsNT[mkcLeft]:=SmkcLeftNT;
    +    MenuKeyCapsNT[mkcUp]:=SmkcUpNT;
    +    MenuKeyCapsNT[mkcRight]:=SmkcRightNT;
    +    MenuKeyCapsNT[mkcDown]:=SmkcDownNT;
    +    MenuKeyCapsNT[mkcIns]:=SmkcInsNT;
    +    MenuKeyCapsNT[mkcDel]:=SmkcDelNT;
    +    MenuKeyCapsNT[mkcShift]:=SmkcShiftNT;
    +    MenuKeyCapsNT[mkcCtrl]:=SmkcCtrlNT;
    +    MenuKeyCapsNT[mkcAlt]:=SmkcAltNT;
    +    MenuKeyCapsNT[mkcMeta]:=SmkcMetaNT;
    +
         MenuKeyCapsInited:=true;
       end;
     end;
    @@ -713,6 +757,28 @@
       end;
     end;
     
    +function KeyCodeToKeyStringNT(Key: integer): string;
    +begin
    +  case Key of
    +    VK_BACK:
    +      Result := MenuKeyCapsNT[mkcBkSp];
    +    VK_TAB:
    +      Result := MenuKeyCapsNT[mkcTab];
    +    VK_RETURN:
    +      Result := MenuKeyCapsNT[mkcEnter];
    +    VK_ESCAPE:
    +      Result := MenuKeyCapsNT[mkcEsc];
    +    VK_SPACE..VK_SPACE+8:
    +      Result := MenuKeyCapsNT[TMenuKeyCap(Key - VK_SPACE + Ord(mkcSpace))];
    +    VK_INSERT:
    +      Result := MenuKeyCapsNT[mkcIns];
    +    VK_DELETE:
    +      Result := MenuKeyCapsNT[mkcDel];
    +    else
    +      Result := '';
    +  end;
    +end;
    +
     function ShortCutToText(ShortCut: TShortCut): string;
     var
       Name: string;
    @@ -730,6 +796,23 @@
       end;
     end;
     
    +function ShortCutToTextNT(ShortCut: TShortCut): string;
    +var
    +  Name: string;
    +begin
    +  Result := '';
    +  InitializeMenuKeyCaps;
    +  Name := KeyCodeToKeyStringNT(ShortCut and $FF);
    +  if Name <> '' then
    +  begin
    +    if ShortCut and scShift <> 0 then Result := Result + MenuKeyCaps[mkcShift];
    +    if ShortCut and scCtrl <> 0 then Result := Result + MenuKeyCaps[mkcCtrl];
    +    if ShortCut and scMeta <> 0 then Result := Result + MenuKeyCaps[mkcMeta];
    +    if ShortCut and scAlt <> 0 then Result := Result + MenuKeyCaps[mkcAlt];
    +    Result := Result + Name;
    +  end;
    +end;
    +
     function TextToShortCut(const ShortCutText: string): TShortCut;
     
       function CompareFront(var StartPos: integer; const Front: string): Boolean;
    @@ -766,6 +849,14 @@
           Shift := Shift or scAlt
         else if CompareFront(StartPos, MenuKeyCaps[mkcMeta]) then
           Shift := Shift or scMeta
    +    else if CompareFront(StartPos, MenuKeyCapsNT[mkcShift]) then
    +      Shift := Shift or scShift
    +    else if CompareFront(StartPos, MenuKeyCapsNT[mkcCtrl]) then
    +      Shift := Shift or scCtrl
    +    else if CompareFront(StartPos, MenuKeyCapsNT[mkcAlt]) then
    +      Shift := Shift or scAlt
    +    else if CompareFront(StartPos, MenuKeyCapsNT[mkcMeta]) then
    +      Shift := Shift or scMeta
         else
           Break;
       end;
    @@ -778,6 +869,15 @@
           Exit;
         end;
       end;
    +  for Key := $08 to $FF do begin { Copy range from table in ShortCutToText not translated }
    +    Name := ShortCutToTextNT(Key);
    +    if (Name<>'') and (length(Name)=length(ShortCutText)-StartPos+1)
    +    and (AnsiStrLIComp(@ShortCutText[StartPos], PChar(Name), length(Name)) = 0)
    +    then begin
    +      Result := Key or Shift;
    +      Exit;
    +    end;
    +  end;
     end;
     
     function GetCompleteText(const sText: string; iSelStart: Integer;
    
    lclproc.pas.patch (4,627 bytes)

Relationships

related to 0030992 resolvedMichl Patches ShortcutToText faster, with array 
related to 0034045 closedMaxim Ganetsky Lazarus Translation of keyboard shortcuts does not change when language is switched 

Activities

2012-10-07 18:46

 

shortcut.7z (73,068 bytes)

Maxim Ganetsky

2012-10-07 22:02

developer   ~0062983

What is the problem? This behavior seems to be correct as far as I understand.

Andrey Zubarev

2012-10-07 22:17

reporter   ~0062984

Last edited: 2012-10-07 23:31

Need to work the english and localized names.

@Maxim Ganetsky
Otherwise if a program reads shortcuts from some configuration file it will need to have a separate file for every translation. Alternatively some function translating between localized shortcut names needs to be developed.

Andrey Zubarev

2017-08-21 10:02

reporter  

lclproc.pas.patch (4,627 bytes)
Index: lcl/lclproc.pas
===================================================================
--- lcl/lclproc.pas	(revision 55724)
+++ lcl/lclproc.pas	(working copy)
@@ -462,6 +462,28 @@
 //-----------------------------------------------------------------------------
 // Keys and shortcuts
 
+const
+    // not translated copy of menu key captions consts {SmkcXXXX} from LCLStrConsts
+  SmkcBkSpNT = 'BkSp';
+  SmkcTabNT = 'Tab';
+  SmkcEscNT = 'Esc';
+  SmkcEnterNT = 'Enter';
+  SmkcSpaceNT = 'Space';
+  SmkcPgUpNT = 'PgUp';
+  SmkcPgDnNT = 'PgDn';
+  SmkcEndNT = 'End';
+  SmkcHomeNT = 'Home';
+  SmkcLeftNT = 'Left';
+  SmkcUpNT = 'Up';
+  SmkcRightNT = 'Right';
+  SmkcDownNT = 'Down';
+  SmkcInsNT = 'Ins';
+  SmkcDelNT = 'Del';
+  SmkcShiftNT = 'Shift+';
+  SmkcCtrlNT = 'Ctrl+';
+  SmkcAltNT = 'Alt+';
+  SmkcMetaNT = 'Meta+';
+
 type
   TMenuKeyCap = (mkcBkSp, mkcTab, mkcEsc, mkcEnter, mkcSpace, mkcPgUp,
     mkcPgDn, mkcEnd, mkcHome, mkcLeft, mkcUp, mkcRight, mkcDown, mkcIns,
@@ -469,6 +491,7 @@
 
 var
   MenuKeyCaps: array[TMenuKeyCap] of string;
+  MenuKeyCapsNT: array[TMenuKeyCap] of string;
   MenuKeyCapsInited: boolean = false;
 
 procedure InitializeMenuKeyCaps;
@@ -494,6 +517,27 @@
     MenuKeyCaps[mkcCtrl]:=SmkcCtrl;
     MenuKeyCaps[mkcAlt]:=SmkcAlt;
     MenuKeyCaps[mkcMeta]:=SmkcMeta;
+
+    MenuKeyCapsNT[mkcBkSp]:=SmkcBkSpNT;
+    MenuKeyCapsNT[mkcTab]:=SmkcTabNT;
+    MenuKeyCapsNT[mkcEsc]:=SmkcEscNT;
+    MenuKeyCapsNT[mkcEnter]:=SmkcEnterNT;
+    MenuKeyCapsNT[mkcSpace]:=SmkcSpaceNT;
+    MenuKeyCapsNT[mkcPgUp]:=SmkcPgUpNT;
+    MenuKeyCapsNT[mkcPgDn]:=SmkcPgDnNT;
+    MenuKeyCapsNT[mkcEnd]:=SmkcEndNT;
+    MenuKeyCapsNT[mkcHome]:=SmkcHomeNT;
+    MenuKeyCapsNT[mkcLeft]:=SmkcLeftNT;
+    MenuKeyCapsNT[mkcUp]:=SmkcUpNT;
+    MenuKeyCapsNT[mkcRight]:=SmkcRightNT;
+    MenuKeyCapsNT[mkcDown]:=SmkcDownNT;
+    MenuKeyCapsNT[mkcIns]:=SmkcInsNT;
+    MenuKeyCapsNT[mkcDel]:=SmkcDelNT;
+    MenuKeyCapsNT[mkcShift]:=SmkcShiftNT;
+    MenuKeyCapsNT[mkcCtrl]:=SmkcCtrlNT;
+    MenuKeyCapsNT[mkcAlt]:=SmkcAltNT;
+    MenuKeyCapsNT[mkcMeta]:=SmkcMetaNT;
+
     MenuKeyCapsInited:=true;
   end;
 end;
@@ -713,6 +757,28 @@
   end;
 end;
 
+function KeyCodeToKeyStringNT(Key: integer): string;
+begin
+  case Key of
+    VK_BACK:
+      Result := MenuKeyCapsNT[mkcBkSp];
+    VK_TAB:
+      Result := MenuKeyCapsNT[mkcTab];
+    VK_RETURN:
+      Result := MenuKeyCapsNT[mkcEnter];
+    VK_ESCAPE:
+      Result := MenuKeyCapsNT[mkcEsc];
+    VK_SPACE..VK_SPACE+8:
+      Result := MenuKeyCapsNT[TMenuKeyCap(Key - VK_SPACE + Ord(mkcSpace))];
+    VK_INSERT:
+      Result := MenuKeyCapsNT[mkcIns];
+    VK_DELETE:
+      Result := MenuKeyCapsNT[mkcDel];
+    else
+      Result := '';
+  end;
+end;
+
 function ShortCutToText(ShortCut: TShortCut): string;
 var
   Name: string;
@@ -730,6 +796,23 @@
   end;
 end;
 
+function ShortCutToTextNT(ShortCut: TShortCut): string;
+var
+  Name: string;
+begin
+  Result := '';
+  InitializeMenuKeyCaps;
+  Name := KeyCodeToKeyStringNT(ShortCut and $FF);
+  if Name <> '' then
+  begin
+    if ShortCut and scShift <> 0 then Result := Result + MenuKeyCaps[mkcShift];
+    if ShortCut and scCtrl <> 0 then Result := Result + MenuKeyCaps[mkcCtrl];
+    if ShortCut and scMeta <> 0 then Result := Result + MenuKeyCaps[mkcMeta];
+    if ShortCut and scAlt <> 0 then Result := Result + MenuKeyCaps[mkcAlt];
+    Result := Result + Name;
+  end;
+end;
+
 function TextToShortCut(const ShortCutText: string): TShortCut;
 
   function CompareFront(var StartPos: integer; const Front: string): Boolean;
@@ -766,6 +849,14 @@
       Shift := Shift or scAlt
     else if CompareFront(StartPos, MenuKeyCaps[mkcMeta]) then
       Shift := Shift or scMeta
+    else if CompareFront(StartPos, MenuKeyCapsNT[mkcShift]) then
+      Shift := Shift or scShift
+    else if CompareFront(StartPos, MenuKeyCapsNT[mkcCtrl]) then
+      Shift := Shift or scCtrl
+    else if CompareFront(StartPos, MenuKeyCapsNT[mkcAlt]) then
+      Shift := Shift or scAlt
+    else if CompareFront(StartPos, MenuKeyCapsNT[mkcMeta]) then
+      Shift := Shift or scMeta
     else
       Break;
   end;
@@ -778,6 +869,15 @@
       Exit;
     end;
   end;
+  for Key := $08 to $FF do begin { Copy range from table in ShortCutToText not translated }
+    Name := ShortCutToTextNT(Key);
+    if (Name<>'') and (length(Name)=length(ShortCutText)-StartPos+1)
+    and (AnsiStrLIComp(@ShortCutText[StartPos], PChar(Name), length(Name)) = 0)
+    then begin
+      Result := Key or Shift;
+      Exit;
+    end;
+  end;
 end;
 
 function GetCompleteText(const sText: string; iSelStart: Integer;
lclproc.pas.patch (4,627 bytes)

Andrey Zubarev

2017-08-21 10:03

reporter   ~0102281

Try fix it, please review lclproc.pas.patch

CudaText man

2018-07-30 14:27

reporter   ~0109757

@Andrey

+function ShortCutToTextNT(ShortCut: TShortCut): string;
...
+ Name := KeyCodeToKeyStringNT(ShortCut and $FF);
+ if Name <> '' then
+ begin
+ if ShortCut and scShift <> 0 then Result := Result + MenuKeyCaps[mkcShift];
+ if ShortCut and scCtrl <> 0 then Result := Result + MenuKeyCaps[mkcCtrl];
+ if ShortCut and scMeta <> 0 then Result := Result + MenuKeyCaps[mkcMeta];
+ if ShortCut and scAlt <> 0 then Result := Result + MenuKeyCaps[mkcAlt];

in function *NT you use _translated_ string ManyKeyCaps w/o NT.

Maxim Ganetsky

2018-08-14 00:33

developer   ~0110023

Last edited: 2018-08-14 00:33

View 2 revisions

Added TextToShortCutRaw and ShortCutToTextRaw functions, which expect/have UNlocalized input/output. You are advised to use them for config purposes.

TextToShortCut and ShortCutToText behavior remains unchanged (locale dependent), as it seems to be Delphi compatible.

Please test and close if OK.

Andrey Zubarev

2018-09-13 18:10

reporter   ~0110721

Thanks!

Issue History

Date Modified Username Field Change
2012-10-07 18:46 Andrey Zubarev New Issue
2012-10-07 18:46 Andrey Zubarev File Added: shortcut.7z
2012-10-07 22:02 Maxim Ganetsky LazTarget => -
2012-10-07 22:02 Maxim Ganetsky Note Added: 0062983
2012-10-07 22:02 Maxim Ganetsky Status new => feedback
2012-10-07 22:17 Andrey Zubarev Note Added: 0062984
2012-10-07 23:19 Maxim Ganetsky Status feedback => acknowledged
2012-10-07 23:31 Maxim Ganetsky Note Edited: 0062984
2017-08-21 10:02 Andrey Zubarev File Added: lclproc.pas.patch
2017-08-21 10:03 Andrey Zubarev Note Added: 0102281
2017-08-21 13:11 Michl Relationship added related to 0030992
2018-07-28 22:18 wp Relationship added related to 0034045
2018-07-30 14:27 CudaText man Note Added: 0109757
2018-08-01 01:38 Maxim Ganetsky Assigned To => Maxim Ganetsky
2018-08-01 01:38 Maxim Ganetsky Status acknowledged => assigned
2018-08-14 00:33 Maxim Ganetsky Fixed in Revision => 58700
2018-08-14 00:33 Maxim Ganetsky Note Added: 0110023
2018-08-14 00:33 Maxim Ganetsky Status assigned => resolved
2018-08-14 00:33 Maxim Ganetsky Fixed in Version => 1.10
2018-08-14 00:33 Maxim Ganetsky Resolution open => fixed
2018-08-14 00:33 Maxim Ganetsky Note Edited: 0110023 View Revisions
2018-09-13 18:10 Andrey Zubarev Note Added: 0110721
2018-09-13 18:10 Andrey Zubarev Status resolved => closed