navigator/src/Navigator.ahk

254 lines
7.3 KiB
Plaintext

#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