(*
/*

//-------------- wrapper for {Dialog_file}

CLASS {AL4_file_dialog|s_Delphi}, NATIVE, UNTESTED :
IMPORT: {Control}, {String_functions}, {Dialog_file} .

NATIVE:@"uses AL4_file_dialog "
		"	  , Forms"
		"	{$IFDEF LINUX}"
		"	{$ELSE} "
		"			, Windows "
		"	{$ENDIF};" .
		
NATIVE: "{$I AL4_options.inc}" .		
		
*/
*)
unit AL4_file_dialog;

interface

{$I AL4_options.inc}

uses Classes, Forms, Controls, Menus,
// use AL4 to access system functions (AL4.pas inserted by the compiler into
// a project folder)
     AL4,
// use All_classes from a project folder (generated for a certain project)
     All_classes,
     AL4_form,
     StdCtrls, ExtCtrls, ComCtrls, Dialogs
     {$IFDEF LINUX} 
     {$ELSE}
     		, Windows, Messages, CommDlg
     {$ENDIF} ;


function Do_Create_dialog_file(P: Integer; X_D: Pointer;
         X_Save: Boolean): Integer;
function Do_Show_file_dialog(X_D: Integer; const def_Ext: String): Boolean;

implementation

uses SysUtils;

(*
/*
// Create file dialog, either save dialog or open dialog.
//----------------------------------------------------------------------------
FUN Create_file_dialog({Control} D|ialog_control,
    BOOL Save|_dialog) ==> INT
    :
    RESULT = do_create_file_dialog(D.Form_.Handle, D, Save) .

FUN do_create_file_dialog(INT F|orm_handle,
    {Control} D|ialog_control, BOOL Save|_dialog) ==> INT, NATIVE :
    "     Result := Do_Create_dialog_file(X_F, X_D, X_Save);" .
*/
*)
type
    TPanelDialogFile = class(TPanel)
        DialogObject: TCommonDialog;
        public destructor Destroy; override;
        {$IFnDEF LINUX}
        public procedure DialogShow(Sender: TObject);
        {$ENDIF}
    end;
    
{$IFnDEF LINUX}   //////////////////////////////////////////////////////////////

var FormCenter: TForm;
//{$IFDEF FPC}
//type TWindowProc = function(
//     p1: LongWord; p2: LongWord; p3, p4: LongInt): LongInt; stdcall;
//{$ENDIF}

function NewOpenDlgProc(
	Wnd: HWND; uMsg: DWORD; wParam: Integer; lParam: integer): integer; 
	stdcall;
var r: TRect;
	NewLeft, NewTop: Integer;
begin
	GetWindowRect(Wnd, r);
	if (uMsg = WM_SHOWWINDOW) and Assigned(FormCenter) then
	begin
		NewLeft := FormCenter.Left + (FormCenter.Width - (r.Right - r.Left)) div 2;
		NewTop := FormCenter.Top + (FormCenter.Height - (r.Bottom - r.Top)) div 2;
		if NewLeft < FormCenter.Left + 20 then
		   NewLeft := FormCenter.Left + 20;
		if NewTop < FormCenter.Top + 20 then
		   NewTop := FormCenter.Top + 20;  
  		SetWindowPos(wnd, HWND_TOP, 
  			NewLeft, 
  			NewTop, 
  			0, 0, SWP_NOSIZE);
	end;
	Result := CallWindowProc(
		{$IFDEF FPC} WNDPROC {$ENDIF} (
		Pointer(GetWindowLong(Wnd, GWL_USERDATA))),
		Wnd, uMsg, wParam, lParam);
end;

procedure TPanelDialogFile.DialogShow(
Sender: TObject);
begin
	SetWindowLong(
		GetParent(DialogObject.Handle),
		GWL_USERDATA, 
		SetWindowLong(
			GetParent(DialogObject.Handle),
			DWL_DLGPROC,
			DWORD(@NewOpenDlgProc)));
end; 

{$ENDIF} ///////////////////////////////////////////////////////////////////////

destructor TPanelDialogFile.Destroy;
begin
	{$IFDEF USE_LISTS_OF_DESCRIPTORS}
	release_control(Self);
	{$ENDIF}
	inherited;
end;

function Do_Create_dialog_file(P: Integer; X_D: Pointer;
         X_Save: Boolean): Integer;
var Parent: TAL4Column;
    D: TPanelDialogFile;
    F: TAL4Form;
begin
	{$IFDEF USE_LISTS_OF_DESCRIPTORS}
    	F := TAL4Form(All_forms[P]);
	{$ELSE}
    	F := TAL4Form(P);
	{$ENDIF}
    Parent := F.Get_current_column;
    D := TPanelDialogFile.Create(Parent);
    D.Tag := {$IFDEF FPC} IntPtr {$ELSE} Int64 {$ENDIF}(X_D);
    D.Parent := Parent;
    D.Width := 0;
    D.Height := 0;
    D.Visible := FALSE;
    //------------------------- 'create DialogObject'
    if  X_Save then
    begin
        D.DialogObject := TSaveDialog.Create(D);
        {$IFDEF FPC}
        TSaveDialog(D.DialogObject).Options := 
        TSaveDialog(D.DialogObject).Options + [ofOverwritePrompt];
        {$ENDIF}
    end
    else D.DialogObject := TOpenDialog.Create(D);
    {$IFDEF USE_LISTS_OF_DESCRIPTORS}
    	Result := allocate_control(D);
    {$ELSE}
    	Result := Integer(D);
    {$ENDIF}
end;

(*
/*
// Show file dialog, return TRUE if  file was selected.
//-----------------------------------------------------
FUN Show_file_dialog({Control} D|ialog_control) ==> BOOL, NATIVE:
	INT h|ialog_control_handle = D.Handle
	STR default_ext = D.{Dialog_file}.Default_ext
	CASE default_ext == "" ? 
		 STR ext|ensions[].Split(D.{Dialog_file}.Filter, "|")
		 ext[].Split(ext[1], ";")
		 CASE "." IN ext[0] ? 
		      default_ext = "." ext[0].After(".") ;
	;
	NATIVE @
    "    RESULT := Do_Show_file_dialog(X_h, X_default_ext);" .
*/
*)
function Get_parent_form(C: TWinControl): TForm;
begin
	Result := nil;
	while C <> nil do
	begin
		if C is TForm then begin Result := TForm(C); Exit; end;
		C := C.Parent;
	end;
end;

function Do_Show_file_dialog(X_D: Integer; const def_Ext: String): Boolean;
var DP: TPanelDialogFile;
    OD: TOpenDialog;
    SD: TSaveDialog;
    CD: C_Dialog_file;
    RD: Ref_obj;
    {$IFnDEF LINUX}
    F: TForm;
    X: HWND;
    {$ENDIF}
    oop: TOpenOptions;
    i: Integer;
    s: String;
begin
	{$IFDEF USE_LISTS_OF_DESCRIPTORS}
    	DP := TPanelDialogFile(All_controls[X_D]);
	{$ELSE}
    	DP := TPanelDialogFile(X_D);
	{$ENDIF}
	RD := ref_obj_from_control(DP);
    CD := C_Dialog_file(RD.Obj);
    OD := nil;
    //if  DP.DialogObject is TSaveDialog then
    if CD.F_Save_dialog then
    begin
        SD := DP.DialogObject as TSaveDialog;
        SD.Title := CD.F_Title;
        SD.InitialDir := CD.F_Initial_path;
        SD.DefaultExt := CD.F_Default_ext;
        SD.Filter := CD.F_Filter;
        SD.FileName := CD.F_Filename;
        if def_Ext <> '' then
        	SD.DefaultExt := def_Ext;
        {$IFnDEF LINUX}
        SD.OnShow := {$IFDEF FPC} @ {$ENDIF} DP.DialogShow;
        {$ENDIF}
    end
    else
    begin
        OD := DP.DialogObject as TOpenDialog;
        OD.Title := CD.F_Title;
        OD.InitialDir := CD.F_Initial_path;
        OD.DefaultExt := CD.F_Default_ext;
        OD.Filter := CD.F_Filter;
        OD.FileName := CD.F_Filename;
        
        oop := OD.Options;
        if CD.F_Multiselect then
        	Include(oop, ofAllowMultiSelect)
        else Exclude(oop, ofAllowMultiSelect);
        OD.Options := oop;
        
        {$IFnDEF LINUX}
        OD.OnShow := {$IFDEF FPC} @ {$ENDIF} DP.DialogShow;
        {$ENDIF}
    end;
    {$IFnDEF LINUX}
        FormCenter := Get_parent_form(DP);
    {$ENDIF}
    {$IFDEF _D6orHigher}
    	Result := DP.DialogObject.Execute;
    {$ELSE}
    	//if DP.DialogObject is TSaveDialog then
    	if CD.F_Save_dialog then
    		Result := TSaveDialog(DP.DialogObject).Execute
    	else Result := TOpenDialog(DP.DialogObject).Execute;
    {$ENDIF}
    if  Result then
    begin
        //if  DP.DialogObject is TSaveDialog then
        if CD.F_Save_dialog then
        begin
            SD := DP.DialogObject as TSaveDialog;
            {$IFDEF FPC}
            CD.F_Filename.Assign_string(SD.Filename);
            {$ELSE}
            CD.F_Filename := SD.Filename;
            {$ENDIF}
        end
          else
        begin
            OD := DP.DialogObject as TOpenDialog;
            s := OD.Filename;
            if CD.F_Multiselect then
            begin
            	s := '';
            	for i := 0 to OD.Files.Count-1 do
            	begin
            		if i > 0 then s := s + ';';
            		s := s + OD.Files[i];
            	end;
            end; 
            {$IFDEF FPC}
            CD.F_Filename.Assign_string(s);
            {$ELSE}
            CD.F_Filename := s;
            {$ENDIF}
        end;
    end;
end;

(*
/*
END
*/
*)

end.
