diff --git a/ahk/_async/engine.py b/ahk/_async/engine.py index 630a369..2f1313c 100644 --- a/ahk/_async/engine.py +++ b/ahk/_async/engine.py @@ -3650,6 +3650,43 @@ async def file_select_box( args = [options, root, title, filter] return await self._transport.function_call('AHKFileSelectFile', args, blocking=blocking) + # fmt: off + @overload + async def folder_select_box(self, prompt: str = 'Select Folder', root: str = '', chroot: bool = False, enable_new_directories: bool = True, edit_field: bool = False, new_dialog_style: bool = False) -> Union[None, str]: ... + @overload + async def folder_select_box(self, prompt: str = 'Select Folder', root: str = '', chroot: bool = False, enable_new_directories: bool = True, edit_field: bool = False, new_dialog_style: bool = False, *, blocking: Literal[False]) -> Union[AsyncFutureResult[str], AsyncFutureResult[None]]: ... + @overload + async def folder_select_box(self, prompt: str = 'Select Folder', root: str = '', chroot: bool = False, enable_new_directories: bool = True, edit_field: bool = False, new_dialog_style: bool = False, *, blocking: Literal[True]) -> Union[str, None]: ... + @overload + async def folder_select_box(self, prompt: str = 'Select Folder', root: str = '', chroot: bool = False, enable_new_directories: bool = True, edit_field: bool = False, new_dialog_style: bool = False, *, blocking: bool = True) -> Union[str, None, AsyncFutureResult[str], AsyncFutureResult[None]]: ... + # fmt: on + async def folder_select_box( + self, + prompt: str = 'Select Folder', + root: str = '', + chroot: bool = False, + enable_new_directories: bool = True, + edit_field: bool = False, + new_dialog_style: bool = False, + *, + blocking: bool = True, + ) -> Union[str, None, AsyncFutureResult[str], AsyncFutureResult[None]]: + if not chroot: + starting_folder = '*' + else: + starting_folder = '' + starting_folder += root + if enable_new_directories: + opts = 1 + else: + opts = 0 + if edit_field: + opts += 2 + if new_dialog_style: + opts += 4 + args = [starting_folder, str(opts), prompt] + return await self._transport.function_call('AHKFileSelectFolder', args, blocking=blocking) + async def block_forever(self) -> NoReturn: """ Blocks (sleeps) forever. Utility method to prevent script from exiting. diff --git a/ahk/_async/transport.py b/ahk/_async/transport.py index 072956f..d34f18b 100644 --- a/ahk/_async/transport.py +++ b/ahk/_async/transport.py @@ -87,6 +87,7 @@ def result(self, timeout: Optional[float] = None) -> T_SyncFuture: 'AHKControlGetText', 'AHKControlSend', 'AHKFileSelectFile', + 'AHKFileSelectFolder', 'AHKGetClipboard', 'AHKGetClipboardAll', 'AHKGetCoordMode', @@ -603,7 +604,8 @@ async def function_call(self, function_name: Literal['AHKMsgBox'], args: Optiona async def function_call(self, function_name: Literal['AHKInputBox'], args: Optional[List[str]] = None, *, blocking: bool = True) -> Union[str, None, AsyncFutureResult[str], AsyncFutureResult[None]]: ... @overload async def function_call(self, function_name: Literal['AHKFileSelectFile'], args: Optional[List[str]] = None, *, blocking: bool = True) -> Union[str, None, AsyncFutureResult[str], AsyncFutureResult[None]]: ... - + @overload + async def function_call(self, function_name: Literal['AHKFileSelectFolder'], args: Optional[List[str]] = None, *, blocking: bool = True) -> Union[str, None, AsyncFutureResult[str], AsyncFutureResult[None]]: ... # fmt: on async def function_call( diff --git a/ahk/_constants.py b/ahk/_constants.py index d71bcf6..f2aacd0 100644 --- a/ahk/_constants.py +++ b/ahk/_constants.py @@ -2723,6 +2723,22 @@ return ret } +AHKFileSelectFolder(byRef command) { + global STRINGRESPONSEMESSAGE + starting_folder := command[2] + options := command[3] + prompt := command[4] + + FileSelectFolder, output, %starting_folder%, %options%, %prompt% + + if (ErrorLevel = 1) { + ret := FormatNoValueResponse() + } else { + ret := FormatResponse(STRINGRESPONSEMESSAGE, output) + } + return ret +} + b64decode(ByRef pszString) { ; TODO load DLL globally for performance ; REF: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinaryw diff --git a/ahk/_sync/engine.py b/ahk/_sync/engine.py index 06901fa..4b44f2b 100644 --- a/ahk/_sync/engine.py +++ b/ahk/_sync/engine.py @@ -3603,7 +3603,21 @@ def file_select_box(self, title: str = 'Select File', multi: bool = False, root: @overload def file_select_box(self, title: str = 'Select File', multi: bool = False, root: str = '', filter: str = '', save_button: bool = False, file_must_exist: bool = False, path_must_exist: bool = False, prompt_create_new_file: bool = False, prompt_override_file: bool = False, follow_shortcuts: bool = True, *, blocking: bool = True) -> Union[str, None, FutureResult[str], FutureResult[None]]: ... # fmt: on - def file_select_box(self, title: str = 'Select File', multi: bool = False, root: str = '', filter: str = '', save_button: bool = False, file_must_exist: bool = False, path_must_exist: bool = False, prompt_create_new_file: bool = False, prompt_override_file: bool = False, follow_shortcuts: bool = True, *, blocking: bool = True) -> Union[str, None, FutureResult[str], FutureResult[None]]: + def file_select_box( + self, + title: str = 'Select File', + multi: bool = False, + root: str = '', + filter: str = '', + save_button: bool = False, + file_must_exist: bool = False, + path_must_exist: bool = False, + prompt_create_new_file: bool = False, + prompt_override_file: bool = False, + follow_shortcuts: bool = True, + *, + blocking: bool = True, + ) -> Union[str, None, FutureResult[str], FutureResult[None]]: opts = 0 if file_must_exist: opts += 1 @@ -3625,7 +3639,42 @@ def file_select_box(self, title: str = 'Select File', multi: bool = False, root: args = [options, root, title, filter] return self._transport.function_call('AHKFileSelectFile', args, blocking=blocking) - + # fmt: off + @overload + def folder_select_box(self, prompt: str = 'Select Folder', root: str = '', chroot: bool = False, enable_new_directories: bool = True, edit_field: bool = False, new_dialog_style: bool = False) -> Union[None, str]: ... + @overload + def folder_select_box(self, prompt: str = 'Select Folder', root: str = '', chroot: bool = False, enable_new_directories: bool = True, edit_field: bool = False, new_dialog_style: bool = False, *, blocking: Literal[False]) -> Union[FutureResult[str], FutureResult[None]]: ... + @overload + def folder_select_box(self, prompt: str = 'Select Folder', root: str = '', chroot: bool = False, enable_new_directories: bool = True, edit_field: bool = False, new_dialog_style: bool = False, *, blocking: Literal[True]) -> Union[str, None]: ... + @overload + def folder_select_box(self, prompt: str = 'Select Folder', root: str = '', chroot: bool = False, enable_new_directories: bool = True, edit_field: bool = False, new_dialog_style: bool = False, *, blocking: bool = True) -> Union[str, None, FutureResult[str], FutureResult[None]]: ... + # fmt: on + def folder_select_box( + self, + prompt: str = 'Select Folder', + root: str = '', + chroot: bool = False, + enable_new_directories: bool = True, + edit_field: bool = False, + new_dialog_style: bool = False, + *, + blocking: bool = True, + ) -> Union[str, None, FutureResult[str], FutureResult[None]]: + if not chroot: + starting_folder = '*' + else: + starting_folder = '' + starting_folder += root + if enable_new_directories: + opts = 1 + else: + opts = 0 + if edit_field: + opts += 2 + if new_dialog_style: + opts += 4 + args = [starting_folder, str(opts), prompt] + return self._transport.function_call('AHKFileSelectFolder', args, blocking=blocking) def block_forever(self) -> NoReturn: """ diff --git a/ahk/_sync/transport.py b/ahk/_sync/transport.py index 75c56d1..0c964f8 100644 --- a/ahk/_sync/transport.py +++ b/ahk/_sync/transport.py @@ -79,6 +79,7 @@ def result(self, timeout: Optional[float] = None) -> T_SyncFuture: 'AHKControlGetText', 'AHKControlSend', 'AHKFileSelectFile', + 'AHKFileSelectFolder', 'AHKGetClipboard', 'AHKGetClipboardAll', 'AHKGetCoordMode', @@ -584,7 +585,8 @@ def function_call(self, function_name: Literal['AHKMsgBox'], args: Optional[List def function_call(self, function_name: Literal['AHKInputBox'], args: Optional[List[str]] = None, *, blocking: bool = True) -> Union[str, None, FutureResult[str], FutureResult[None]]: ... @overload def function_call(self, function_name: Literal['AHKFileSelectFile'], args: Optional[List[str]] = None, *, blocking: bool = True) -> Union[str, None, FutureResult[str], FutureResult[None]]: ... - + @overload + def function_call(self, function_name: Literal['AHKFileSelectFolder'], args: Optional[List[str]] = None, *, blocking: bool = True) -> Union[str, None, FutureResult[str], FutureResult[None]]: ... # fmt: on def function_call( diff --git a/ahk/templates/daemon.ahk b/ahk/templates/daemon.ahk index f2bb845..fead619 100644 --- a/ahk/templates/daemon.ahk +++ b/ahk/templates/daemon.ahk @@ -2720,6 +2720,22 @@ AHKFileSelectFile(byRef command) { return ret } +AHKFileSelectFolder(byRef command) { + global STRINGRESPONSEMESSAGE + starting_folder := command[2] + options := command[3] + prompt := command[4] + + FileSelectFolder, output, %starting_folder%, %options%, %prompt% + + if (ErrorLevel = 1) { + ret := FormatNoValueResponse() + } else { + ret := FormatResponse(STRINGRESPONSEMESSAGE, output) + } + return ret +} + b64decode(ByRef pszString) { ; TODO load DLL globally for performance ; REF: https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinaryw