Article

From:
To:
Stefan Ineichen
Subject:
Re: XE2 with OSX Mavericks: TOpenDialog fails to work
Newsgroup:
embarcadero.public.delphi.firemonkey

Re: XE2 with OSX Mavericks: TOpenDialog fails to work

> {quote:title=Stefan Ineichen wrote:}{quote}
> I have the same issue with XE3. And it is the same with TSaveDialog. I do not have XE5, so does anyone have a solution/bugfix for this?


The following customized version works on 10.9 with XE3
Also, it's safer to call application.processMessages before the TOpendialog.execute (or TSaveDialog) like:
{code}
  Application.processMessages;
  if ODIALOG.execute
  then ...
{code}    


{code}
function TPlatformCocoa.DialogSaveFiles(var AFileName: TFileName; const AInitDir, ADefaultExt, AFilter, ATitle: string; var AFilterIndex: Integer; var AFiles: TStrings; var AOptions: TOpenOptions): Boolean;
var
  SaveFile: NSSavePanel;
  DefaultExt: string;
  Filter: NSArray;
  InitialDir: NSURL;
  outcome : NSInteger;

  function AllocFilterStr(const S: string; var Filter: NSArray): Boolean;   var     input, pattern: string;     FileTypes: array of string;     outcome, aux: TArray<string>;     i, j: Integer;     FileTypesNS: array of Pointer;     NStr: NSString;     LocObj: ILocalObject;   begin     Result := false;     // First, split the string by using '|' as a separator     input := S;     pattern := '\|';
    outcome := TRegEx.Split(input, pattern);
    pattern := '\*\.';     SetLength(FileTypes, 0);
    for i := 0 to length(outcome) - 1 do     begin       if Odd(i) then         if outcome[i] <> '*.*' then           if AnsiLeftStr(outcome[i], 2) = '*.' then           begin             // Split the string by using '*.' as a separator             aux := TRegEx.Split(outcome[i], pattern);             for j := 0 to length(aux) - 1 do             begin               aux[j] := Trim(aux[j]);               if aux[j] <> '' then               begin                 //Remove the ';' if necessary                 if AnsiEndsStr(';', aux[j]) then                   aux[j] := AnsiLeftStr(aux[j], length(aux[j]) - 1);                 SetLength(FileTypes, length(FileTypes) + 1);                 FileTypes[length(FileTypes) - 1] := aux[j];               end;             end;           end;     end;
    // create the NSArray from the FileTypes array     SetLength(FileTypesNS, Length(FileTypes));     for i := 0 to Length(FileTypes) - 1 do     begin       NStr := NSSTR(FileTypes[i]);       if Supports(NStr, ILocalObject, LocObj) then         FileTypesNS[i] := LocObj.GetObjectID;     end;     if length(FileTypes) > 0 then begin
Filter := TNSArray.Wrap(TNSArray.OCClass.arrayWithObjects(@FileTypesNS[0], Length(FileTypes)));
      Result := true;
    end;
  end;

begin   Result := False;
  //SaveFile := TNSSavePanel.Create;   SaveFile := TNSSavePanel.Wrap(TNSSavePanel.OCClass.savePanel);
  if AInitDir <> '' then   begin     InitialDir := TNSURL.Create;     InitialDir.initFileURLWithPath(NSSTR(AInitDir));     SaveFile.setDirectoryURL(InitialDir);   end;
  if AFileName <> '' then   begin     SaveFile.setNameFieldStringValue(NSSTR(AFileName));   end;
  if AFilter <> '' then   begin     if AllocFilterStr(AFilter, Filter) then       SaveFile.setAllowedFileTypes(Filter);   end;
  if ATitle <> '' then     SaveFile.setTitle(NSSTR(ATitle));
  SaveFile.retain;   try     outcome := SaveFile.runModal;     if (FModalStack <> nil) and (FModalStack.Count > 0) then       FRestartModal := True;     if outcome = NSOKButton then     begin       AFileName := UTF8ToString(SaveFile.URL.relativePath.UTF8String);       if DefaultExt <> '' then         if ExtractFileExt(AFileName) = '' then           ChangeFileExt(AFileName, DefaultExt);       Result := True;     end;   finally     SaveFile.release;   end; end;

{ Dialogs ===============================================================}
function TPlatformCocoa.DialogOpenFiles(var AFileName: TFileName; const AInitDir, ADefaultExt, AFilter, ATitle: string; var AFilterIndex: Integer; var AFiles: TStrings; var AOptions: TOpenOptions): Boolean;
var
  OpenFile: NSOpenPanel;
  DefaultExt: string;
  Filter: NSArray;
  InitialDir: NSURL;
  outcome: NSInteger;
  I: Integer;

  function AllocFilterStr(const S: string; var Filter: NSArray): Boolean;   var     input, pattern: string;     FileTypes: array of string;     outcome, aux: TArray<string>;     i, j: Integer;     FileTypesNS: array of Pointer;     NStr: NSString;     LocObj: ILocalObject;   begin     // First, split the string by using '|' as a separator     Result := false;     input := S;     pattern := '\|';
    outcome := TRegEx.Split(input, pattern);
    pattern := '\*\.';     SetLength(FileTypes, 0);
    for i := 0 to length(outcome) - 1 do     begin       if Odd(i) then         if outcome[i] <> '*.*' then           if AnsiLeftStr(outcome[i], 2) = '*.' then           begin             aux := TRegEx.Split(outcome[i], pattern);             for j := 0 to length(aux) - 1 do             begin               aux[j] := Trim(aux[j]);               if aux[j] <> '' then               begin                 if AnsiEndsStr(';', aux[j]) then                   aux[j] := AnsiLeftStr(aux[j], length(aux[j]) - 1);                 SetLength(FileTypes, length(FileTypes) + 1);                 FileTypes[length(FileTypes) - 1] := aux[j];               end;             end;           end;     end;
    // create the NSArray from the FileTypes array     SetLength(FileTypesNS, length(FileTypes));     for i := 0 to length(FileTypes) - 1 do     begin       NStr := NSSTR(FileTypes[i]);       if Supports(NStr, ILocalObject, LocObj) then         FileTypesNS[i] := LocObj.GetObjectID;     end;     if length(FileTypes) > 0 then begin
Filter := TNSArray.Wrap(TNSArray.OCClass.arrayWithObjects(@FileTypesNS[0], length(FileTypes)));
      result := true;
    end;
  end;

begin   Result := False;   DefaultExt := ADefaultExt;
  OpenFile := TNSOpenPanel.Wrap(TNSOpenPanel.OCClass.openPanel);
OpenFile.setAllowsMultipleSelection(TOpenOption.ofAllowMultiSelect in AOptions);
  OpenFile.setCanChooseFiles(True);
  // senso added
  OpenFile.setCanChooseDirectories(True);
  // senso added
  OpenFile.setTreatsFilePackagesAsDirectories(True);
  // senso added
  OpenFile.setResolvesAliases(true);



  AFiles.Clear;
  if AInitDir <> '' then   begin     InitialDir := TNSURL.Create;     InitialDir.initFileURLWithPath(NSSTR(AInitDir));     OpenFile.setDirectoryURL(InitialDir);   end;
  if AFileName <> '' then   begin     OpenFile.setNameFieldStringValue(NSSTR(AFileName));   end;
  if AFilter <> '' then   begin     if AllocFilterStr(AFilter, Filter) then       OpenFile.setAllowedFileTypes(Filter);   end;
  if ATitle <> '' then     OpenFile.setTitle(NSSTR(ATitle));
  OpenFile.retain;   try     outcome := OpenFile.runModal;     if (FModalStack <> nil) and (FModalStack.Count > 0) then       FRestartModal := True;     if outcome = NSOKButton then     begin       for I := 0 to OpenFile.URLs.count - 1 do
AFiles.Add(UTF8ToString(TNSUrl.Wrap(OpenFile.URLs.objectAtIndex(I)).relativePath.UTF8String));

      if AFiles.Count > 0 then
        AFileName := AFiles[0];

      if DefaultExt <> '' then         if ExtractFileExt(AFileName) = '' then           ChangeFileExt(AFileName, DefaultExt);       Result := True;     end;   finally     OpenFile.release;   end; end; {code}
FYI: Phrase searches are enclosed in either single or double quotes
 
 
Originally created by
Tamarack Associates
Fri, 29 Mar 2024 00:59:27 UTC
Copyright © 2009-2024
HREF Tools Corp.