2012-10-19 12 views
8

Ho creato un programma di esempio Firemonkey (Delphi XE2) che contiene un TButton e un TSavedialog con due filtri diversi. (Il componente TSaveDialog supporta la piattaforma Win32/Win64 e OS X.)FireMonkey/Rad Studio XE2: Come posso visualizzare il filtro SaveDialog su OS X?

Funziona correttamente su Win32/Win64, ma non ora perché non mostra i filtri Savedialog su OS X (VirtualBox/OS X 10.7.x).

Come posso farlo funzionare su OS X?

procedure TForm1.Button_SaveClick(Sender: TObject); 
begin 
    SaveDialog.Filter:='Format_1 (*.fmt1)|*.fmt1|Format_2 (*.fmt2)|*.fmt2'; 

    If Savedialog.Execute Then ShowMessage(SaveDialog.FileName+#13+'Selected filterindex: '+Inttostr(SaveDialog.FilterIndex)); 
end; 

risposta

3

La finestra di dialogo Salva non è costruita in Delphi ma chiama la finestra di dialogo MAC OSX nativa (NSSavePanel). Questo non ha un filtro selezionabile dall'utente.

Quando si esegue una finestra di dialogo di salvataggio, Delphi passa il filtro come una matrice a NSSavePanel.SetAllowedFileTypes che determina quali estensioni la finestra di dialogo OSX consentirà all'utente di specificare - ma non esiste un elenco selezionabile.

Per consentire all'utente di selezionare da un elenco, è necessario creare la propria finestra di dialogo per la selezione del tipo di file e quindi eseguire tale selezione e passare al file salvato come tipo di file predefinito e l'unico elemento del filtro.

L'alternativa di creare una finestra di dialogo fileSave completamente nuova non è semplice in quanto il componente dell'albero Firemonkey sembra insistere sull'espansione di tutti i suoi nodi e quindi esegue una traversa completa di tutti i file sul disco rigido. In ogni caso, gli utenti MAC avranno familiarità con la finestra di dialogo standard.

+0

David, grazie per le tue informazioni molto utili, ma non ero troppo felice quando ho letto la tua risposta. –

+0

Ho un visualizzatore/convertitore di file in formato MS Windows 3D (geometria) (http://web.t-online.hu/karpo) che supporta 615 formati di file diversi (292 sono per il salvataggio!) E sto eseguendo il porting di questo programma sotto FireMonkey per ottenere eseguibili Win32/Win64 e OS X. Penso che userò un semplice ComboBox per selezionare il formato (e un secondo ComboBox per la selezione dai formati preferiti) e un SaveDialog per selezionare il nome del file. –

1

Avevo lo stesso problema con TOpendialog in MAC OSX: i filtri non funzionano, ma in Windows lo fanno. Ora ho risolto il problema, forse puoi usare il codice per la tua soluzione alternativa. Quei file che NON sono visualizzati in Windows sono disabilitati sotto MAC OSX, non è possibile selezionarli.

uses 
    Macapi.Foundation, Macapi.ObjectiveC, Macapi.AppKit; 


{$IFDEF MACOS} 

    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; 

function CFToDelphiString(const CFStr: CFStringRef): string; 
var 
    Range: CFRange; 
begin 
    Range.location := 0; 
    Range.length := CFStringGetLength(CFStr); 
    SetLength(Result, Range.length); 
    if Range.length = 0 then Exit; 
    CFStringGetCharacters(CFStr, Range, PWideChar(Result)); 
end; 

function NSToDelphiString(const NSStr: NSString): string; inline; 
begin 
    Result := CFToDelphiString((NSStr as ILocalObject).GetObjectID); 
end; 


    {$ENDIF} 


procedure TMainform.LoadClick(Sender: TObject); 
{$IFDEF MACOS} 
var 
    Filter: NSArray; 
    LOpenDir: NSOpenPanel; 
    {$ENDIF} 
begin 

    {$IFDEF MSWINDOWS} 
    Opendialog1.Filter:= '*.fcb|*.fcb'; 
    if Opendialog1.execute then 
    begin 
    case Opendialog1.Filterindex of 
     1: LoadPlaylist(Opendialog1.filename, false, false); 
     2: LoadPlaylist(Opendialog1.filename, false, true); 
    end; 
    end; 
    {$ENDIF} 

{$IFDEF MACOS} 
    LOpenDir := TNSOpenPanel.Wrap(TNSOpenPanel.OCClass.openPanel); 
    if AllocFilterStr('*.fcb|*.fcb', Filter) then 
    if LOpenDir.runModalForTypes(Filter)=1 then 
    LoadPlaylist(NSToDelphiString(LOpenDir.filename), false, false); 
    {$ENDIF} 
end;