LCL, carbon, fix filterindex and add trigger some missing dialog events, fix issue #25086

git-svn-id: trunk@43061 -
This commit is contained in:
jesus 2013-10-03 03:31:11 +00:00
parent 5c1eabea87
commit 1047128fbb

View File

@ -95,7 +95,76 @@ uses
var
Filters: TStringList; // filter text + TMaskList in object
FilterIndex: Integer;
procedure DescListToFiles(DescList: AEDescListPtr; FileDialog: TFileDialog);
var
FileCount, FileIdx: Integer;
Keyword: AEKeyword;
FileDesc: AEDesc;
FileRef: FSRef;
FileURL: CFURLRef;
FileCFStr: CFStringRef;
FileName: string;
begin
//DebugLnEnter('DescListToFiles INIT');
//if OSError(NavDialogGetReply(DialogRef, DialogReply{%H-}), Self, SShowModal,
// 'NavDialogGetReply') then Exit; // Get user's selection
//
FileDialog.Files.Clear;
if DescList=nil then begin
DebugLnExit('DescList is nil, EXIT');
exit;
end;
if (DescList=nil) or OSError(AECountItems(DescList^, FileCount{%H-}), FileDialog,
SShowModal, 'AECountItems') then Exit;
for FileIdx := 1 to FileCount do
begin
if OSError(AEGetNthDesc(DescList^, FileIdx, typeFSRef,
@Keyword, FileDesc{%H-}), FileDialog, SShowModal, 'AEGetNthDesc') then Exit;
// Get file reference
if OSError(AEGetDescData(FileDesc, @FileRef, SizeOf(FSRef)), FileDialog,
SShowModal, 'AEGetDescData') then Exit;
if OSError(AEDisposeDesc(FileDesc), FileDialog, SShowModal,
'AEDisposeDesc') then Exit;
FileURL := CFURLCreateFromFSRef(kCFAllocatorDefault, FileRef); // Get URL
FileCFStr := CFURLCopyFileSystemPath(FileURL, kCFURLPOSIXPathStyle); // Get path
FileName := CFStringToStr(FileCFStr);
//DebugLn('%d/%d FileName=%s',[FileIdx, FileCount, FileName]);
FileDialog.Files.Add(FileName);
FreeCFString(FileURL);
FreeCFString(FileCFStr);
// Note: Previous 5 lines replace next 2 lines and eliminate need
// to decide what size to make FileBuf array.
// See http://developer.apple.com/technotes/tn2002/tn2078.html
// FSRefMakePath(FileRef, @FileBuf, SizeOf(FileBuf)); {Get file path}
// FileDialog.Files.Add(string(FileBuf)); //FileBuf contains UTF8 C string
end;
FileDialog.FileName := FileDialog.Files.Strings[0];
//if FileDialog.FCompStyle=csSaveFileDialog then
// FileDialog.FileName := FileDialog.FileName + PathDelim +
// CFStringToStr(NavDialogGetSaveFileName(DialogRef));
// {Note: Not at all clear from Apple docs that NavReplyRecord.Selection
// returns only path to file's folder with Save dialog. Also, what they
// mean by the "full file name" returned by NavDialogGetSaveFileName
// must mean extension and not path to file's folder.}
// Dispose of data that record points to (?)
//if OSError(NavDisposeReply(DialogReply), FileDialog, SShowModal,
// 'NavDisposeReply') then Exit;
//FileDialog.FilterIndex := FilterIndex + 1;
//DebugLnExit('DescListToFiles END Files.Count=%d',[FileDialog.Files.Count]);
end;
function FilterCallback(var theItem: AEDesc; info: NavFileOrFolderInfoPtr;
callbackUD: UnivPtr; {%H-}filterMode: NavFilterModes): Boolean; mwpascal;
@ -111,14 +180,15 @@ var
FileCFStr: CFStringRef;
FilePath: string;
FilterMask: TMaskList;
FileDialog: TFileDialog;
AIndex: Integer;
begin
Result := True;
FileDialog := TFileDialog(CallbackUD);
if (FileDialog = nil) or (FileDialog.Filter='') then // No user data passed?
Exit;
if callbackUD = nil then // No user data passed?
Exit;
if TFileDialog(callbackUD).Filter = '' then // No filter passed?
Exit;
if TFileDialog(callbackUD) is TOpenDialog then
if FileDialog is TOpenDialog then
begin
if info^.isFolder then // Don't dim folder?
Exit;
@ -144,8 +214,9 @@ begin
FreeCFString(FileCFStr);
FilterMask := nil;
if (FilterIndex >= 0) and (FilterIndex < Filters.Count) then
FilterMask := TMaskList(Filters.Objects[FilterIndex]);
AIndex := FileDialog.FilterIndex - 1;
if (AIndex >= 0) and (AIndex < Filters.Count) then
FilterMask := TMaskList(Filters.Objects[AIndex]);
Result := (FilterMask = nil) or FilterMask.Matches(ExtractFilename(FilePath));
//DebugLn('FilterCallback ' + DbgS(FilterMask) + ' ' + ExtractFilename(FilePath) + ' ' + DbgS(Result));
@ -160,29 +231,25 @@ var
DirCFStr: CFStringRef;
PMenuSpec: NavMenuItemSpecPtr;
MenuSpec: NavMenuItemSpec;
AEDescList: AEDescListPtr;
FileDialog: TFileDialog;
const
SName = 'NavDialogCallback';
begin
//DebugLn('NavDialogCallback ' + DbgS(CallbackUD));
//DebugLnEnter(['NavDialogCallback INIT selector=',CallbackSelector]);
if CallbackUD = nil then // No user data passed?
Exit;
FileDialog := TFileDialog(CallbackUD);
case CallBackSelector of
kNavCBStart:
begin
// set initial filter index
MenuSpec.version := kNavMenuItemSpecVersion;
MenuSpec.menuCreator := kExtensionFolderType;
MenuSpec.menuType := OSType(FilterIndex);
MenuSpec.menuItemName := '';
OSError(NavCustomControl(CallBackParms^.context, kNavCtlSelectCustomType, @MenuSpec),
SName, 'NavCustomControl', 'FilterIndex');
// Set InitialDir
if DirectoryExistsUTF8(TFileDialog(CallbackUD).InitialDir) then
if DirectoryExistsUTF8(FileDialog.InitialDir) then
begin
//DebugLn('Set InitialDir ' + TFileDialog(CallbackUD).InitialDir);
CreateCFString(TFileDialog(CallbackUD).InitialDir, DirCFStr);
CreateCFString(FileDialog.InitialDir, DirCFStr);
try
DirURL := CFURLCreateWithFileSystemPath(nil, DirCFStr,
kCFURLPOSIXPathStyle, True);
@ -197,17 +264,39 @@ begin
OSError(NavCustomControl(CallBackParms^.context, kNavCtlSetLocation, @Dir),
SName, 'NavCustomControl', 'InitialDir');
end;
// set initial filter index
MenuSpec.version := kNavMenuItemSpecVersion;
MenuSpec.menuCreator := kExtensionFolderType;
MenuSpec.menuType := OSType(FileDialog.FilterIndex-1);
MenuSpec.menuItemName := '';
OSError(NavCustomControl(CallBackParms^.context, kNavCtlSelectCustomType, @MenuSpec),
SName, 'NavCustomControl', 'FilterIndex');
end;
kNavCBPopupMenuSelect: // user has changed filter
begin
if CallBackParms = nil then Exit;
PMenuSpec := NavMenuItemSpecPtr(CallBackParms^.eventData.eventDataParms.param);
if PMenuSpec = nil then Exit;
//DebugLn(DbgS(PMenuSpec^.menuType));
FileDialog.FilterIndex:= PMenuSpec^.menuType + 1;
FileDialog.DoTypeChange;
end;
kNavCBSelectEntry: // user has selected something
begin
if CallbackParms = nil then exit;
AEDescList := AEDescListPtr(CallBackParms^.eventData.eventDataParms.param);
DescListToFiles(AEDescList, FileDialog);
//DebugLn(['kNavCBSelectEntry IsOpenDialog=',FileDialog is TOpenDialog]);
if FileDialog is TOpenDialog then
TOpenDialog(FileDialog).DoSelectionChange;
end;
kNavCBNewLocation: // user has changed folder
if FileDialog is TOpenDialog then
TOpenDialog(FileDialog).DoFolderChange;
end;
FilterIndex := PMenuSpec^.menuType;
end;
end;
//DebugLnExit('NavDialogCallback DONE');
end;
@ -230,14 +319,7 @@ var
FilterUPP: NavObjectFilterUPP;
NavDialogUPP: NavEventUPP;
DialogRef: NavDialogRef;
DialogReply: NavReplyRecord;
FileCount: Integer;
FileIdx, I: Integer;
Keyword: AEKeyword;
FileDesc: AEDesc;
FileRef: FSRef;
FileURL: CFURLRef;
FileCFStr: CFStringRef;
I: Integer;
ParsedFilter: TParseStringList;
M: TMaskList;
filterext: String;
@ -262,8 +344,6 @@ begin
NavDialogUPP := NewNavEventUPP(NavEventProcPtr(@NavDialogCallback));
Filters := TStringList.Create;
FilterIndex := FileDialog.FilterIndex - 1; // file dialog filter index is ine based
// parse filters to popup menu - filter text + TMaskList
ParsedFilter := TParseStringList.Create(FileDialog.Filter, '|');
try
@ -338,40 +418,6 @@ begin
if NavDialogGetUserAction(DialogRef) <> kNavUserActionCancel then // User OK?
begin
if OSError(NavDialogGetReply(DialogRef, DialogReply{%H-}), Self, SShowModal,
'NavDialogGetReply') then Exit; // Get user's selection
if OSError(AECountItems(DialogReply.Selection, FileCount{%H-}), Self,
SShowModal, 'AECountItems') then Exit;
FileDialog.Files.Clear;
for FileIdx := 1 to FileCount do
begin
if OSError(AEGetNthDesc(DialogReply.Selection, FileIdx, typeFSRef,
@Keyword, FileDesc{%H-}), Self, SShowModal, 'AEGetNthDesc') then Exit;
// Get file reference
if OSError(AEGetDescData(FileDesc, @FileRef, SizeOf(FSRef)), Self,
SShowModal, 'AEGetDescData') then Exit;
if OSError(AEDisposeDesc(FileDesc), Self, SShowModal,
'AEDisposeDesc') then Exit;
FileURL := CFURLCreateFromFSRef(kCFAllocatorDefault, FileRef); // Get URL
FileCFStr := CFURLCopyFileSystemPath(FileURL, kCFURLPOSIXPathStyle); // Get path
FileDialog.Files.Add(CFStringToStr(FileCFStr));
FreeCFString(FileURL);
FreeCFString(FileCFStr);
// Note: Previous 5 lines replace next 2 lines and eliminate need
// to decide what size to make FileBuf array.
// See http://developer.apple.com/technotes/tn2002/tn2078.html
// FSRefMakePath(FileRef, @FileBuf, SizeOf(FileBuf)); {Get file path}
// FileDialog.Files.Add(string(FileBuf)); //FileBuf contains UTF8 C string
end;
FileDialog.FileName := FileDialog.Files.Strings[0];
if FileDialog.FCompStyle=csSaveFileDialog then
FileDialog.FileName := FileDialog.FileName + PathDelim +
CFStringToStr(NavDialogGetSaveFileName(DialogRef));
@ -380,11 +426,6 @@ begin
mean by the "full file name" returned by NavDialogGetSaveFileName
must mean extension and not path to file's folder.}
// Dispose of data that record points to (?)
if OSError(NavDisposeReply(DialogReply), Self, SShowModal,
'NavDisposeReply') then Exit;
FileDialog.FilterIndex := FilterIndex + 1;
FileDialog.UserChoice := mrOK;
end;
finally