Code: Select all
local _KEY,_NAME,_VER = "JD","MenuAutoFilter","1.0.2"
local minfarbuild = 3892 --hDlg:send
local F = far.Flags
local build = select(4,far.AdvControl(F.ACTL_GETFARMANAGERVERSION,true))
if build<minfarbuild
and 2~=far.Message(("FAR 3 build %s or newer required.\nYour build: %s")
:format(minfarbuild,build),_NAME,"Cancel;Continue","lw")
then return
end
---------------------
-- Menu autofilter --
local allMenu = "Menu MainMenu UserMenu Disks "
local set,lock,notempty = 0,1,2 -- first arg of Menu.Filter()
local Auto = mf.mload("JD",_NAME) or {
["880968A6-6258-43E0-9BDC-F2B8678EC278"] = "HistoryCmdId",
["E770E044-23A8-4F4D-B268-0E602B98CCF9"] = "HistoryEditViewId",
["FC3384A8-6608-4C9B-8D6B-EE105F4C5A54"] = "HistoryFolderId",
["937F0B1C-7690-4F85-8469-AA935517F202"] = "PluginsMenuId",
["B4C242E7-AA8E-4449-B0C3-BD8D9FA11AED"] = "PluginsConfigMenuId",
["78A4A4E3-C2F0-40BD-9AA7-EAAC11836631"] = "CodePagesMenuId",
["72EB948A-5F1D-4481-9A91-A4BFD869D127"] = "ScreensSwitchId",
["5B87B32E-494A-4982-AF55-DAFFCD251383"] = "FiltersMenuId",
["4CD742BC-295F-4AFA-A158-7AA05A16BEA1"] = "FolderShortcutsId",
["B8B6E1DA-4221-47D2-AB2E-9EC67D0DC1E3"] = "SelectSortModeId",
["A204FF09-07FA-478C-98C9-E56F61377BDE"] = "AdvancedConfigId",
["4406C688-209F-4378-8B7B-465BF16205FF"] = "SelectFromEditHistoryId",
["Task list"] = true,
}
local isList = {}
----
local function getListId()
local noid = "00000000-0000-0000-0000-000000000000"
local id = Area.Menu and Menu.Id or
Dlg.ItemType==F.DI_LISTBOX and Dlg.Id
id = id==noid and Object.Title or id --??+Dlg.Owner
return id~="" and id
or Area.MainMenu and "MAINMENU"
end
local function reTitle(hDlg,list)
local Title = list.titles.Title
hDlg:send(F.DM_LISTSETTITLES, list.dlgpos, list.auto
and {Title=Title..(Title=="" and "[]" or " []"),Bottom=list.titles.Bottom}
or list.titles
)
end
Event { group="DialogEvent"; description="MenuAutoFilter init";
condition=function(Event,param)
if Event==F.DE_DLGPROCEND then
if param.Msg==F.DN_CLOSE then
isList[param.hDlg:rawhandle()] = nil
else
return param.Msg==F.DN_INITDIALOG
end
end
end;
action=function(Event,param)
local hDlg = param.hDlg
isList[hDlg:rawhandle()] = false --need value different from nil
mf.postmacro(function()
if isList[hDlg:rawhandle()]==nil then return end
local id = getListId(); if not id then return end
local list = {id=id, auto=Auto[id], dlgpos=param.Param1} --nb! ID элемента, который получит фокус ввода по умолчанию.
list.titles = hDlg:send(F.DM_LISTGETTITLES) or {Title="", Bottom=""}
if list.auto then reTitle(hDlg,list) end
isList[hDlg:rawhandle()] = list
end);
end;
}
local BS = 0x8
local CtrlAltMask = bor(F.LEFT_ALT_PRESSED,F.LEFT_CTRL_PRESSED,F.RIGHT_ALT_PRESSED,F.RIGHT_CTRL_PRESSED)
local AltGr = bor(F.LEFT_CTRL_PRESSED,F.RIGHT_ALT_PRESSED)
local function check (state)
local mods = band(state, CtrlAltMask)
return mods==0 or mods==AltGr
end
Event { group="DialogEvent"; description="MenuAutoFilter handler";
condition=function(Event,param)
if not param then error("Event=="..tostring(Event)) end
local input = param.Param2
if Event~=F.DE_DEFDLGPROCINIT
and param.Msg==F.DN_CONTROLINPUT
and input.EventType==F.KEY_EVENT
and check(input.ControlKeyState)
then
local list = isList[param.hDlg:rawhandle()]
return list and list.auto
end
end;
action=function(Event,param)
local input = param.Param2
if Event==F.DE_DLGPROCINIT
and input.UnicodeChar:byte()>=32
and Menu.Filter(set)==0 then
Menu.Filter(set,1)
elseif Event==F.DE_DLGPROCEND
and input.VirtualKeyCode==BS
and Menu.Filter(set)==1 and Menu.Filter(notempty)==0 then
Menu.Filter(set,0)
end
end;
}
----
local function MessagePopup(msg,title,flags,delay)
local s = far.SaveScreen()
far.Message(msg,title or "","",flags)
win.Sleep(delay or 500); far.RestoreScreen(s)
end
local hDlg,list
Macro { description="MenuAutoFilter toggle";
area="Dialog "..allMenu; key="CtrlAltF"; priority=30;
condition=function()
hDlg = far.AdvControl(F.ACTL_GETWINDOWINFO).Id
if not hDlg then return end
list = isList[hDlg:rawhandle()]
return list and (not Area.Dialog or list.dlgpos==Dlg.CurPos)
end;
action=function()
list.auto = not list.auto
reTitle(hDlg,list)
Menu.Filter(set, not list.auto and 0 or nil)
Auto[list.id] = list.auto and Object.Title or nil
MessagePopup(list.auto and "on" or "off","auto filter",nil,1000)
mf.msave(_KEY,_NAME,Auto)
end;
-- mf.mdelete(_KEY,_NAME,"*") --cleanup
}