Platforms to show: All Mac Windows Linux Cross-Platform
/MacCocoa/Dynamic FileOpenDialog
Required plugins for this example: MBS MacOSX Plugin, MBS MacBase Plugin, MBS MacControls Plugin, MBS MacCocoa Plugin, MBS Util Plugin, MBS Main Plugin
You find this example project in your Plugins Download as a Xojo project file within the examples folder: /MacCocoa/Dynamic FileOpenDialog
This example is the version from Mon, 6th Nov 2022.
Project "Dynamic FileOpenDialog.xojo_binary_project"
Class App Inherits Application
Const kEditClear = "&Delete"
Const kFileQuit = "&Quit"
Const kFileQuitShortcut = ""
End Class
Class main Inherits Window
Control TestBtn Inherits PushButton
ControlInstance TestBtn Inherits PushButton
EventHandler Sub Action()
dim s As String = typesFld.Text
if AllTypesCB.Value Then s = ""
ShowDocOpenDlg s, "AddDocument"
End EventHandler
End Control
Control OpenFiles Inherits FileOpenPanel
ControlInstance OpenFiles(0) Inherits FileOpenPanel
End Control
Control typesFld Inherits TextField
ControlInstance typesFld Inherits TextField
End Control
Control StaticText1 Inherits Label
ControlInstance StaticText1 Inherits Label
End Control
Control AllTypesCB Inherits Checkbox
ControlInstance AllTypesCB Inherits Checkbox
End Control
Sub DataChanged(src As Notifier)
// Part of the Receiver interface.
if src <> nil Then
dim v As Variant = src.Data
if v isa OpenPanelResults Then
dim result As OpenPanelResults = v
if result.CallingMethod = "AddDocument" Then
HandleAddDocuments result.files
end if
end if
end if
End Sub
Private Sub HandleAddDocuments(files() As FolderItem)
dim u As Integer = UBound(files)
if u = -1 Then
MsgBox "You cancelled the file open dialog"
Else
dim s As String = "You chose:" + EndOfLine + EndOfLine
for i As Integer = 0 to u
if files(i) <> nil Then s = s + files(i).DisplayName + EndOfLine
next
MsgBox s
end if
End Sub
Private Sub ShowDocOpenDlg(apptypes As String, callingMethod As String)
dim types() As String = FileOpenPanel.OSTypeStrToArray(apptypes)
if UBound(types) = 0 and types(0) = "''" Then
types.Remove 0 // pass an empty array
end if
OpenDialog = new OpenFiles(nil, "", types, callingMethod, True, True, self)
End Sub
Private Sub TestFileTypeConversion()
const characters = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
dim cnt As Integer = Len(characters)
const arrLen = 100000
dim r As new Random
dim i As Integer
dim arr(arrLen) As String
for i = 0 to arrLen
dim type As String
for n As Integer = 1 to 4
type = type + Mid(characters, r.InRange(1, cnt), 1)
next
arr(i) = type
next
dim mTics As Integer = ticks
'#pragma DisableAutoWaitCursor
#pragma DisableBackgroundTasks
for i = 0 to arrLen
arr(i) = NSOpenPanelMBS.FileTypeForHFSType(arr(i))
next
mTics = Ticks - mTics
dim fTics As Integer = Ticks
arr = FileOpenPanel.OSTypeArrayToHFSArray(arr)
fTics = Ticks - fTics
MsgBox "NSOpenPanelMBS.FileTypeForHFSType:" + str(mTics) + EndOfLine + _
"FileOpenPanel.OSTypeArrayToHFSArray: " + str(fTics)
End Sub
Property Private OpenDialog As FileOpenPanel
End Class
MenuBar MenuBar1
MenuItem FileMenu = "&File"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Edit"
MenuItem EditUndo = "&Undo"
MenuItem UntitledMenu1 = "-"
MenuItem EditCut = "Cu&t"
MenuItem EditCopy = "&Copy"
MenuItem EditPaste = "&Paste"
MenuItem EditClear = "#App.kEditClear"
MenuItem UntitledMenu0 = "-"
MenuItem EditSelectAll = "Select &All"
End MenuBar
Class FileOpenPanel Inherits NSOpenPanelMBS
Const kAddToFavesIdentifier = "AddToFavorites"
Const kShowAllTypesIdentifier = "ShowAllTypes"
Const kShowInvisiblesIdentifier = "ShowInvisibles"
EventHandler Sub savePanelDidEnd(ReturnCode as integer)
dim files() As FolderItem
if ReturnCode > 0 Then
for i As Integer = 0 to me.FilesCount
if me.Files(i) <> nil Then files.Append me.Files(i)
next
end if
me.Results = new OpenPanelResults(me.CallerMethod, files)
NotifyAll
End EventHandler
EventHandler Function shouldShowFilename(path as string, item as folderitem) As boolean
dim t as string
if AllFileTypes then Return true
if item.Directory then // special handling for folders
dim l as LaunchServicesItemInfoMBS
l=item.LaunchServicesItemInfoMBS(4) // check for bundled files like Pages documents
if l=nil then
Return true
else
Return l.IsPackage=False
end if
end if
t=item.NameExtensionMBS
For Each s As String In FileTypes
If StrComp(s,t,0)=0 Then Return True
Next
End EventHandler
Sub AddNotifier(recv As Receiver)
// Part of the Notifier interface.
if Receivers.IndexOf(recv) = -1 Then
Receivers.Append recv
end if
End Sub
Private Sub AddShowAllFileTypesCheckbox()
AssureAccessoryView
if AccView <> nil Then
ShowAllTypesCheckbox = new OpenFileButton(0, 10, 126, 20, kShowAllTypesIdentifier, "Show all file types", me)
ShowAllTypesCheckbox.setButtonType NSButtonMBS.NSSwitchButton
AccView.addSubview ShowAllTypesCheckbox
end if
End Sub
Private Sub AddShowInvisiblesCheckbox()
AssureAccessoryView
if AccView <> nil Then
ShowInvisiblesCheckView = new OpenFileButton(140, 10, 132, 20, kShowInvisiblesIdentifier, "Show invisible files", me)
ShowInvisiblesCheckView.setButtonType NSButtonMBS.NSSwitchButton
AccView.addSubview ShowInvisiblesCheckView
end if
End Sub
Private Sub AssureAccessoryView()
if AccView = nil Then
AccView = new NSViewMBS(0, 0, 460, 40)
me.accessoryView = me.AccView
end if
End Sub
Sub Constructor(initialFolder As FolderItem, hilitedFile As String, fileTypes() As String, callingMethod As String, allowInvisibles As Boolean, multipleSelection As Boolean, parentWindow As Window)
// Use this constructor for choosing files
Super.Constructor
me.CallerMethod = callingMethod
me.FileTypes = FileTypes
me.allowsMultipleSelection = multipleSelection
if parentWindow isa Receiver Then AddNotifier(Receiver(parentWindow))
if allowInvisibles Then
AddShowInvisiblesCheckbox
end if
if Ubound(fileTypes) >= 0 Then
AddShowAllFileTypesCheckbox
end if
'me.canChooseDirectories = False
'me.canChooseFiles = True
me.beginSheetForDirectory(initialFolder, hilitedFile, nil, parentWindow)
End Sub
Function Data() As Variant
// Part of the Notifier interface.
Return me.Results
End Function
Sub DataChanged(src As Notifier)
// handles results from OpenFileButtons
dim command As String = src.Data
Select Case command
Case kShowAllTypesIdentifier
dim btnValue As Integer
btnValue = ShowAllTypesCheckbox.state
AllFileTypes=btnValue=1
super.validateVisibleColumns
Case kShowInvisiblesIdentifier
me.showsHiddenFiles = ShowInvisiblesCheckView.state = 1
End Select
'validateVisibleColumns
End Sub
Sub NotifyAll()
// Part of the Notifier interface.
for i As Integer = 0 to UBound(me.Receivers)
me.Receivers(i).DataChanged me
next
End Sub
Shared Function OSTypeArrayToHFSArray(osTypes() As String) As String()
dim s As String = "'" + Join(OSTypes, "','") + "'"
Return Split(s, ",")
End Function
Shared Function OSTypeStrToArray(osTypes As String) As String()
return Split(OSTypes, ",")
End Function
Shared Function OSTypeStrToHFSArray(osTypes As String) As String()
dim arr() As String = Split(OSTypes, ",")
dim s As String = "'" + Join(arr, "','") + "'"
Return Split(s, ",")
End Function
Sub RemoveNotifier(rcv As Receiver)
// Part of the Notifier interface.
dim n As Integer = me.Receivers.IndexOf(rcv)
if n > -1 Then me.Receivers.Remove n
End Sub
Property Private AccView As NSViewMBS
Property Private AllFileTypes As boolean
Property Private CallerMethod As String
Property Private FileTypes() As string
Property Private Receivers() As Receiver
Property Private Results As OpenPanelResults
Property Private ShowAllTypesCheckbox As OpenFileButton
Property Private ShowInvisiblesCheckView As OpenFileButton
End Class
Class OpenPanelResults
Sub Constructor(caller As String, f() As FolderItem)
me.CallingMethod = caller
me.files = f
End Sub
Property CallingMethod As String
Property files() As FolderItem
End Class
Class OpenFileButton Inherits NSButtonMBS
EventHandler Sub Action()
NotifyAll
End EventHandler
Sub AddNotifier(recv As Receiver)
// Part of the Notifier interface.
if me.Receivers.IndexOf(recv) = -1 Then
me.Receivers.Append recv
end if
End Sub
Sub Constructor(left as double, top as double, width as double, height as double, cmd As String, caption As String, r As Receiver)
// Constructor(left As double, top As double, width As double, height As double) -- From NSViewMBS
Super.Constructor(left, top, width, height)
me.Command = cmd
me.Title = caption
AddNotifier r
End Sub
Function Data() As Variant
// Part of the Notifier interface.
Return me.Command
End Function
Sub NotifyAll()
// Part of the Notifier interface.
for i As Integer = 0 to UBound(me.Receivers)
me.Receivers(i).DataChanged me
next
End Sub
Sub RemoveNotifier(rcv As Receiver)
// Part of the Notifier interface.
dim n As Integer = me.Receivers.IndexOf(rcv)
if n > -1 Then
me.Receivers.Remove n
end if
End Sub
Property Private Command As String
Property Private Receivers() As Receiver
End Class
Interface Notifier
Sub AddNotifier(recv As Receiver)
Function Data() As Variant
Sub NotifyAll()
Sub RemoveNotifier(rcv As Receiver)
End Interface
Interface Receiver
Sub DataChanged(src As Notifier)
End Interface
End Project
The items on this page are in the following plugins: MBS MacCocoa Plugin.