mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-09 02:28:27 +01:00
LCL: Simplify code dealing with ampersands (&). Remove duplicate code.
git-svn-id: trunk@62493 -
This commit is contained in:
parent
2282f707cf
commit
63cc527b35
@ -95,6 +95,7 @@ function StringCase(const AString: String; const ACase: array of String; const A
|
|||||||
|
|
||||||
// PChar
|
// PChar
|
||||||
function SamePChar(P1, P2: PChar): boolean;
|
function SamePChar(P1, P2: PChar): boolean;
|
||||||
|
function StrLScan(P: PChar; c: Char; MaxLen: Cardinal): PChar;
|
||||||
|
|
||||||
// Like IsValidIdent() in FPC 3.1.
|
// Like IsValidIdent() in FPC 3.1.
|
||||||
function LazIsValidIdent(const Ident: string; AllowDots: Boolean = False;
|
function LazIsValidIdent(const Ident: string; AllowDots: Boolean = False;
|
||||||
@ -1255,6 +1256,20 @@ begin
|
|||||||
Result:=False;
|
Result:=False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function StrLScan(P: PChar; c: Char; MaxLen: Cardinal): PChar;
|
||||||
|
// Like StrScan() but only scan to MaxLen. Also check for Nil P before scanning.
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
Result:=Nil;
|
||||||
|
if P=Nil then Exit;
|
||||||
|
for i:=0 to MaxLen-1 do
|
||||||
|
begin
|
||||||
|
if P[i]=#0 then Exit; // End of the string, c was not found.
|
||||||
|
if P[i]=c then Exit(@P[i]); // Found!
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function LazIsValidIdent(const Ident: string; AllowDots: Boolean = False;
|
function LazIsValidIdent(const Ident: string; AllowDots: Boolean = False;
|
||||||
StrictDots: Boolean = False): Boolean;
|
StrictDots: Boolean = False): Boolean;
|
||||||
// This is a copy of IsValidIdent from FPC 3.1.
|
// This is a copy of IsValidIdent from FPC 3.1.
|
||||||
|
|||||||
20
lcl/forms.pp
20
lcl/forms.pp
@ -2108,21 +2108,17 @@ var
|
|||||||
begin
|
begin
|
||||||
ACaption := Str;
|
ACaption := Str;
|
||||||
Result := false;
|
Result := false;
|
||||||
|
repeat
|
||||||
position := UTF8Pos(AmpersandChar, ACaption);
|
position := UTF8Pos(AmpersandChar, ACaption);
|
||||||
// if AmpersandChar is on the last position then there is nothing to underscore, ignore this character
|
// Not found or found at the end of string. Nothing to underscore.
|
||||||
while (position > 0) and (position < UTF8Length(ACaption)) do
|
if (position <= 0) or (position >= UTF8Length(ACaption)) then break;
|
||||||
begin
|
|
||||||
FoundChar := UTF8Copy(ACaption, position+1, 1);
|
FoundChar := UTF8Copy(ACaption, position+1, 1);
|
||||||
// two AmpersandChar characters together are not valid hot key
|
// two AmpersandChar characters together are not valid hot key
|
||||||
if FoundChar <> AmpersandChar then begin
|
if FoundChar = AmpersandChar then
|
||||||
Result := UTF8UpperCase(UTF16ToUTF8(WideString(WideChar(VK)))) = UTF8UpperCase(FoundChar);
|
UTF8Delete(ACaption, 1, position+1)
|
||||||
exit;
|
else
|
||||||
end
|
Exit(UTF8UpperCase(UTF16ToUTF8(WideString(WideChar(VK)))) = UTF8UpperCase(FoundChar));
|
||||||
else begin
|
until false;
|
||||||
UTF8Delete(ACaption, 1, position+1);
|
|
||||||
position := UTF8Pos(AmpersandChar, ACaption);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|||||||
@ -9071,22 +9071,16 @@ procedure GetTextExtentIgnoringAmpersands(TheFont: TGtkIntfFont;
|
|||||||
Str : PChar; StrLength: integer;
|
Str : PChar; StrLength: integer;
|
||||||
lbearing, rbearing, width, ascent, descent : Pgint);
|
lbearing, rbearing, width, ascent, descent : Pgint);
|
||||||
var
|
var
|
||||||
NewStr : PChar;
|
NewStr: PChar;
|
||||||
i: integer;
|
|
||||||
begin
|
begin
|
||||||
NewStr:=Str;
|
// check if Str contains an ampersand before removing them all.
|
||||||
// first check if Str contains an ampersand:
|
if StrLScan(Str, '&', StrLength) <> nil then
|
||||||
if (Str<>nil) then begin
|
NewStr := RemoveAmpersands(Str, StrLength)
|
||||||
i:=0;
|
else
|
||||||
while (Str[i]<>'&') and (i<StrLength) do inc(i);
|
NewStr := Str;
|
||||||
if i<StrLength then begin
|
|
||||||
NewStr := RemoveAmpersands(Str, StrLength);
|
|
||||||
StrLength:=StrLen(NewStr);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
gdk_text_extents(TheFont, NewStr, StrLength,
|
gdk_text_extents(TheFont, NewStr, StrLength,
|
||||||
lbearing, rBearing, width, ascent, descent);
|
lbearing, rBearing, width, ascent, descent);
|
||||||
if NewStr<>Str then
|
if NewStr <> Str then
|
||||||
StrDispose(NewStr);
|
StrDispose(NewStr);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
@ -21,9 +21,13 @@ unit gtk3objects;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, Graphics, types, LCLType, LCLProc, LazUTF8, IntegerList,
|
Classes, SysUtils, Types, FPCanvas,
|
||||||
LazGtk3, LazGdk3, LazGObject2, LazPango1, LazPangoCairo1, LazGdkPixbuf2,
|
// LazUtils
|
||||||
LazGLib2, LazCairo1, FPCanvas;
|
LazUTF8, IntegerList, LazStringUtils,
|
||||||
|
// LCL
|
||||||
|
LCLType, LCLProc, Graphics,
|
||||||
|
LazGtk3, LazGdk3, LazGObject2, LazGLib2, LazGdkPixbuf2,
|
||||||
|
LazPango1, LazPangoCairo1, LazCairo1;
|
||||||
|
|
||||||
type
|
type
|
||||||
TGtk3DeviceContext = class;
|
TGtk3DeviceContext = class;
|
||||||
@ -1874,67 +1878,6 @@ begin
|
|||||||
Result := StringReplace(Result, '&', '_', [rfReplaceAll]);
|
Result := StringReplace(Result, '&', '_', [rfReplaceAll]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{-------------------------------------------------------------------------------
|
|
||||||
function RemoveAmpersands(Src: PChar; LineLength : Longint) : PChar;
|
|
||||||
|
|
||||||
Creates a new PChar removing all escaping ampersands.
|
|
||||||
-------------------------------------------------------------------------------}
|
|
||||||
function RemoveAmpersands(Src: PChar; LineLength : Longint) : PChar;
|
|
||||||
var
|
|
||||||
i, j: Longint;
|
|
||||||
ShortenChars, NewLength, SrcLength: integer;
|
|
||||||
begin
|
|
||||||
// count ampersands and find first ampersand
|
|
||||||
ShortenChars:= 0; // chars to delete
|
|
||||||
SrcLength:= LineLength;
|
|
||||||
|
|
||||||
{ Look for amperands. If found, check if it is an escaped ampersand.
|
|
||||||
If it is, don't count it in. }
|
|
||||||
i:=0;
|
|
||||||
while i<SrcLength do
|
|
||||||
begin
|
|
||||||
if Src[i] = '&' then
|
|
||||||
begin
|
|
||||||
if (i < SrcLength - 1) and (Src[i+1] = '&') then
|
|
||||||
begin
|
|
||||||
// escaping ampersand found
|
|
||||||
inc(ShortenChars);
|
|
||||||
inc(i,2);
|
|
||||||
Continue;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
inc(ShortenChars);
|
|
||||||
end;
|
|
||||||
inc(i);
|
|
||||||
end;
|
|
||||||
// create new PChar
|
|
||||||
NewLength:= SrcLength - ShortenChars;
|
|
||||||
|
|
||||||
Result:=StrAlloc(NewLength+1); // +1 for #0 char at end
|
|
||||||
|
|
||||||
// copy string without ampersands
|
|
||||||
i:=0;
|
|
||||||
j:=0;
|
|
||||||
while (j < NewLength) do begin
|
|
||||||
if Src[i] <> '&' then begin
|
|
||||||
// copy normal char
|
|
||||||
Result[j]:= Src[i];
|
|
||||||
end else begin
|
|
||||||
// ampersand
|
|
||||||
if (i < (SrcLength - 1)) and (Src[i+1] = '&') then begin
|
|
||||||
// escaping ampersand found
|
|
||||||
inc(i);
|
|
||||||
Result[j]:='&';
|
|
||||||
end else
|
|
||||||
// delete single ampersand
|
|
||||||
dec(j);
|
|
||||||
end;
|
|
||||||
Inc(i);
|
|
||||||
Inc(j);
|
|
||||||
end;
|
|
||||||
Result[NewLength]:=#0;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{-------------------------------------------------------------------------------
|
{-------------------------------------------------------------------------------
|
||||||
function GetTextExtentIgnoringAmpersands(TheFont: PGDKFont;
|
function GetTextExtentIgnoringAmpersands(TheFont: PGDKFont;
|
||||||
Str : PChar; StrLength: integer;
|
Str : PChar; StrLength: integer;
|
||||||
@ -1949,24 +1892,15 @@ procedure GetTextExtentIgnoringAmpersands(TheFont: TGtk3Font;
|
|||||||
lbearing, rbearing, width, ascent, descent : Pgint);
|
lbearing, rbearing, width, ascent, descent : Pgint);
|
||||||
var
|
var
|
||||||
NewStr : PChar;
|
NewStr : PChar;
|
||||||
i: integer;
|
|
||||||
AMetrics: PPangoFontMetrics;
|
AMetrics: PPangoFontMetrics;
|
||||||
{ACharWidth,}ATextWidth,ATextHeight: gint;
|
{ACharWidth,}ATextWidth,ATextHeight: gint;
|
||||||
begin
|
begin
|
||||||
NewStr:=Str;
|
// check if Str contains an ampersand before removing them all.
|
||||||
// first check if Str contains an ampersand:
|
if StrLScan(Str, '&', StrLength) <> nil then
|
||||||
if (Str<>nil) then
|
NewStr := RemoveAmpersands(Str, StrLength)
|
||||||
begin
|
else
|
||||||
i:=0;
|
NewStr := Str;
|
||||||
while (Str[i]<>'&') and (i<StrLength) do inc(i);
|
TheFont.Layout^.set_text(NewStr, StrLength);
|
||||||
if i<StrLength then
|
|
||||||
begin
|
|
||||||
NewStr := RemoveAmpersands(Str, StrLength);
|
|
||||||
StrLength:=StrLen(NewStr);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
TheFont.Layout^.set_text(Str, StrLength);
|
|
||||||
|
|
||||||
// TheFont.Layout^.get_extents(@AInkRect, @ALogicalRect);
|
// TheFont.Layout^.get_extents(@AInkRect, @ALogicalRect);
|
||||||
|
|
||||||
AMetrics := pango_context_get_metrics(TheFont.Layout^.get_context, TheFont.Handle, TheFont.Layout^.get_context^.get_language);
|
AMetrics := pango_context_get_metrics(TheFont.Layout^.get_context, TheFont.Handle, TheFont.Layout^.get_context^.get_language);
|
||||||
@ -1995,7 +1929,7 @@ begin
|
|||||||
// rBearing^ := 0;
|
// rBearing^ := 0;
|
||||||
// gdk_text_extents(TheFont, NewStr, StrLength,
|
// gdk_text_extents(TheFont, NewStr, StrLength,
|
||||||
// lbearing, rBearing, width, ascent, descent);
|
// lbearing, rBearing, width, ascent, descent);
|
||||||
if NewStr<>Str then
|
if NewStr <> Str then
|
||||||
StrDispose(NewStr);
|
StrDispose(NewStr);
|
||||||
AMetrics^.unref;
|
AMetrics^.unref;
|
||||||
end;
|
end;
|
||||||
|
|||||||
@ -973,11 +973,7 @@ begin
|
|||||||
AStr := StringReplace(AStr, #9, TabString, [rfReplaceAll]);
|
AStr := StringReplace(AStr, #9, TabString, [rfReplaceAll]);
|
||||||
|
|
||||||
if (Flags and DT_NOPREFIX) <> DT_NOPREFIX then
|
if (Flags and DT_NOPREFIX) <> DT_NOPREFIX then
|
||||||
begin
|
pIndex := DeleteAmpersands(AStr)
|
||||||
pIndex := DeleteAmpersands(AStr);
|
|
||||||
if pIndex > Length(AStr) then
|
|
||||||
pIndex := -1; // String ended in '&', which was deleted
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
pIndex := -1;
|
pIndex := -1;
|
||||||
|
|
||||||
|
|||||||
@ -133,7 +133,7 @@ procedure CalculateLeftTopWidthHeight(X1,Y1,X2,Y2: integer;
|
|||||||
// Ampersands
|
// Ampersands
|
||||||
function DeleteAmpersands(var Str : String) : Integer;
|
function DeleteAmpersands(var Str : String) : Integer;
|
||||||
function RemoveAmpersands(const ASource: String): String;
|
function RemoveAmpersands(const ASource: String): String;
|
||||||
function RemoveAmpersands(Src: PChar; LineLength: Longint): PChar;
|
function RemoveAmpersands(Src: PChar; var LineLength: Longint): PChar;
|
||||||
|
|
||||||
function ComparePointers(p1, p2: Pointer): integer; inline;
|
function ComparePointers(p1, p2: Pointer): integer; inline;
|
||||||
function CompareHandles(h1, h2: THandle): integer;
|
function CompareHandles(h1, h2: THandle): integer;
|
||||||
@ -394,14 +394,15 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function RemoveAmpersands(Src: PChar; LineLength: Longint): PChar;
|
function RemoveAmpersands(Src: PChar; var LineLength: Longint): PChar;
|
||||||
var
|
var
|
||||||
s: String;
|
s: String;
|
||||||
begin
|
begin
|
||||||
SetLength(s, LineLength);
|
SetLength(s, LineLength);
|
||||||
strlcopy(PChar(s), Src, LineLength);
|
strlcopy(PChar(s), Src, LineLength);
|
||||||
s := RemoveAmpersands(s);
|
s := RemoveAmpersands(s);
|
||||||
Result := StrAlloc(Length(s)+1); // +1 for #0 char at end
|
LineLength := Length(s);
|
||||||
|
Result := StrAlloc(LineLength+1); // +1 for #0 char at end
|
||||||
strcopy(Result, PChar(s));
|
strcopy(Result, PChar(s));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
@ -2774,11 +2774,7 @@ var
|
|||||||
|
|
||||||
|
|
||||||
if (Flags and DT_NOPREFIX) <> DT_NOPREFIX then
|
if (Flags and DT_NOPREFIX) <> DT_NOPREFIX then
|
||||||
begin
|
pIndex := DeleteAmpersands(AStr)
|
||||||
pIndex := DeleteAmpersands(AStr);
|
|
||||||
if pIndex > Length(AStr) then
|
|
||||||
pIndex := -1; // String ended in '&', which was deleted
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
pIndex := -1;
|
pIndex := -1;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user