API call help

Mac OSX specific forum
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: API call help

Post 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.
Wolfram
Enthusiast
Enthusiast
Posts: 607
Joined: Thu May 30, 2013 4:39 pm

Re: API call help

Post by Wolfram »

Many Thanks!

but I get an Error if I try to load a File
Object dose not respond to method "fileSystemRepresentation"
macOS Catalina 10.15.7
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3943
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: API call help

Post by wilbert »

Wolfram wrote:Object dose not respond to method "fileSystemRepresentation"
The fileSystemRepresentation method requires OS X 10.9 (Mavericks).
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: API call help

Post 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.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3943
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: API call help

Post 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 )
Windows (x64)
Raspberry Pi OS (Arm64)
Wolfram
Enthusiast
Enthusiast
Posts: 607
Joined: Thu May 30, 2013 4:39 pm

Re: API call help

Post 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
macOS Catalina 10.15.7
Wolfram
Enthusiast
Enthusiast
Posts: 607
Joined: Thu May 30, 2013 4:39 pm

Re: API call help

Post 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?
macOS Catalina 10.15.7
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3943
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: API call help

Post 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)
Windows (x64)
Raspberry Pi OS (Arm64)
Wolfram
Enthusiast
Enthusiast
Posts: 607
Joined: Thu May 30, 2013 4:39 pm

Re: API call help

Post 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
macOS Catalina 10.15.7
User avatar
Shardik
Addict
Addict
Posts: 2067
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: API call help

Post 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...
WilliamL
Addict
Addict
Posts: 1253
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: API call help

Post 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. :)
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
Post Reply