use super::super::{PathPickerError, PathPurpose};
use cocoa::base::{id, nil, BOOL, NO, YES};
use cocoa::foundation::{NSAutoreleasePool, NSString};
use objc::{class, msg_send, sel, sel_impl};
const NS_MODAL_RESPONSE_OK: i64 = 1;
pub(crate) fn choose_path(
purpose: PathPurpose,
title: &str,
) -> Result<Option<std::path::PathBuf>, PathPickerError> {
unsafe {
let on_main_thread: BOOL = msg_send![class!(NSThread), isMainThread];
if on_main_thread == NO {
return Err(PathPickerError::Unavailable);
}
let panel: id = match purpose {
PathPurpose::SaveFile => msg_send![class!(NSSavePanel), savePanel],
_ => msg_send![class!(NSOpenPanel), openPanel],
};
if panel == nil {
return Err(PathPickerError::Unavailable);
}
let title_object = NSString::alloc(nil).init_str(title).autorelease();
let _: () = msg_send![panel, setTitle: title_object];
match purpose {
PathPurpose::SelectDirectory => {
let _: () = msg_send![panel, setCanChooseFiles: NO];
let _: () = msg_send![panel, setCanChooseDirectories: YES];
}
PathPurpose::OpenFile => {
let _: () = msg_send![panel, setCanChooseFiles: YES];
let _: () = msg_send![panel, setCanChooseDirectories: NO];
}
PathPurpose::SaveFile => {}
}
let _: () = msg_send![panel, setAllowsMultipleSelection: NO];
let response: i64 = msg_send![panel, runModal];
if response != NS_MODAL_RESPONSE_OK {
return Ok(None);
}
let url: id = msg_send![panel, URL];
if url == nil {
return Ok(None);
}
let path_object: id = msg_send![url, path];
if path_object == nil {
return Ok(None);
}
let utf8: *const std::os::raw::c_char = msg_send![path_object, UTF8String];
if utf8.is_null() {
return Ok(None);
}
let text = std::ffi::CStr::from_ptr(utf8).to_string_lossy().into_owned();
Ok(Some(std::path::PathBuf::from(text)))
}
}