Page 1 of 2

Re: API call help

Posted: Fri Nov 08, 2013 8:15 am
by Danilo
Wolfram wrote:can some give me a easy example of this code. I'm a beginner and have no experience with C.
PB help says:
Note: The 'Pattern$' and 'PatternPosition' parameters have no effect on Mac OSX (the requester always displays all files).
So here a version with patterns, based on Polo's Objective-C code:

Code: Select all

Macro CreateCocoaObject(objectName,withMethod="alloc")
    CocoaMessage(0,0,objectName+" "+withMethod)
EndMacro


#showHiddenFiles        = 1
#allowMultipleSelection = 1 << 1
#returnAbsoluteNames    = 1 << 2

#NSFileHandlingPanelOKButton     = 1
#NSFileHandlingPanelCancelButton = 0

Procedure OpenFileRequester_(List out.s(), title.s, defaultdirectory.s="", pattern.s="", message.s="", flags=0)
    ClearList(out())
    NSApp = CreateCocoaObject("NSApplication")
    If NSApp
        currentwin = CocoaMessage(0,NSApp,"keyWindow")
        If Not currentwin
            CocoaMessage(0,NSApp,"activateIgnoringOtherApps:",#YES)
        EndIf
        
        panel = CreateCocoaObject("NSOpenPanel","openPanel")
        If panel
            ;
            ; set title
            ;
            CocoaMessage(0,panel,"setTitle:$",@title)
            
            ;
            ; set optional message text
            ;
            If message
                CocoaMessage(0,panel,"setMessage:$",@message)
            EndIf
            
            ;
            ; set allowed patterns, separated by '|'
            ;
            If pattern <> ""
                i = 1
                nextPattern.s = StringField(pattern,i,"|")
                fileTypesArray = CocoaMessage(0,0,"NSArray arrayWithObject:$", @nextPattern)
                Repeat
                    i + 1
                    nextPattern = StringField(pattern,i,"|")
                    If nextPattern
                        fileTypesArray = CocoaMessage(0,fileTypesArray, "arrayByAddingObject:$", @nextPattern)
                    EndIf
                Until nextPattern = ""
                CocoaMessage(0,panel,"setAllowedFileTypes:",fileTypesArray)
            EndIf
            
            ;
            ; show hidden files?
            ;
            If flags & #showHiddenFiles
                CocoaMessage(0,panel,"setShowsHiddenFiles:",#YES)
            EndIf
            
            ;
            ; allow multiple selection?
            ;
            If flags & #allowMultipleSelection
                CocoaMessage(0,panel,"setAllowsMultipleSelection:",#YES)
            EndIf
            
            ;
            ; set default directory
            ;
            url = CocoaMessage(0,0,"NSURL URLWithString:$",@defaultdirectory)
            CocoaMessage(0,panel,"setDirectoryURL:",url)
            
            ;
            ; run
            ;
            If CocoaMessage(0,panel,"runModal") = #NSFileHandlingPanelOKButton
            
                ;
                ; get results
                ;
                results = CocoaMessage(0,panel,"URLs")
                If results
                    count = CocoaMessage(0, results, "count")
                    If count
                        For i = 0 To count-1
                            NSURL = CocoaMessage(0,results,"objectAtIndex:",i)
                            If NSURL
                                If Not flags & #returnAbsoluteNames
                                    ;
                                    ; return file names
                                    ;
                                    string = CocoaMessage(0,NSURL,"fileSystemRepresentation")
                                    If string
                                        fileName.s = PeekS(string,-1,#PB_UTF8)
                                        If AddElement(out())
                                            out() = fileName
                                        EndIf
                                    EndIf
                                Else
                                    ;
                                    ; return absolute names
                                    ;
                                    string = CocoaMessage(0,NSURL,"absoluteString")
                                    If string
                                        utf8 = CocoaMessage(0,string,"UTF8String")
                                        If utf8
                                            fileName.s = PeekS(utf8,-1,#PB_UTF8)
                                            If AddElement(out())
                                                out() = fileName
                                            EndIf
                                        EndIf
                                    EndIf
                                EndIf
                            EndIf
                        Next i
                    EndIf
                EndIf
            EndIf
        EndIf
    EndIf
    If currentwin
        CocoaMessage(0,currentwin,"makeKeyWindow")
    EndIf
    ProcedureReturn count
EndProcedure




NewList files.s()

num = OpenFileRequester_( files(),
                          "Please choose file(s) to load",
                          "/users/",
                          "pb|pbi|prefs|rtf|txt",
                          "Optional message:"+#CR$+"Please open a file for loading."+#CR$+"Second message line",
                          #allowMultipleSelection |
                          #showHiddenFiles )

Debug num

ForEach files()
    Debug files()
Next
Polo's example used "runModalForDirectory:file:types:" method, and it was marked deprecated in OS X v10.6.
My version uses newer methods, but I think it requires at least OS X v10.6.

Re: API call help

Posted: Fri Nov 08, 2013 10:05 pm
by Wolfram
Many Thanks!

but I get an Error if I try to load a File
Object dose not respond to method "fileSystemRepresentation"

Re: API call help

Posted: Sat Nov 09, 2013 6:59 am
by wilbert
Wolfram wrote:Object dose not respond to method "fileSystemRepresentation"
The fileSystemRepresentation method requires OS X 10.9 (Mavericks).

Re: API call help

Posted: Sat Nov 09, 2013 8:06 am
by Danilo
Wolfram wrote:but I get an Error if I try to load a File
Object dose not respond to method "fileSystemRepresentation"
Does it work for you with flag '#returnAbsoluteNames'?
In this case you get results like "file:///users/danilo/todo.rtf", but it could
be different URL for Network files.

Re: API call help

Posted: Sat Nov 09, 2013 8:15 am
by wilbert
Here's also a simplified version of Danilo's approach returning all absolute names in one string separated by |
Minimum requirement is OS X 10.6

Code: Select all

#showHiddenFiles        = 1 << 0
#allowMultipleSelection = 1 << 1

Procedure.s OpenFileRequester_(title.s, defaultdirectory.s = "", pattern.s = "", message.s = "", flags = 0)
  Protected NSPanel, NSArray, NSString
  
  NSPanel = CocoaMessage(0, 0, "NSOpenPanel openPanel")
  NSArray = CocoaMessage(0, CocoaMessage(0, 0, "NSString stringWithString:$", @pattern), "componentsSeparatedByString:$", @"|")
  
  CocoaMessage(0, NSPanel, "setTitle:$", @title)
  CocoaMessage(0, NSPanel, "setDirectoryURL:", CocoaMessage(0, 0, "NSURL URLWithString:$", @defaultdirectory))
  CocoaMessage(0, NSPanel, "setAllowedFileTypes:", NSArray)
  CocoaMessage(0, NSPanel, "setMessage:$", @message)
  
  If flags & #showHiddenFiles
    CocoaMessage(0, NSPanel, "setShowsHiddenFiles:", #YES)
  EndIf
  
  If flags & #allowMultipleSelection
    CocoaMessage(0, NSPanel, "setAllowsMultipleSelection:", #YES)
  EndIf
  
  If CocoaMessage(0, NSPanel, "runModal")
    NSString = CocoaMessage(0, CocoaMessage(0, NSPanel, "URLs"), "componentsJoinedByString:$", @"|")
    ProcedureReturn PeekS(CocoaMessage(0, NSString, "UTF8String"), -1, #PB_UTF8)
  Else
    ProcedureReturn ""
  EndIf
  
EndProcedure


Debug OpenFileRequester_("Please choose file(s) to load",
                         "/users/",
                         "pb|pbi|prefs|rtf|txt",
                         "Optional message:"+#CR$+"Please open a file for loading."+#CR$+"Second message line",
                         #allowMultipleSelection |
                         #showHiddenFiles )

Re: API call help

Posted: Sat Nov 09, 2013 12:25 pm
by Wolfram
Withe "#returnAbsoluteNames" it woks. I get a Path like this "file://localhost/TEXT.txt" for a file in the root of my HD.

With Wilbert solution I get the same Path.


...And I'm on OS X 10.7.5

Re: API call help

Posted: Sat Nov 09, 2013 1:44 pm
by Wolfram
Danilo wrote:
Wolfram wrote:but I get an Error if I try to load a File
Object dose not respond to method "fileSystemRepresentation"
Does it work for you with flag '#returnAbsoluteNames'?
In this case you get results like "file:///users/danilo/todo.rtf", but it could
be different URL for Network files.
Withe "#returnAbsoluteNames" it woks. I get a Path like this "file://localhost/TEXT.txt" for a file in the root of my HD.
Can I use this kind of Path or are there any problems with it?

Re: API call help

Posted: Sun Nov 10, 2013 9:52 pm
by wilbert
Here's a modified version of my previous post, returning file names in a more common form

Code: Select all

#RequesterTypeOpen = 0
#RequesterTypeSave = 1

Procedure.s FileRequester(RequesterType, Title.s, DefaultFile.s = "", AllowedFileTypes.s = "", Message.s = "", Flags = 0)
  Protected Result.s, Path.s, NSPanel, NSEnumerator, NSURL, NSString
  
  If RequesterType = #RequesterTypeSave
    NSPanel = CocoaMessage(0, 0, "NSSavePanel savePanel")
  Else
    NSPanel = CocoaMessage(0, 0, "NSOpenPanel openPanel")
    If Flags & #PB_Requester_MultiSelection
      CocoaMessage(0, NSPanel, "setAllowsMultipleSelection:", #YES)
    EndIf    
  EndIf
  
  Path = GetPathPart(DefaultFile)
  DefaultFile = GetFilePart(DefaultFile)
  
  CocoaMessage(0, NSPanel, "setTitle:$", @Title)
  CocoaMessage(0, NSPanel, "setMessage:$", @Message)
  CocoaMessage(0, NSPanel, "setAllowedFileTypes:", CocoaMessage(0, CocoaMessage(0, 0, "NSString stringWithString:$", @AllowedFileTypes), "componentsSeparatedByString:$", @"|"))
  CocoaMessage(0, NSPanel, "setDirectoryURL:", CocoaMessage(0, 0, "NSURL fileURLWithPath:$", @Path))
  CocoaMessage(0, NSPanel, "setNameFieldStringValue:$", @DefaultFile)
  
  If CocoaMessage(0, NSPanel, "runModal")
    If RequesterType = #RequesterTypeSave
      Result = PeekS(CocoaMessage(0, CocoaMessage(0, CocoaMessage(0, NSPanel, "URL"), "path"), "fileSystemRepresentation"), -1, #PB_Ascii)
    Else
      NSEnumerator = CocoaMessage(0, CocoaMessage(0, NSPanel, "URLs"), "objectEnumerator")
      NSURL = CocoaMessage(0, NSEnumerator, "nextObject")
      If NSURL
        Result = PeekS(CocoaMessage(0, CocoaMessage(0, NSURL, "path"), "fileSystemRepresentation"), -1, #PB_Ascii)
        NSURL = CocoaMessage(0, NSEnumerator, "nextObject")
        While NSURL
          Result + "|" + PeekS(CocoaMessage(0, CocoaMessage(0, NSURL, "path"), "fileSystemRepresentation"), -1, #PB_Ascii)
          NSURL = CocoaMessage(0, NSEnumerator, "nextObject")
        Wend
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn Result
EndProcedure


Debug FileRequester(#RequesterTypeOpen,
                    "Please choose file to open",
                    "/users/",
                    "pb|pbi|txt",
                    "Optional message",
                    #PB_Requester_MultiSelection)

Re: API call help

Posted: Tue Dec 10, 2013 1:21 pm
by Wolfram
Wilbert solution works fine But there is one problem...

on OSX 10.7.5 if I use the search field in the NSOpenPanel I can only search for .txt fils
Example: if I open it with AllowedFileTypes "txt" and search for .txt I find every text file.
If I open it with AllowedFileTypes "ems" and search for .ems I get no result.

on OSX 10.6.8 it works!

Dose anyone have an idee???

Thanx

Re: API call help

Posted: Thu Dec 12, 2013 10:37 pm
by Shardik
I have tested with a test file "Test.ems" using Wilbert's last example code on both OS X 10.6.8 (Snow Leopard) and OS X 10.7.5 (Lion) and I can't reproduce Wolfram's finding that ems file extensions are not found on Lion. Wilbert's example works without any problems on both Snow Leopard and Lion with the file extension ems...

Re: API call help

Posted: Thu Dec 12, 2013 11:43 pm
by WilliamL
I just tried wilbert's example and it works correctly for me. It only lets me choose 'pb' or 'pbi' or 'txt' files.

Oh, I tried '.ems' and it only found files that I changed to .ems. :)