Adapted creation of QtFilterString for native dialogs mode.

- Fixed the formation of the filter string, searching in the list for a subsequent call to FileTypeChanged.
- In order for the extensions themselves to be displayed in the drop-down list, and not just the titles,
  Unicode characters FULLWIDTH LEFT PARENTHESIS, FULLWIDTH RIGHT PARENTHESIS are used instead of '(' and ')'.
This commit is contained in:
Sergey Larin 2021-09-16 18:24:49 +03:00
parent bf3f6dbae2
commit 72b19e5f84
2 changed files with 57 additions and 44 deletions

View File

@ -28,7 +28,7 @@ uses
// Free Pascal
Classes, SysUtils, Types,
// LCL
LCLType, LCLProc, LazUTF8, LCLIntf, LMessages, Graphics, Forms, Controls,
LCLType, LCLProc, LazUTF8, LazStringUtils, LCLIntf, LMessages, Graphics, Forms, Controls,
ComCtrls, ExtCtrls, StdCtrls, Menus, Dialogs, ImgList;
type
@ -19293,16 +19293,34 @@ end;
procedure TQtFileDialog.FilterSelectedEvent(filter: PWideString); cdecl;
var
List: TQtStringList;
index: Integer;
i, index: Integer;
s: String;
begin
if filter <> nil then
begin
List := TQtStringList.Create;
getFilters(List.Handle);
index := List.IndexOf(UTF16ToUTF8(filter^));
if index <> -1 then
TFileDialog(FDialog).IntfFileTypeChanged(index + 1);
List.Free;
try
getFilters(List.Handle);
s := UTF16ToUTF8(filter^);
index := -1;
if s <> '' then
if s[Length(s)] = ')' then // if QFileDialogDontUseNativeDialog = True
index := List.IndexOf(s)
else
begin
s := '(' + s + ')';
for i := 0 to List.Count - 1 do
if LazEndsStr(s, List[i]) then
begin
index := i;
break;
end;
end;
if index <> -1 then
TFileDialog(FDialog).IntfFileTypeChanged(index + 1);
finally
List.Free;
end;
end;
end;

View File

@ -189,15 +189,24 @@ end;
class function TQtWSFileDialog.GetQtFilterString(const AFileDialog: TFileDialog;
var ASelectedFilter: WideString): WideString;
function GetExtensionString(ASource: String; AStart, ALength: Integer): String; inline;
const
FULLWIDTH_LEFT_PARENTHESIS_UTF8 = #$EF#$BC#$88;
FULLWIDTH_RIGHT_PARENTHESIS_UTF8 = #$EF#$BC#$89;
function ReplaceExtensionDelimiter(const ASource: String): String; inline;
begin
// replace *.ext1, *.ext2 by *.ext1 *.ext2
Result := '(' + StringReplace(Copy(ASource, AStart, ALength), ';', ' ', [rfReplaceAll]) + ')';
// replace *.ext1;*.ext2 by *.ext1 *.ext2
Result := StringReplace(ASource, ';', ' ', [rfReplaceAll]);
end;
function GetExtensionString(const ASource: String): String; inline;
begin
Result := '(' + ReplaceExtensionDelimiter(ASource) + ')';
end;
var
TmpFilter, strExtensions, DialogFilter: string;
ParserState, Position, i: Integer;
TmpFilter, strExtensions, DialogFilter, S, S1: string;
ParserState, Position, i, L: Integer;
List: TStrings;
begin
{------------------------------------------------------------------------------
@ -231,61 +240,47 @@ begin
ParserState := 0;
Position := 1;
TmpFilter := AFileDialog.Filter;
DialogFilter := AFileDialog.Filter;
ASelectedFilter := '';
{we must remove all brackets since qt-45 doesn't like brackets
outside filters,so our eg. Pascal source (*.pas;*.pp) | *.pas;*.pp
becomes invalid after filters processing.}
TmpFilter := StringReplace(TmpFilter,'(','',[rfReplaceAll]);
TmpFilter := StringReplace(TmpFilter,')','',[rfReplaceAll]);
DialogFilter := TmpFilter;
TmpFilter := '';
List := TStringList.Create;
try
for i := 1 to Length(DialogFilter) do
S1 := '';
L := Length(DialogFilter);
for i := 1 to L + 1 do
begin
if Copy(DialogFilter, i, 1) = '|' then
if (i = L + 1) or (DialogFilter[i] = '|') then
begin
ParserState := ParserState + 1;
S := Copy(DialogFilter, Position, i - Position);
if ParserState = 1 then
begin
List.Add(Copy(DialogFilter, Position, i - Position));
TmpFilter := TmpFilter + Copy(DialogFilter, Position, i - Position);
S := StringReplace(S, ' (', FULLWIDTH_LEFT_PARENTHESIS_UTF8, []);
S := StringReplace(S, '(', FULLWIDTH_LEFT_PARENTHESIS_UTF8, []);
S := StringReplace(S, ')', FULLWIDTH_RIGHT_PARENTHESIS_UTF8, []);
S1 := S;
List.Add(S1);
TmpFilter := TmpFilter + S1;
end else
if ParserState = 2 then
//if ParserState = 2 then
begin
strExtensions := GetExtensionString(DialogFilter, Position, i - Position);
if Pos(strExtensions, TmpFilter) = 0 then
begin
if List.Count > 0 then
List.Strings[List.Count - 1] := List.Strings[List.Count - 1] +' '+ strExtensions;
TmpFilter := TmpFilter + ' ' + strExtensions;
end;
TmpFilter := TmpFilter + ';;';
strExtensions := GetExtensionString(S);
List.Strings[List.Count - 1] := S1 + ' ' + strExtensions;
TmpFilter := TmpFilter + ' ' + strExtensions;
if i <> L + 1 then
TmpFilter := TmpFilter + ';;';
ParserState := 0;
end;
if i <> Length(DialogFilter) then
Position := i + 1;
Position := i + 1;
end;
end;
strExtensions := GetExtensionString(DialogFilter, Position, i + 1 - Position);
if Pos(strExtensions, TmpFilter) = 0 then
begin
if List.Count > 0 then
List.Strings[List.Count - 1] := List.Strings[List.Count - 1] +' '+ strExtensions;
TmpFilter := TmpFilter + ' ' + strExtensions;
end;
// Remember that AFileDialog.FilterIndex is a 1-based index and that
// List has a zero-based index
if (AFileDialog.FilterIndex > 0) and (List.Count >= AFileDialog.FilterIndex) then