Impl prompts
and savefile dialog
on Windows (#9009)
### Description This is a part of #8809 , and this PR dose not include `open file dialog`, as I already saw two PRs impl this. https://github.com/zed-industries/zed/assets/14981363/3223490a-de77-4892-986f-97cf85aec3ae Release Notes: - N/A
This commit is contained in:
parent
bf295eac90
commit
a550b9cecf
5 changed files with 147 additions and 13 deletions
|
@ -5,6 +5,7 @@ use std::{
|
|||
cell::RefCell,
|
||||
collections::HashSet,
|
||||
ffi::{c_uint, c_void},
|
||||
os::windows::ffi::OsStrExt,
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
sync::Arc,
|
||||
|
@ -14,7 +15,8 @@ use std::{
|
|||
use anyhow::{anyhow, Result};
|
||||
use async_task::Runnable;
|
||||
use copypasta::{ClipboardContext, ClipboardProvider};
|
||||
use futures::channel::oneshot::Receiver;
|
||||
use futures::channel::oneshot::{self, Receiver};
|
||||
use itertools::Itertools;
|
||||
use parking_lot::Mutex;
|
||||
use time::UtcOffset;
|
||||
use util::{ResultExt, SemanticVersion};
|
||||
|
@ -25,15 +27,17 @@ use windows::{
|
|||
Foundation::{CloseHandle, BOOL, HANDLE, HWND, LPARAM, TRUE},
|
||||
Graphics::DirectComposition::DCompositionWaitForCompositorClock,
|
||||
System::{
|
||||
Com::{CoCreateInstance, CreateBindCtx, CLSCTX_ALL},
|
||||
Ole::{OleInitialize, OleUninitialize},
|
||||
Threading::{CreateEventW, GetCurrentThreadId, INFINITE},
|
||||
Time::{GetTimeZoneInformation, TIME_ZONE_ID_INVALID},
|
||||
{
|
||||
Ole::{OleInitialize, OleUninitialize},
|
||||
Threading::{CreateEventW, GetCurrentThreadId, INFINITE},
|
||||
},
|
||||
},
|
||||
UI::{
|
||||
Input::KeyboardAndMouse::GetDoubleClickTime,
|
||||
Shell::ShellExecuteW,
|
||||
Shell::{
|
||||
FileSaveDialog, IFileSaveDialog, IShellItem, SHCreateItemFromParsingName,
|
||||
ShellExecuteW, SIGDN_FILESYSPATH,
|
||||
},
|
||||
WindowsAndMessaging::{
|
||||
DispatchMessageW, EnumThreadWindows, LoadImageW, PeekMessageW, PostQuitMessage,
|
||||
SetCursor, SystemParametersInfoW, TranslateMessage, HCURSOR, IDC_ARROW, IDC_CROSS,
|
||||
|
@ -342,9 +346,32 @@ impl Platform for WindowsPlatform {
|
|||
unimplemented!()
|
||||
}
|
||||
|
||||
// todo(windows)
|
||||
fn prompt_for_new_path(&self, directory: &Path) -> Receiver<Option<PathBuf>> {
|
||||
unimplemented!()
|
||||
let directory = directory.to_owned();
|
||||
let (tx, rx) = oneshot::channel();
|
||||
self.foreground_executor()
|
||||
.spawn(async move {
|
||||
unsafe {
|
||||
let Ok(dialog) = show_savefile_dialog(directory) else {
|
||||
let _ = tx.send(None);
|
||||
return;
|
||||
};
|
||||
let Ok(_) = dialog.Show(None) else {
|
||||
let _ = tx.send(None); // user cancel
|
||||
return;
|
||||
};
|
||||
if let Ok(shell_item) = dialog.GetResult() {
|
||||
if let Ok(file) = shell_item.GetDisplayName(SIGDN_FILESYSPATH) {
|
||||
let _ = tx.send(Some(PathBuf::from(file.to_string().unwrap())));
|
||||
return;
|
||||
}
|
||||
}
|
||||
let _ = tx.send(None);
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
|
||||
rx
|
||||
}
|
||||
|
||||
fn reveal_path(&self, path: &Path) {
|
||||
|
@ -555,3 +582,26 @@ fn open_target(target: &str) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn show_savefile_dialog(directory: PathBuf) -> Result<IFileSaveDialog> {
|
||||
let dialog: IFileSaveDialog = CoCreateInstance(&FileSaveDialog, None, CLSCTX_ALL)?;
|
||||
let bind_context = CreateBindCtx(0)?;
|
||||
let Ok(full_path) = directory.canonicalize() else {
|
||||
return Ok(dialog);
|
||||
};
|
||||
let dir_str = full_path.into_os_string();
|
||||
if dir_str.is_empty() {
|
||||
return Ok(dialog);
|
||||
}
|
||||
let dir_vec = dir_str.encode_wide().collect_vec();
|
||||
let ret = SHCreateItemFromParsingName(PCWSTR::from_raw(dir_vec.as_ptr()), &bind_context)
|
||||
.inspect_err(|e| log::error!("unable to create IShellItem: {}", e));
|
||||
if ret.is_ok() {
|
||||
let dir_shell_item: IShellItem = ret.unwrap();
|
||||
let _ = dialog
|
||||
.SetFolder(&dir_shell_item)
|
||||
.inspect_err(|e| log::error!("unable to set folder for save file dialog: {}", e));
|
||||
}
|
||||
|
||||
Ok(dialog)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue