From 55b289a77a59170f10373356ee84621c1e381250 Mon Sep 17 00:00:00 2001 From: jolheiser Date: Thu, 21 Apr 2022 15:14:50 -0500 Subject: [PATCH] Initial commit Signed-off-by: jolheiser --- .gitignore | 1 + .woodpecker.yml | 27 ++++ LICENSE | 19 +++ README.md | 9 ++ icon.ico | Bin 0 -> 27503 bytes src/CheckReg.ahk | 9 ++ src/CheckReg.bat | 2 + src/Navigator-Install.ahk | 35 ++++++ src/Navigator.ahk | 254 ++++++++++++++++++++++++++++++++++++++ src/NavigatorUtil.ahk | 171 +++++++++++++++++++++++++ src/Uninstall.bat | 2 + src/config.ini | 19 +++ src/options.ahk | 9 ++ 13 files changed, 557 insertions(+) create mode 100644 .gitignore create mode 100644 .woodpecker.yml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 icon.ico create mode 100644 src/CheckReg.ahk create mode 100644 src/CheckReg.bat create mode 100644 src/Navigator-Install.ahk create mode 100644 src/Navigator.ahk create mode 100644 src/NavigatorUtil.ahk create mode 100644 src/Uninstall.bat create mode 100644 src/config.ini create mode 100644 src/options.ahk diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..62c8935 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea/ \ No newline at end of file diff --git a/.woodpecker.yml b/.woodpecker.yml new file mode 100644 index 0000000..64e99ab --- /dev/null +++ b/.woodpecker.yml @@ -0,0 +1,27 @@ +pipeline: + compile-util: + image: jolheiser/woodpecker-ahk:latest + settings: + script: src/NavigatorUtil.ahk + icon: icon.ico + out: src/NavigatorUtil.exe + compile-main: + image: jolheiser/woodpecker-ahk:latest + settings: + script: src/Navigator.ahk + icon: icon.ico + out: src/Navigator.exe + compile-installer: + image: jolheiser/woodpecker-ahk:latest + settings: + script: src/Navigator-Install.ahk + icon: icon.ico + out: src/Navigator-Install.exe + release-main: + image: jolheiser/drone-gitea-main:latest + settings: + base: https://git.jojodev.com + token: + from_secret: gitea_token + files: + - "src/Navigator-Install.exe" \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ec2045e --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2022 John Olheiser + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..62e7e65 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# Navigator + +![icon](icon.ico) + +An AHK script to allow quick movement to specified directories. + +## License + +[MIT](LICENSE) \ No newline at end of file diff --git a/icon.ico b/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..8221de0ac7a0571e9ed1b777d247be9a7dd3523c GIT binary patch literal 27503 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 B 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 literal 0 HcmV?d00001 diff --git a/src/CheckReg.ahk b/src/CheckReg.ahk new file mode 100644 index 0000000..ca5857b --- /dev/null +++ b/src/CheckReg.ahk @@ -0,0 +1,9 @@ +RegRead, k_test, HKCR, Directory\shell\Navigator_Add +If k_test = +{ + MsgBox, 36, Navigator, Would you like Navigator to add its options to folder/background context menus? + IfMsgBox, Yes + { + Run, %k_base%\NavigatorUtil.exe WriteReg + } +} \ No newline at end of file diff --git a/src/CheckReg.bat b/src/CheckReg.bat new file mode 100644 index 0000000..0e462cb --- /dev/null +++ b/src/CheckReg.bat @@ -0,0 +1,2 @@ +@ECHO OFF +start "" %~dp0\NavigatorUtil.exe CheckReg \ No newline at end of file diff --git a/src/Navigator-Install.ahk b/src/Navigator-Install.ahk new file mode 100644 index 0000000..8a29066 --- /dev/null +++ b/src/Navigator-Install.ahk @@ -0,0 +1,35 @@ +#Include options.ahk + +;CHECK CONFIG +Gosub, CheckConfig + +return + + +CheckConfig: + IfExist, %k_config% + { + IniRead, k_ver, %k_config%, System, Version, 0.0.0 + If (k_version != k_ver) + { + IfExist, %k_base%\Uninstall.bat + { + MsgBox, 16, Navigator, Please run the uninstaller before updating Navigator!`nThis ensures a clean install with no orphaned objects.`n`nUninstaller location: %k_base%\Uninstall.bat + ExitApp + } + } + } + FileCreateDir, %k_base% + FileInstall, config.ini, %k_config%, 0 + IniWrite, %k_version%, %k_config%, System, Version + FileInstall, Navigator.exe, %k_base%\Navigator.exe, 1 + FileInstall, NavigatorUtil.exe, %k_base%\NavigatorUtil.exe, 1 + FileInstall, CheckReg.bat, %k_base%\CheckReg.bat, 1 + FileInstall, Uninstall.bat, %k_base%\Uninstall.bat, 1 + #Include CheckReg.ahk + MsgBox, 36, Navigator, Installed successfully!`nWould you like to start Navigator? + IfMsgBox, Yes + { + Run, %k_base%\Navigator.exe + } +return \ No newline at end of file diff --git a/src/Navigator.ahk b/src/Navigator.ahk new file mode 100644 index 0000000..f4b19a8 --- /dev/null +++ b/src/Navigator.ahk @@ -0,0 +1,254 @@ +#SingleInstance Force +#Include options.ahk + +;INIT MENU +Menu, NavMenu, Add + +;(RE)LOAD CONFIG +Gosub, ReloadConfig + +;INIT HOTKEY +Hotkey, #n, DisplayNavMenu + +;GENERATE ADDRESS CALLBACK +k_address := RegisterCallback("ReloadConfigCallback") +IniWrite, %k_address%, %k_config%, System, Address + +;MONITOR CONFIG +FileRead, k_monitor, %k_config% +SetTimer, MonitorConfig, 1000 + +return + +MonitorConfig: + FileRead, k_monitor_temp, %k_config% + if (k_monitor_temp != k_monitor) + { + k_monitor := k_monitor_temp + GoSub, ReloadConfig + TrayTip, Navigator, Config Reloaded + } +return + +ReloadConfigCallback() { + GoSub, ReloadConfig + TrayTip, Navigator, Config Reloaded +} + +ReloadConfig: + Gosub, GenerateNavMenu + Gosub, GenerateTrayMenu +return + +GenerateTrayMenu: + Menu, TRAY, DeleteAll + Menu, TRAY, Tip, Navigator + Menu, TRAY, NoStandard + Menu, TRAY, Add, Navigator v%k_version%, Help + Menu, TRAY, Default, Navigator v%k_version% + Menu, TRAY, Add + Menu, TRAY, Add, &Navigator, :NavMenu + fn := Func("ExploreTo").Bind(k_config, true) + Menu, SystemMenu, Add, Lock Menus, Lock + If k_lock + Menu, SystemMenu, Check, Lock Menus + Menu, SystemMenu, Add, Edit Config, %fn% + ;Menu, SystemMenu, Add, Reload Config, ReloadConfig + Menu, SystemMenu, Add, Close, Close + Menu, TRAY, Add, &System, :SystemMenu +return + + +Lock: + If k_lock { + k_lock := false + } else { + k_lock := true + } + Menu, SystemMenu, ToggleCheck, Lock Menus + GoSub, GenerateNavMenu +return + +GenerateNavMenu: + Gui, Menu + Menu, NavMenu, DeleteAll + CreateMenu("NavMenu") +return + +CreateMenu(menu_name) { + global k_config, k_lock, k_ext_pattern + IniRead, k_nav_config, %k_config%, %menu_name% + If (k_nav_config == "") + { + MsgBox,, %menu_name%, No paths found for this sub-menu, please add some to the config. + } + StringSplit, k_nav, k_nav_config, `n + Loop, %k_nav0% + { + StringSplit, k_nav_array, k_nav%A_Index%, `, + If (k_nav_array0 > 1) + { + ; We have a path to work with + fn := Func("ExploreTo").Bind(k_nav_array2) + k_pos := RegExMatch(k_nav_array2, k_ext_pattern) + If (k_pos > 0) + { + Menu, %menu_name%, Add, %k_nav_array1%, %fn%, +Radio + Menu, %menu_name%, Check, %k_nav_array1% + } else { + Menu, %menu_name%, Add, %k_nav_array1%, %fn% + } + + } else { + ; No path, so this is a new menu + Menu, %k_nav_array1%, Add + Menu, %k_nav_array1%, DeleteAll + k_menu_name := k_nav_array1 + k_menu_ini := k_nav_array1 + StringSplit, k_menu_array, k_menu_name, | + If (k_menu_array0 > 1) + { + k_menu_name := k_menu_array2 + k_menu_ini := k_menu_array1 + } + CreateMenu(k_menu_ini) + Menu, %menu_name%, Add, %k_menu_name%, :%k_menu_ini% + } + } + If not k_lock { + Menu, %menu_name%, Add + fn := Func("AddMenuItem").Bind(menu_name) + Menu, %menu_name%, Add, Add, %fn% + } +} + +DisplayNavMenu: + WinGet, k_window_id, ID, A + WinGetClass, k_class, ahk_id %k_window_id% + ControlGetFocus, k_control, ahk_id %k_window_id% + if k_class in ExploreWClass,CabinetWClass + { + ; Try to activate the edit, this sometimes fixes weird issues + SendInput, {AltDown}d{AltUp}{Esc} + ControlGetPos, k_Edit1Pos,,,, Edit1, ahk_id %k_window_id% + } else if k_class in #32770 + { + ControlGetPos, k_Edit2Pos,,,, Edit2, ahk_id %k_window_id% + } + if k_class in #32770,ExploreWClass,CabinetWClass ; Dialog or Explorer. + { + if k_Edit1Pos = ; The control doesn't exist + { + WinActivate, ahk_id %k_window_id% + if k_class in ExploreWClass,CabinetWClass + ControlGetPos, k_Edit1Pos,,,, Edit1, ahk_id %k_window_id% + else if k_class in #32770 + ControlGetPos, k_Edit2Pos,,,, Edit2, ahk_id %k_window_id% + } + } + Menu, NavMenu, Show +return + +AddMenuItem(menu_name) { + global + InputBox, k_label, Navigator, %menu_name%`nPlease enter the name of the new menu item + InputBox, k_path, Navigator, %menu_name%`nPlease enter the path to the new menu item`nIf this is a new sub-menu`, leave this blank + If (k_path == "") + IniWrite, %k_label%, %k_config%, %menu_name% + Else + IniWrite, %k_label%`,%k_path%, %k_config%, %menu_name% + GoSub, ReloadConfig +} + +ExploreTo(location) { + global + RegExMatch(location, k_branch_pattern, k_match) + if k_match <> + { + InputBox, k_replacement, Navigator, %k_match2% + if k_replacement <> + { + location := StrReplace(location, k_match1, k_replacement) + } else { + return + } + } + if k_class = #32770 ; It's a dialog. + { + if k_Edit2Pos <> ; And it has an Edit2 control. + { + ; Activate the window so that if the user is middle-clicking + ; outside the dialog, subsequent clicks will also work: + WinActivate ahk_id %k_window_id% + ; Retrieve any filename that might already be in the field so + ; that it can be restored after the switch to the new folder: + ControlGetText, k_text, Edit1, ahk_id %k_window_id% + ControlSetText, Edit2, %location%, ahk_id %k_window_id% + ControlSend, Edit2, {Enter}, ahk_id %k_window_id% + Sleep, 100 ; It needs extra time on some dialogs or in some cases. + ControlSetText, Edit1, %k_text%, ahk_id %k_window_id% + GoSub, Cleanup + return + } + ; else fall through to the bottom of the subroutine to take standard action. + } + else if k_class in ExploreWClass,CabinetWClass ; In Explorer, switch folders. + { + if k_Edit1Pos <> ; And it has an Edit1 control. + { + ControlSetText, Edit1, %location%, ahk_id %k_window_id% + ; Tekl reported the following: "If I want to change to Folder L:\folder + ; then the addressbar shows http://www.L:\folder.com. To solve this, + ; I added a {right} before {Enter}": + ControlSend, Edit1, {Right}{Enter}, ahk_id %k_window_id% + GoSub, Cleanup + return + } + ; else fall through to the bottom of the subroutine to take standard action. + } + else if k_class in ConsoleWindowClass,TMobaXTermForm,mintty ; In a console window, CD to that directory + { + WinActivate, ahk_id %k_window_id% ; Because sometimes the mclick deactivates it. + SetKeyDelay, 0 ; This will be in effect only for the duration of this thread. + IfInString, k_path, : ; It contains a drive letter + { + StringLeft, k_path_drive, location, 1 + Send %k_path_drive%:{enter} + } + Send, cd "%location%"{Enter} + GoSub, Cleanup + return + } + else if InStr(k_control, "Edit") == 1 ; If Navigator is called from an edit control, modify it + { + ControlSetText, %k_control%, %location%, ahk_id %k_window_id% + ControlSend, %k_control%, {Right}{Enter}, ahk_id %k_window_id% + GoSub, Cleanup + return + } + GoSub, Cleanup + Run, Explorer %location% +} + +Cleanup: + k_window_id= + k_class= + k_control= +return + +Help: + RegRead, k_reg, HKCR, Directory\shell\Navigator_Add + k_reg_help= + if k_reg <> + { + k_reg_help = `n`nRegistry Extension:`n- New context menu options to add a file/folder to Navigator`n- New context menu options to copy a file/folder's path to the clipboard + } + MsgBox, 32, Navigator, Navigator v%k_version%`nThis program was created to aid in quickly navigating to common directories/files.`n`nFeatures:`n- Infinite sub-menus`; Organize your navigations as much as you want.`n- Simple naming`; To rename a folder, simple add a pipe (|) followed by the preferred name`n- Window detection`; In File Explorer`, switch to the directory. In command prompt`, cd to the directory. `n- Hotkey support`; Press the windows key + N to bring up the navigator menu.`n- If the path is a file instead of a directory, Navigator will open the file.*`n`n* File paths will be denoted by a radio mark next to their entry.%k_reg_help% +return + +;This is the only way to actually close the application +Close: + MsgBox, 52, Navigator, Are you sure you want to close the Navigator? + IfMsgBox, YES + ExitApp +return \ No newline at end of file diff --git a/src/NavigatorUtil.ahk b/src/NavigatorUtil.ahk new file mode 100644 index 0000000..14f2ffb --- /dev/null +++ b/src/NavigatorUtil.ahk @@ -0,0 +1,171 @@ +#SingleInstance Off +#Include options.ahk + +;INIT MENU +Menu, NavMenu, Add + +k_args_len=%0% + +if (k_args_len == 0) +{ + MsgBox,, NavigatorUtil, No arguments given. Specify "CheckReg", "AddItem", "Copy", or "Uninstall" + ExitApp +} + +Loop, %0% +{ + if (A_Index > 1) + { + k_arg := %A_Index% + k_index := A_Index - 1 + k_args%k_index% := k_arg + } +} +GoSub, %1% +ExitApp + +CheckReg: + #Include CheckReg.ahk +return + +WriteReg: + if not (A_IsAdmin) + { + ; Circular loop for admin privileges + Run *RunAs "%A_ScriptFullPath%" WriteReg /restart + ExitApp + } + + ; Add to Navigator contexts + + ; Folder context + RegWrite, REG_SZ, HKCR, Directory\shell\Navigator_Add,, Add folder to Navigator + RegWrite, REG_SZ, HKCR, Directory\shell\Navigator_Add, Icon, "%A_ScriptFullPath%" + RegWrite, REG_SZ, HKCR, Directory\shell\Navigator_Add\command,, "%A_ScriptFullPath%" "AddItem" "`%V" + + ; Background context + RegWrite, REG_SZ, HKCR, Directory\Background\shell\Navigator_Add,, Add folder to Navigator + RegWrite, REG_SZ, HKCR, Directory\Background\shell\Navigator_Add, Icon, "%A_ScriptFullPath%" + RegWrite, REG_SZ, HKCR, Directory\Background\shell\Navigator_Add\command,, "%A_ScriptFullPath%" "AddItem" "`%V" + + ; File context + RegWrite, REG_SZ, HKCR, *\shell\Navigator_Add,, Add file to Navigator + RegWrite, REG_SZ, HKCR, *\shell\Navigator_Add, Icon, "%A_ScriptFullPath%" + RegWrite, REG_SZ, HKCR, *\shell\Navigator_Add\command,, "%A_ScriptFullPath%" "AddItem" "`%1" + + + ; Copy location contexts + + ; Folder context + RegWrite, REG_SZ, HKCR, Directory\shell\Navigator_Copy,, Copy folder location + RegWrite, REG_SZ, HKCR, Directory\shell\Navigator_Copy, Icon, "%A_ScriptFullPath%" + RegWrite, REG_SZ, HKCR, Directory\shell\Navigator_Copy\command,, "%A_ScriptFullPath%" "Copy" "`%V" + + ; Background context + RegWrite, REG_SZ, HKCR, Directory\Background\shell\Navigator_Copy,, Copy folder location + RegWrite, REG_SZ, HKCR, Directory\Background\shell\Navigator_Copy, Icon, "%A_ScriptFullPath%" + RegWrite, REG_SZ, HKCR, Directory\Background\shell\Navigator_Copy\command,, "%A_ScriptFullPath%" "Copy" "`%V" + + ; File context + RegWrite, REG_SZ, HKCR, *\shell\Navigator_Copy,, Copy file location + RegWrite, REG_SZ, HKCR, *\shell\Navigator_Copy, Icon, "%A_ScriptFullPath%" + RegWrite, REG_SZ, HKCR, *\shell\Navigator_Copy\command,, "%A_ScriptFullPath%" "Copy" "`%1" + +return + +Uninstall: + RegRead, k_reg, HKCR, Directory\shell\Navigator_Add + if k_reg <> + { + if not (A_IsAdmin) + { + ; Circular loop for admin privileges + Run *RunAs "%A_ScriptFullPath%" Uninstall /restart + ExitApp + } + } + + MsgBox, 35, Navigator, Uninstalling Navigator...`nWould you like to keep your config.ini? + IfMsgBox, Cancel + { + ExitApp + } else { + RegDelete, HKCR, Directory\shell\Navigator_Add + RegDelete, HKCR, Directory\Background\shell\Navigator_Add + RegDelete, HKCR, *\shell\Navigator_Add + RegDelete, HKCR, Directory\shell\Navigator_Copy + RegDelete, HKCR, Directory\Background\shell\Navigator_Copy + RegDelete, HKCR, *\shell\Navigator_Copy + } + IfMsgBox, Yes + { + Run, %ComSpec% /c "TASKKILL /f /im `"Navigator.exe`" > nul 2> nul & SLEEP 1 > nul 2> nul & DEL %A_ScriptDir%\*.bat > nul 2> nul & DEL %A_ScriptDir%\*.exe > nul 2> nul" ; Batch files and exe files + } else IfMsgBox, No + { + Run, %ComSpec% /c "TASKKILL /f /im `"Navigator.exe`" > nul 2> nul & SLEEP 1 > nul 2> nul & RD /S /Q %A_ScriptDir% > nul 2> nul" + } +return + +AddItem: + Gui, Menu + Menu, NavMenu, DeleteAll + CreateMenu("NavMenu") + Menu, NavMenu, Show +return + +Copy: + Clipboard = %k_args1% +return + +ReloadConfig: + IniRead, k_address, %k_config%, System, Address + DllCall(%k_address%) +return + +Select(menu_name) { + global k_config, k_args1 + InputBox, k_label, Navigator, %menu_name%`nPlease enter the name of the new menu item + if (k_label <> "") + { + IniWrite, %k_label%`,%k_args1%, %k_config%, %menu_name% + GoSub, ReloadConfig + } else { + MsgBox, 21, Navigator, You must enter a name for this sub-menu. + IfMsgBox, Retry + { + Select(menu_name) + } + } +} + +CreateMenu(menu_name) { + global k_config, k_ext_pattern + IniRead, k_nav_config, %k_config%, %menu_name% + If (k_nav_config == "") + { + MsgBox,, %menu_name%, No paths found for this sub-menu, please add some to the config. + } + StringSplit, k_nav, k_nav_config, `n + Loop, %k_nav0% + { + StringSplit, k_nav_array, k_nav%A_Index%, `, + If (k_nav_array0 == 1) + { + ; No path, so this is a new menu + Menu, %k_nav_array1%, Add + Menu, %k_nav_array1%, DeleteAll + k_menu_name := k_nav_array1 + k_menu_ini := k_nav_array1 + StringSplit, k_menu_array, k_menu_name, | + If (k_menu_array0 > 1) + { + k_menu_name := k_menu_array2 + k_menu_ini := k_menu_array1 + } + CreateMenu(k_menu_ini) + Menu, %menu_name%, Add, %k_menu_name%, :%k_menu_ini% + } + } + fn := Func("Select").Bind(menu_name) + Menu, %menu_name%, Add, Select This Menu, %fn% +} \ No newline at end of file diff --git a/src/Uninstall.bat b/src/Uninstall.bat new file mode 100644 index 0000000..1dc0317 --- /dev/null +++ b/src/Uninstall.bat @@ -0,0 +1,2 @@ +@ECHO OFF +start "" %~dp0\NavigatorUtil.exe Uninstall \ No newline at end of file diff --git a/src/config.ini b/src/config.ini new file mode 100644 index 0000000..ada193d --- /dev/null +++ b/src/config.ini @@ -0,0 +1,19 @@ +; To re-run the registry check, go to your config folder and run CheckReg.bat +; To uninstall, go to your config folder and run Uninstall.bat + +[NavMenu] +; Without a path, Navigator will assume the next line corresponds with a sub-menu +; Notice the pipe (|) used to rename the sub-menu. Each sub-menu needs to match a specific "header" in the ini file, but sometimes the names double up, so renaming can look better visually. +Config|NavMenu + +[Config] +; A sub-menu for the above matching line in NavMenu + +; Notice this path leads directly to a file, so Navigator will mark it in the sub-menu with a radio button mark +Config File,C:\Applications\Navigator\config.ini + +; If the path is a directory, Navigator will open to that folder. This is really the core of the project and is supported in File Explorer, Command Line, and MobaXTerm. +Config Folder,C:\Applications\Navigator + +[System] +; DO NOT MODIFY \ No newline at end of file diff --git a/src/options.ahk b/src/options.ahk new file mode 100644 index 0000000..f94fc41 --- /dev/null +++ b/src/options.ahk @@ -0,0 +1,9 @@ +;SYSTEM +k_version=2.0.5 ; Version number + +;OPTIONS +k_base=C:\Applications\Navigator ; Base path to the application folder +k_config=%k_base%\config.ini ; Where to store the config file +k_lock=true ; Whether to show the 'Add' options on menus/sub-menus initially +k_branch_pattern=.*(<(.+)>).* ; The regex pattern to match for branching paths +k_ext_pattern=\w+\.\w+$ ; The regex pattern to match for file extensions \ No newline at end of file