/* PSPad Helper ============ Hotkey = Win+Q Shows/hides a listview of all labels in the active PSPad window. - Double-click the label name to go to the line in PSPad. ============ Things to do (maybe): ; dock / attach window to pspad? ; store gui position and settings to ini file instead of positioning automatically (then size downwards until bottom of screen reached) ; change PSPad references to allow usage for other editors ; find unused labels and functions */ #Persistent #SingleInstance force SetBatchLines, -1 Labels =1 ;starting state of checkbox Functions =0 Hotkeys =0 Directives =0 Show_All_Lines =0 WS_VSCROLL =0x200000 SysGet, Scrollbar_Vertical_Thickness, 2 ; 2 is SM_CXVSCROLL, Width of a vertical scroll bar If A_OSVersion =WIN_2000 lv_h_win_2000_adj =2 ; adjust height of main listview by +2 pixels to avoid scrollbar in windows 2000 Else lv_h_win_2000_adj =0 GroupAdd, PSPad_and_PSPad_Helper, ahk_class TfPSPad GroupAdd, PSPad_and_PSPad_Helper, PSPad Helper ahk_class AutoHotkeyGUI ; create gui Gui, Margin, 2, 2 Gui, Add, Radio, Group vLabels gPSPad_Labels_Gui_No_Hide Checked%Labels% xm+2, Labels Gui, Add, Radio, vHotkeys gPSPad_Labels_Gui_No_Hide Checked%Hotkeys% yp x82, Hotkeys Gui, Add, Radio, vFunctions gPSPad_Labels_Gui_No_Hide Checked%Functions% xm+2, Functions Gui, Add, Radio, vDirectives gPSPad_Labels_Gui_No_Hide Checked%Directives% yp x82, Directives Gui, Add, Radio, vShow_All_Lines gPSPad_Labels_Gui_No_Hide Checked%Show_All_Lines% xm+2, Show all lines Gui, Add, Text,xm+2 yp+20, Filter: Gui, Add, Edit, r1 -Multi vFilter_Edit xp+28 yp-3,%Filter_Edit% Gui, Add, Button, vFilter_Edit_Go gPSPad_Labels_Gui_No_Hide xp yp-1 Default, Go ; move before showing Gui, Add, ListView, r20 w700 vListView gListView_Event xm, Line|Command Gui_Shown_Status =0 Gui, +LastFound Gui_ID := WinExist() ; for auto-sizing columns later Return #IfWinActive, ahk_group PSPad_and_PSPad_Helper #q:: IfWinActive, ahk_class TfPSPad ; otherwise gui is active PSPad_ID := WinExist("A") Gosub PSPad_Labels_Gui Return PSPad_Labels_Gui: SetTimer, Check_PSPad_Still_Active, 1000 If Gui_Shown_Status = 1 ; i.e. visible { Gosub, GuiClose Return } Gui_Shown_Status := !Gui_Shown_Status PSPad_Labels_Gui_No_Hide: SetTimer, PSPad_Labels_Gui_No_Hide, off Gui, Submit, NoHide Fill_ListView() ; use a function to avoid left-over variables Return Fill_ListView() { Global ListView, PSPad_ID, Gui_ID, Labels, Functions, Hotkeys, Directives, Filter_Edit, Show_All_Lines , Filter_Edit_Go, Scrollbar_Vertical_Thickness, WS_VSCROLL, PSPad_Edit_Control, lv_h_win_2000_adj LV_Delete() ; clear listview ; get text IfWinActive, ahk_class TfPSPad ; otherwise gui is active ControlGetFocus, PSPad_Edit_Control,ahk_id %PSPad_ID% ControlGetText, Text, %PSPad_Edit_Control%, ahk_id %PSPad_ID% If Text contains † ; seems to always contain this character and lots of question marks when wrong (pspad thing!) { If Text contains ??????? { WinGet, Active_Window, ID, A If Active_Window != ahk_id %PSPad_ID% ; i.e. PSPad Helper active WinActivate, ahk_id %PSPad_ID% ControlGetFocus, PSPad_Edit_Control, ahk_id %PSPad_ID% ControlGetPos, PSPad_Control_X, PSPad_Control_Y, PSPad_Control_W, PSPad_Control_H, %PSPad_Edit_Control%, ahk_id %PSPad_ID% MouseGetPos, Original_Mouse_X, Original_Mouse_Y MouseMove, PSPad_Control_X + PSPad_Control_W / 2, PSPad_Control_Y + PSPad_Control_H / 2, 0 Loop, 5 ; max limit just in case it never retrieves text { If Text contains † ; seems to always contain this character and lots of question marks when wrong { If Text contains ??????? ControlGetText, Text, %PSPad_Edit_Control%,ahk_id %PSPad_ID% } Else Break } MouseMove, %Original_Mouse_X%, %Original_Mouse_Y%, 0 If Active_Window != ahk_id %PSPad_ID% ; i.e. PSPad Helper was active WinActivate, ahk_id %Active_Window% } } StringSplit, Text, Text,`n Loop, %Text0% ; filter results and add to listview { Item_Found =0 ; Strip_Comments Comment_Position := InStr(Text%A_Index%, ";", 0, 0) ; search from right to left for comment ";" If Comment_Position !=0 StringLeft, Text%A_Index%, Text%A_Index%, %Comment_Position% If Show_All_Lines =1 Gosub, ListView_Add If (Labels =1 and Item_Found =0) { If Text%A_Index% contains : ; find labels { If Text%A_Index% not contains ,,,=,:: { Colon_Position := InStr(Text%A_Index%, ":") StringLeft, Text%A_Index%, Text%A_Index%, %Colon_Position% Gosub, Trim_Leading_Spaces_From_Current_Line_to_temp_var If Text%Current_Loop%_temp not contains %A_Space% Gosub, ListView_Add } } } If (Hotkeys =1 and Item_Found =0) { Gosub, Trim_Leading_Spaces_From_Current_Line_to_temp_var StringLeft, Check_If_Hotkey_At_Start_Of_Line, Text%Current_Loop%_temp, 7 If Check_If_Hotkey_At_Start_Of_Line =Hotkey, Gosub, ListView_Add Else If Text%A_Index% contains :: { If Text%A_Index% not contains if,instr,Add,,%A_Space% Gosub, ListView_Add } } If (Functions =1 and Item_Found =0) { If (InStr(Text%A_Index%,"(") and InStr(Text%A_Index%,")")) { Next_Line := A_Index + 1 If ((InStr(Text%A_Index%,"{") or (InStr(Text%Next_Line%,"{"))) and not InStr(Text%A_Index%,"=") and not InStr(Text%Next_Line%,"loop") and not InStr(Text%Next_Line%,"if") and not InStr(Text%Next_Line%,"else")) { Bracket_Position := InStr(Text%A_Index%, "(") StringLeft, Text%A_Index%, Text%A_Index%, %Bracket_Position% Gosub, Trim_Leading_Spaces_From_Current_Line_to_temp_var If Text%Current_Loop%_temp not contains %A_Space% Gosub, ListView_Add } } } If (Directives =1 and Item_Found =0) { If Text%A_Index% contains # { If Text%A_Index% not contains :: { Gosub, Trim_Leading_Spaces_From_Current_Line_to_temp_var Hash_Position := InStr(Text%A_Index%, "#") If Hash_Position =1 Gosub, ListView_Add } } } } DetectHiddenWindows, On ; Automatically resize listview vertically Number_Rows := LV_GetCount() If Filter_Edit != { Row_To_Process := Number_Rows + 1 ; initialise Loop, %Number_Rows% { Row_To_Process -=1 LV_GetText(Line_Text, Row_To_Process, 2) If Line_Text not contains %Filter_Edit% LV_Delete(Row_To_Process) } Number_Rows := LV_GetCount() } If Number_Rows =0 ; error retrieving text / maybe all filtered { Number_Rows =1 LV_Add("", "", "No items to display!") } ; ListView height If (Number_Rows > (A_ScreenHeight - 95)/15) ; set a max height Number_Rows := (A_ScreenHeight - 95)/15 SendMessage, 0x1000+31, 0, 0, SysListView321, ahk_id %Gui_ID% ; LVM_GETHEADER WinGetPos,,,, lv_header_h, ahk_id %ErrorLevel% VarSetCapacity( rect, 16, 0 ) SendMessage, 0x1000+14, 0, &rect, SysListView321, ahk_id %Gui_ID% ; LVM_GETITEMRECT ; LVIR_BOUNDS y1 := 0 y2 := 0 Loop, 4 { y1 += *( &rect + 3 + A_Index ) y2 += *( &rect + 11 + A_Index ) } lv_row_h := y2 - y1 lv_h := 4 + lv_header_h + ( lv_row_h * Number_Rows ) + lv_h_win_2000_adj GuiControl, Move, SysListView321, h%lv_h% LV_ModifyCol(1, "Integer") ; For sorting purposes, indicate that column 2 is an integer. ; ListView width LV_ModifyCol(1, AutoHdr) ; Auto-size column LV_ModifyCol(2) ; Auto-size column SendMessage, 0x1000+29, 0, 0, SysListView321, ahk_id %Gui_ID% ; LVM_GETCOLUMNWIDTH is 0x1000+29 Width_Column_1 := ErrorLevel SendMessage, 0x1000+29, 1, 0, SysListView321, ahk_id %Gui_ID% ; LVM_GETCOLUMNWIDTH is 0x1000+29 Width_Column_2 := ErrorLevel ListView_Width := Width_Column_1 + Width_Column_2 + 4 If ListView_Width < 190 ; maintain minimum width ListView_Width =190 Else If ( ListView_Width > A_ScreenWidth / 3 ) ; maintain maximum width ListView_Width := A_ScreenWidth / 3 GuiControl, Move, ListView, w%ListView_Width% ControlGet, ListView_Style, Style,, SysListView321, ahk_id %Gui_ID% If ( ListView_Style & WS_VSCROLL ) { ListView_Width := ListView_Width + Scrollbar_Vertical_Thickness GuiControl, Move, ListView, w%ListView_Width% } Filter_Edit_W := ListView_Width -58 GuiControl, Move, Filter_Edit, w%Filter_Edit_W% Filter_Edit_Go_x := Filter_Edit_W + 33 GuiControl, Move, Filter_Edit_Go, x%Filter_Edit_Go_x% Gui_Pos_X := A_ScreenWidth - ListView_Width - Scrollbar_Vertical_Thickness - 12 Gui, +AlwaysOnTop +ToolWindow Gui, Show, AutoSize x%Gui_Pos_X% yCenter, PSPad Helper GuiControl, Focus, Filter_Edit Return ListView_Add: LV_Add("", A_Index, Text%A_Index%) Item_Found =1 Return Trim_Leading_Spaces_From_Current_Line_to_temp_var: StringLen, Text_Length, Text%A_Index% Current_Loop := A_Index Loop, %Text_Length% ; trim off leading spaces for checking if more than one word remains { StringMid, Check_For_Space_temp, Text%Current_Loop%, %A_Index%, 1 If Check_For_Space_temp !=%A_Space% { Previous_Index_temp := A_Index - 1 StringTrimLeft, Text%Current_Loop%_temp, Text%Current_Loop%, %Previous_Index_temp% Break } } Return } ListView_Event: If A_GuiEvent = DoubleClick { LV_GetText(Row_Number, A_EventInfo) ; Get the row's first-column text. Gosub, GuiClose WinActivate, ahk_id %PSPad_ID% Send, ^g%Row_Number%{Enter} } Return GuiClose: ; Indicate that the script should exit automatically when the window is closed. GuiEscape: SetTimer, Check_PSPad_Still_Active, Off Gui, Submit Gui_Shown_Status := !Gui_Shown_Status Return Check_PSPad_Still_Active: IfWinNotActive, PSPad Gosub, GuiClose Return