View Issue Details

IDProjectCategoryView StatusLast Update
0036255LazarusWidgetsetpublic2019-11-04 15:35
ReporterAlexey Tor.Assigned ToZeljan Rikalo 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionreopened 
PlatformUbuntu 19 x64OSOS Version
Product Version2.1 (SVN)Product Build 
Target VersionFixed in Version 
Summary0036255: gtk3: MainManu items don't handle & accelerator chars
Description& symbols are not handled in MainMenu items (top level items + sub items).
demo added.
TagsNo tags attached.
Fixed in Revision62190,62191
LazTarget-
WidgetsetGTK 3
Attached Files
  • tst-gtk3-mainmenu-accelerators.zip (2,213 bytes)
  • und.diff (3,053 bytes)
    Index: lcl/interfaces/gtk3/gtk3objects.pas
    ===================================================================
    --- lcl/interfaces/gtk3/gtk3objects.pas	(revision 62182)
    +++ lcl/interfaces/gtk3/gtk3objects.pas	(working copy)
    @@ -290,6 +290,8 @@
     function Gtk3DefaultContext: TGtk3DeviceContext;
     function Gtk3ScreenContext: TGtk3DeviceContext;
     
    +function ReplaceAmpersandsWithUnderscores(const S: string): string; inline;
    +
     implementation
     uses math, gtk3int, gtk3procs;
     
    @@ -1918,6 +1920,11 @@
     
     //various routines for text , copied from gtk2.
     
    +function ReplaceAmpersandsWithUnderscores(const S: string): string; inline;
    +begin
    +  Result := StringReplace(S, '&', '_', [rfReplaceAll]);
    +end;
    +
     {-------------------------------------------------------------------------------
       function RemoveAmpersands(Src: PChar; LineLength : Longint) : PChar;
     
    Index: lcl/interfaces/gtk3/gtk3widgets.pas
    ===================================================================
    --- lcl/interfaces/gtk3/gtk3widgets.pas	(revision 62182)
    +++ lcl/interfaces/gtk3/gtk3widgets.pas	(working copy)
    @@ -4008,7 +4008,7 @@
       for i:=0 to AToolbar.ButtonCount-1 do
       begin
         btn:=AToolBar.Buttons[i];
    -    bs:=StringReplace(btn.Caption,'&','_',[rfReplaceAll]);
    +    bs:= ReplaceAmpersandsWithUnderscores(btn.Caption);
         wicon:=nil;
         if btn is TToolButton then
         begin
    @@ -4525,7 +4525,8 @@
     
       if MenuItem.Caption <> cLineCaption then
       begin
    -    PGtkMenuItem(Result)^.set_label(PgChar(MenuItem.Caption));
    +    PGtkMenuItem(Result)^.use_underline := True;
    +    PGtkMenuItem(Result)^.set_label(PgChar(ReplaceAmpersandsWithUnderscores(MenuItem.Caption)));
         PGtkMenuItem(Result)^.set_sensitive(MenuItem.Enabled);
         // there's nothing like this in Gtk3
         // if MenuItem.RightJustify then
    @@ -6393,13 +6394,12 @@
     begin
       if IsWidgetOk then
       begin
    -    PGtkButton(FWidget)^.set_label(PgChar(StringReplace(AValue,'&','_',[rfReplaceAll])));
    +    PGtkButton(FWidget)^.set_label(PgChar(ReplaceAmpersandsWithUnderscores(AValue)));
       end;
     end;
     
     function TGtk3Button.CreateWidget(const Params: TCreateParams): PGtkWidget;
     var
    -  img:PGtkImage;
       btn:PGtkButton absolute Result;
     begin
       Result := PGtkWidget(TGtkButton.new);
    @@ -6477,8 +6477,12 @@
     end;
     
     function TGtk3CheckBox.CreateWidget(const Params: TCreateParams): PGtkWidget;
    +var
    +  check: PGtkCheckButton;
     begin
    -  Result := PGtkWidget(TGtkCheckButton.new);
    +  check := TGtkCheckButton.new;
    +  Result := PGtkWidget(check);
    +  check^.set_use_underline(True);
     end;
     
     { TGtk3RadioButton }
    @@ -6485,6 +6489,7 @@
     
     function TGtk3RadioButton.CreateWidget(const Params: TCreateParams): PGtkWidget;
     var
    +  btn: PGtkRadioButton;
       w: PGtkWidget;
       ctl, Parent: TWinControl;
       rb: TRadioButton;
    @@ -6492,7 +6497,9 @@
     begin
       if Self.LCLObject.Name='HiddenRadioButton' then
         exit;
    -  Result := PGtkWidget(TGtkRadioButton.new(nil));
    +  btn := TGtkRadioButton.new(nil);
    +  btn^.use_underline := True;
    +  Result := PGtkWidget(btn);
       ctl := Self.LCLObject;
       if Assigned(ctl) then
       begin
    
    und.diff (3,053 bytes)
  • tog.diff (542 bytes)
    Index: lcl/interfaces/gtk3/gtk3widgets.pas
    ===================================================================
    --- lcl/interfaces/gtk3/gtk3widgets.pas	(revision 62190)
    +++ lcl/interfaces/gtk3/gtk3widgets.pas	(working copy)
    @@ -6455,8 +6455,12 @@
     end;
     
     function TGtk3ToggleButton.CreateWidget(const Params: TCreateParams): PGtkWidget;
    +var
    +  btn: PGtkToggleButton;
     begin
    -  Result := PGtkWidget(TGtkToggleButton.new);
    +  btn := TGtkToggleButton.new;
    +  btn^.use_underline := True;
    +  Result := PGtkWidget(btn);
     end;
     
     { TGtk3CheckBox }
    
    tog.diff (542 bytes)

Activities

Alexey Tor.

2019-11-03 18:38

reporter  

tst-gtk3-mainmenu-accelerators.zip (2,213 bytes)

Alexey Tor.

2019-11-03 18:39

reporter  

Alexey Tor.

2019-11-03 23:59

reporter   ~0119033

Patch. adds support for & chars in TMenuItem, TCheckbox, TRadioButton. adds helper function ReplaceAmpersandsWithUnderscores.

und.diff (3,053 bytes)
Index: lcl/interfaces/gtk3/gtk3objects.pas
===================================================================
--- lcl/interfaces/gtk3/gtk3objects.pas	(revision 62182)
+++ lcl/interfaces/gtk3/gtk3objects.pas	(working copy)
@@ -290,6 +290,8 @@
 function Gtk3DefaultContext: TGtk3DeviceContext;
 function Gtk3ScreenContext: TGtk3DeviceContext;
 
+function ReplaceAmpersandsWithUnderscores(const S: string): string; inline;
+
 implementation
 uses math, gtk3int, gtk3procs;
 
@@ -1918,6 +1920,11 @@
 
 //various routines for text , copied from gtk2.
 
+function ReplaceAmpersandsWithUnderscores(const S: string): string; inline;
+begin
+  Result := StringReplace(S, '&', '_', [rfReplaceAll]);
+end;
+
 {-------------------------------------------------------------------------------
   function RemoveAmpersands(Src: PChar; LineLength : Longint) : PChar;
 
Index: lcl/interfaces/gtk3/gtk3widgets.pas
===================================================================
--- lcl/interfaces/gtk3/gtk3widgets.pas	(revision 62182)
+++ lcl/interfaces/gtk3/gtk3widgets.pas	(working copy)
@@ -4008,7 +4008,7 @@
   for i:=0 to AToolbar.ButtonCount-1 do
   begin
     btn:=AToolBar.Buttons[i];
-    bs:=StringReplace(btn.Caption,'&','_',[rfReplaceAll]);
+    bs:= ReplaceAmpersandsWithUnderscores(btn.Caption);
     wicon:=nil;
     if btn is TToolButton then
     begin
@@ -4525,7 +4525,8 @@
 
   if MenuItem.Caption <> cLineCaption then
   begin
-    PGtkMenuItem(Result)^.set_label(PgChar(MenuItem.Caption));
+    PGtkMenuItem(Result)^.use_underline := True;
+    PGtkMenuItem(Result)^.set_label(PgChar(ReplaceAmpersandsWithUnderscores(MenuItem.Caption)));
     PGtkMenuItem(Result)^.set_sensitive(MenuItem.Enabled);
     // there's nothing like this in Gtk3
     // if MenuItem.RightJustify then
@@ -6393,13 +6394,12 @@
 begin
   if IsWidgetOk then
   begin
-    PGtkButton(FWidget)^.set_label(PgChar(StringReplace(AValue,'&','_',[rfReplaceAll])));
+    PGtkButton(FWidget)^.set_label(PgChar(ReplaceAmpersandsWithUnderscores(AValue)));
   end;
 end;
 
 function TGtk3Button.CreateWidget(const Params: TCreateParams): PGtkWidget;
 var
-  img:PGtkImage;
   btn:PGtkButton absolute Result;
 begin
   Result := PGtkWidget(TGtkButton.new);
@@ -6477,8 +6477,12 @@
 end;
 
 function TGtk3CheckBox.CreateWidget(const Params: TCreateParams): PGtkWidget;
+var
+  check: PGtkCheckButton;
 begin
-  Result := PGtkWidget(TGtkCheckButton.new);
+  check := TGtkCheckButton.new;
+  Result := PGtkWidget(check);
+  check^.set_use_underline(True);
 end;
 
 { TGtk3RadioButton }
@@ -6485,6 +6489,7 @@
 
 function TGtk3RadioButton.CreateWidget(const Params: TCreateParams): PGtkWidget;
 var
+  btn: PGtkRadioButton;
   w: PGtkWidget;
   ctl, Parent: TWinControl;
   rb: TRadioButton;
@@ -6492,7 +6497,9 @@
 begin
   if Self.LCLObject.Name='HiddenRadioButton' then
     exit;
-  Result := PGtkWidget(TGtkRadioButton.new(nil));
+  btn := TGtkRadioButton.new(nil);
+  btn^.use_underline := True;
+  Result := PGtkWidget(btn);
   ctl := Self.LCLObject;
   if Assigned(ctl) then
   begin
und.diff (3,053 bytes)

Zeljan Rikalo

2019-11-04 10:23

developer   ~0119041

Please test and close if ok. Thanks for the patch.

Alexey Tor.

2019-11-04 14:44

reporter   ~0119051

And patch to support & in TToggleBox.
Seems TLabeledEdit works ok, TBitBtn works ok, TSpeedButton too.
Seems i cannot support this in TGroupBox caption.

tog.diff (542 bytes)
Index: lcl/interfaces/gtk3/gtk3widgets.pas
===================================================================
--- lcl/interfaces/gtk3/gtk3widgets.pas	(revision 62190)
+++ lcl/interfaces/gtk3/gtk3widgets.pas	(working copy)
@@ -6455,8 +6455,12 @@
 end;
 
 function TGtk3ToggleButton.CreateWidget(const Params: TCreateParams): PGtkWidget;
+var
+  btn: PGtkToggleButton;
 begin
-  Result := PGtkWidget(TGtkToggleButton.new);
+  btn := TGtkToggleButton.new;
+  btn^.use_underline := True;
+  Result := PGtkWidget(btn);
 end;
 
 { TGtk3CheckBox }
tog.diff (542 bytes)

Zeljan Rikalo

2019-11-04 15:35

developer   ~0119052

Please test and close if ok.

Issue History

Date Modified Username Field Change
2019-11-03 18:38 Alexey Tor. New Issue
2019-11-03 18:38 Alexey Tor. File Added: tst-gtk3-mainmenu-accelerators.zip
2019-11-03 18:39 Alexey Tor. File Added: Screenshot from 2019-11-03 20-38-51.png
2019-11-03 23:59 Alexey Tor. File Added: und.diff
2019-11-03 23:59 Alexey Tor. Note Added: 0119033
2019-11-04 09:20 Zeljan Rikalo Assigned To => Zeljan Rikalo
2019-11-04 09:20 Zeljan Rikalo Status new => assigned
2019-11-04 10:23 Zeljan Rikalo Status assigned => resolved
2019-11-04 10:23 Zeljan Rikalo Resolution open => fixed
2019-11-04 10:23 Zeljan Rikalo Fixed in Revision => 62190
2019-11-04 10:23 Zeljan Rikalo LazTarget => -
2019-11-04 10:23 Zeljan Rikalo Widgetset GTK 3 => GTK 3
2019-11-04 10:23 Zeljan Rikalo Note Added: 0119041
2019-11-04 14:44 Alexey Tor. File Added: tog.diff
2019-11-04 14:44 Alexey Tor. Note Added: 0119051
2019-11-04 14:44 Alexey Tor. Status resolved => assigned
2019-11-04 14:44 Alexey Tor. Resolution fixed => reopened
2019-11-04 15:35 Zeljan Rikalo Status assigned => resolved
2019-11-04 15:35 Zeljan Rikalo Fixed in Revision 62190 => 62190,62191
2019-11-04 15:35 Zeljan Rikalo Widgetset GTK 3 => GTK 3
2019-11-04 15:35 Zeljan Rikalo Note Added: 0119052