use std::path::PathBuf;
use block::ConcreteBlock;
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::ShareId;
use crate::filesystem::enums::ModalResponse;
use crate::foundation::{id, nil, NSInteger, NSString, NO, NSURL, YES};
#[cfg(feature = "appkit")]
use crate::appkit::window::{Window, WindowDelegate};
#[derive(Debug)]
pub struct FileSelectPanel {
pub panel: ShareId<Object>,
pub delegate: ShareId<Object>,
pub can_choose_files: bool,
pub can_choose_directories: bool,
pub resolves_aliases: bool,
pub allows_multiple_selection: bool
}
impl Default for FileSelectPanel {
fn default() -> Self {
FileSelectPanel::new()
}
}
impl FileSelectPanel {
pub fn new() -> Self {
FileSelectPanel {
panel: unsafe {
let cls = class!(NSOpenPanel);
let x: id = msg_send![cls, openPanel];
ShareId::from_ptr(x)
},
delegate: unsafe { ShareId::from_ptr(msg_send![class!(NSObject), new]) },
can_choose_files: true,
can_choose_directories: false,
resolves_aliases: true,
allows_multiple_selection: true
}
}
pub fn set_delegate(&mut self) {}
pub fn set_can_choose_files(&mut self, can_choose: bool) {
unsafe {
let _: () = msg_send![&*self.panel, setCanChooseFiles:match can_choose {
true => YES,
false => NO
}];
}
self.can_choose_files = can_choose;
}
pub fn set_message<S: AsRef<str>>(&mut self, message: S) {
unsafe {
let message = NSString::new(message.as_ref());
let _: () = msg_send![&*self.panel, setMessage:&*message];
}
}
pub fn set_can_choose_directories(&mut self, can_choose: bool) {
unsafe {
let _: () = msg_send![&*self.panel, setCanChooseDirectories:match can_choose {
true => YES,
false => NO
}];
}
self.can_choose_directories = can_choose;
}
pub fn set_resolves_aliases(&mut self, resolves: bool) {
unsafe {
let _: () = msg_send![&*self.panel, setResolvesAliases:match resolves {
true => YES,
false => NO
}];
}
self.resolves_aliases = resolves;
}
pub fn set_allows_multiple_selection(&mut self, allows: bool) {
unsafe {
let _: () = msg_send![&*self.panel, setAllowsMultipleSelection:match allows {
true => YES,
false => NO
}];
}
self.allows_multiple_selection = allows;
}
pub fn show<F>(&self, handler: F)
where
F: Fn(Vec<NSURL>) + 'static
{
let panel = self.panel.clone();
let completion = ConcreteBlock::new(move |result: NSInteger| {
let response: ModalResponse = result.into();
handler(match response {
ModalResponse::Ok => get_urls(&panel),
_ => Vec::new()
});
});
unsafe {
let _: () = msg_send![&*self.panel, beginWithCompletionHandler:completion.copy()];
}
}
pub fn close(&self) {
unsafe {
let _: () = msg_send![&*self.panel, close];
}
}
pub fn begin_sheet<T, F>(&self, window: &Window<T>, handler: F)
where
F: Fn(Vec<NSURL>) + 'static
{
let panel = self.panel.clone();
let completion = ConcreteBlock::new(move |result: NSInteger| {
let response: ModalResponse = result.into();
handler(match response {
ModalResponse::Ok => get_urls(&panel),
_ => Vec::new()
});
});
unsafe {
let _: () = msg_send![&*self.panel, beginSheetModalForWindow:&*window.objc completionHandler:completion.copy()];
}
}
}
fn get_urls(panel: &Object) -> Vec<NSURL> {
unsafe {
let urls: id = msg_send![&*panel, URLs];
let count: usize = msg_send![urls, count];
(0..count)
.map(|index| NSURL::retain(msg_send![urls, objectAtIndex: index]))
.collect()
}
}