Merge branch 'qt5-filedialog-native' into 'main'

QT5 Native File Dialogs

See merge request freepascal.org/lazarus/lazarus!80
This commit is contained in:
Juha Manninen 2022-02-25 09:08:04 +00:00
commit 48eac88385
2 changed files with 62 additions and 52 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

@ -158,7 +158,7 @@ end;
Params: None
Returns: Nothing
Dummy handle creator. On Qt we don´t need a Handle for common dialogs
Dummy handle creator. On Qt we don't need a Handle for common dialogs
------------------------------------------------------------------------------}
class function TQtWSCommonDialog.CreateHandle(const ACommonDialog: TCommonDialog): THandle;
begin
@ -171,7 +171,7 @@ end;
Params: None
Returns: Nothing
Dummy handle destructor. On Qt we don´t need a Handle for common dialogs
Dummy handle destructor. On Qt we don't need a Handle for common dialogs
------------------------------------------------------------------------------}
class procedure TQtWSCommonDialog.DestroyHandle(const ACommonDialog: TCommonDialog);
begin
@ -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
@ -387,9 +382,8 @@ begin
QWidget_setWindowFlags(FileDialog.Widget, QtDialog or QtWindowSystemMenuHint or QtCustomizeWindowHint);
{$endif}
{$note WE MUST USE NON NATIVE DIALOGS HERE, OTHERWISE NO SIGNALS #16532.}
QFileDialog_setOption(QFileDialogH(FileDialog.Widget),
QFileDialogDontUseNativeDialog, True);
QFileDialogDontUseNativeDialog, False);
FileDialog.AttachEvents;
@ -660,10 +654,9 @@ begin
{$ifdef darwin}
QWidget_setWindowFlags(FileDialog.Widget, QtDialog or QtWindowSystemMenuHint or QtCustomizeWindowHint);
{$endif}
{. $note WE MUST USE NON NATIVE DIALOGS HERE, OTHERWISE NO SIGNALS #16532.}
{$ifndef QT_NATIVE_DIALOGS}
QFileDialog_setOption(QFileDialogH(FileDialog.Widget),
QFileDialogDontUseNativeDialog, True);
{$ifndef QT_NATIVE_DIALOGS}
FileDialog.initializePreview(TPreviewFileDialog(ACommonDialog).PreviewFileControl);
{$endif}
FileDialog.AttachEvents;
@ -734,9 +727,8 @@ begin
QtWindowSystemMenuHint or QtCustomizeWindowHint);
{$endif}
{$note qt-4.5.0,qt-4.5.1 currently supports macosx only.}
QFileDialog_setOption(QFileDialogH(FileDialog.Widget),
QFileDialogDontUseNativeDialog, True);
QFileDialogDontUseNativeDialog, False);
FileDialog.setFileMode(QFileDialogDirectoryOnly);