summaryrefslogtreecommitdiff
path: root/plugins/Actman30/ua
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2013-07-16 20:08:30 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2013-07-16 20:08:30 +0000
commit74e738f374f759723daf8920677158712d0ca5c1 (patch)
tree89a93d70f87e950e28d23466d3c84120ead0e770 /plugins/Actman30/ua
parente5c9c0077f7b50bbfe90201154c31c13e1a6fc63 (diff)
- Actman 3 added (not adopted)
git-svn-id: http://svn.miranda-ng.org/main/trunk@5391 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Actman30/ua')
-rw-r--r--plugins/Actman30/ua/action.icobin0 -> 2550 bytes
-rw-r--r--plugins/Actman30/ua/i_inoutjson.inc355
-rw-r--r--plugins/Actman30/ua/i_inoutxm.inc357
-rw-r--r--plugins/Actman30/ua/i_opt_dlg.inc572
-rw-r--r--plugins/Actman30/ua/i_options.inc252
-rw-r--r--plugins/Actman30/ua/i_ua.inc219
-rw-r--r--plugins/Actman30/ua/i_uaplaces.inc832
-rw-r--r--plugins/Actman30/ua/i_uavars.inc121
-rw-r--r--plugins/Actman30/ua/i_uconst.inc34
-rw-r--r--plugins/Actman30/ua/ua.pas108
-rw-r--r--plugins/Actman30/ua/ua.rc51
11 files changed, 2901 insertions, 0 deletions
diff --git a/plugins/Actman30/ua/action.ico b/plugins/Actman30/ua/action.ico
new file mode 100644
index 0000000000..9e4c60d9d3
--- /dev/null
+++ b/plugins/Actman30/ua/action.ico
Binary files differ
diff --git a/plugins/Actman30/ua/i_inoutjson.inc b/plugins/Actman30/ua/i_inoutjson.inc
new file mode 100644
index 0000000000..61879200a1
--- /dev/null
+++ b/plugins/Actman30/ua/i_inoutjson.inc
@@ -0,0 +1,355 @@
+{}
+var
+ jsonparser:TJSONSERVICEINTERFACE;
+
+const
+ ioAction :PWideChar = 'Action';
+ ioUA :PWideChar = 'UA';
+
+ ioName :PWideChar = 'name';
+
+ ioTwoState :PWideChar = 'twostate';
+ ioSaveState :PWideChar = 'savestate';
+
+ ioHotkey :PWideChar = 'Hotkey';
+ ioToolbar :PWideChar = 'Toolbar';
+ ioTabSRMM :PWideChar = 'TabSRMM';
+ ioMenuItem :PWideChar = 'Menu';
+
+ ioTooltip :PWideChar = 'tooltip';
+ ioTooltipPressed :PWideChar = 'tt_pressed';
+
+ ioType :PWideChar = 'type';
+ ioMenuPopup :PWideChar = 'Popup';
+ ioMenuName :PWideChar = 'Name';
+ ioMenuShow :PWideChar = 'Show';
+ ioMenuUsed :PWideChar = 'Used';
+ ioMenuSeparated :PWideChar = 'Separated';
+
+
+function ImportMenuItems(node:JSONNODE;var MenuItem:tUAMenuItem):integer;
+begin
+ result:=0;
+
+ with jsonparser do
+ begin
+ with MenuItem do
+ begin
+ menu_opt:=0;
+ // popup
+ StrDupW(szMenuPopup,getAttrValue(node,ioMenuPopup));
+ // name
+ StrDupW(szMenuNameVars,getAttrValue(node,ioMenuName));
+ // show
+ StrDupW(szMenuShowWhenVars,getAttrValue(node,ioMenuShow));
+ // used
+ if StrToInt(getAttrValue(node,ioMenuUsed))<>0 then
+ menu_opt:=menu_opt or UAF_MENUUSE;
+ // separated
+ if StrToInt(getAttrValue(node,ioMenuSeparated))<>0 then
+ menu_opt:=menu_opt or UAF_MENUSEP;
+ end;
+ end;
+end;
+
+function ImportUAction(actnode:JSONNODE;var UA:tMyActionItem):integer;
+var
+ num,i:integer;
+ sub:JSONNODE;
+begin
+ result:=0;
+ if actnode=0 then exit;
+
+ with jsonparser do
+ begin
+ // we don't need that node as is, just it's child for UA
+// actnode:=GetNthChild(actnode,ioUA,0);
+
+ UA.flags:=0;
+ // ----- Common -----
+ if StrToInt(getAttrValue(actnode,ioTwoState))<>0 then
+ UA.flags:=UA.flags or UAF_2STATE;
+
+ if StrToInt(getAttrValue(actnode,ioSaveState))<>0 then
+ UA.flags:=UA.flags or UAF_SAVESTATE;
+
+ // sub:=AddChild(actnode,ioRegister,nil);
+ if StrToInt(getAttrValue(actnode,ioHotkey))<>0 then
+ UA.flags:=UA.flags or UAF_REGHOTKEY;
+ if StrToInt(getAttrValue(actnode,ioToolbar))<>0 then
+ UA.flags:=UA.flags or UAF_REGTTBB;
+ if StrToInt(getAttrValue(actnode,ioTabSRMM))<>0 then
+ UA.flags:=UA.flags or UAF_REGTABB;
+
+ // ----- Hotkey -----
+ // nothing
+
+ // ----- Modern CList toolbar -----
+ // source - ANSI text
+ sub:=GetNthChild(actnode,ioToolbar,0);
+ WideToAnsi(GetAttrValue(sub,ioTooltip ),UA.szTTBTooltip ,MirandaCP);
+ WideToAnsi(GetAttrValue(sub,ioTooltipPressed),UA.szTTBTooltipPressed,MirandaCP);
+
+ // ----- TabSRMM toolbar -----
+ sub:=GetNthChild(actnode,ioTabSRMM,0);
+ StrDupW(UA.szTabBTooltip ,getAttrValue(sub,ioTooltip));
+ StrDupW(UA.szTabBTooltipPressed,getAttrValue(sub,ioTooltipPressed));
+
+ // ----- Menus -----
+ num:=0;
+ repeat
+ sub:=getNextChild(actnode,ioMenuItem,@num);
+ if sub=0 then break;
+
+ i:=StrToInt(getAttrValue(sub,ioType));
+ ImportMenuItems(sub,
+ UA.UAMenuItem[tMenuType(i)]);
+ until false;
+ end;
+end;
+
+function Import(fname:PWideChar;aflags:dword):integer;
+var
+ i,j,act:integer;
+ root,actnode:JSONNODE;
+ pcw,res:pWideChar;
+ f:THANDLE;
+ num,num1:integer;
+ ptr,ptr1:pChain;
+begin
+ result:=0;
+
+ if (fname=nil) or (fname^=#0) then
+ exit;
+ i:=GetFSize(fname);
+ if i=0 then
+ exit;
+
+ num:=CallService(MS_ACT_GETLIST,0,LPARAM(@ptr));
+ if num=0 then exit;
+ ptr1:=ptr;
+
+ mGetMem (res ,i+SizeOf(WideChar));
+ FillChar(res^,i+SizeOf(WideChar),0);
+ f:=Reset(fname);
+ BlockRead(f,res^,i);
+ CloseHandle(f);
+
+ CallService(MS_JSON_GETINTERFACE,0,lparam(@jsonparser));
+ with jsonparser do
+ begin
+ root:=parseString(ChangeUnicode(res),@i,nil);
+ j:=0;
+ repeat
+ actnode:=getNthChild(root,ioAction,j);
+ if actnode=0 then break;
+ // search id by name?
+ pcw:=GetAttrValue(actnode,ioName);
+ ptr:=ptr1;
+ inc(pbyte(ptr),4);
+ for i:=0 to num-1 do
+ begin
+ if (ptr.flags and ACCF_IMPORTED)<>0 then
+ begin
+ if StrCmpw(pcw,ptr.descr)=0 then
+ begin
+ // delete old UA for overwrited actions
+ if (ptr.flags and ACCF_OVERLOAD)<>0 then
+ begin
+ for act:=0 to HIGH(UActionList) do
+ begin
+ if ptr.id=UActionList[act].dwActID then
+ begin
+ DeleteUAction(act,true);
+ break;
+ end;
+ end;
+ end;
+ num1:=AddUAction(-1,ptr);
+ ImportUAction(getNthChild(actnode,ioUA,0),UActionList[num1]);
+ break;
+ end;
+ end;
+ inc(ptr);
+ end;
+
+ inc(j);
+ until false;
+
+ DestroyNode(root);
+ end;
+ CallService(MS_ACT_FREELIST,0,LPARAM(ptr1));
+ mFreeMem(res);
+ result:=1;
+ if settings<>0 then
+ begin
+ FillActionList(settings);
+ ShowAction(settings,-1);
+ end;
+end;
+
+//--------------------------
+
+function ExportMenuItems(node:JSONNODE;MenuItem:tUAMenuItem):HXML;
+begin
+ with jsonparser do
+ begin
+ result:=AddChild(node,ioMenuItem,nil);
+ with MenuItem do
+ begin
+ // popup
+ if (szMenuPopup<>nil) and (szMenuPopup^<>#0) then
+ AddAttr(result,ioMenuPopup,szMenuPopup);
+ // name
+ if (szMenuNameVars<>nil) and (szMenuNameVars^<>#0) then
+ AddAttr(result,ioMenuName,szMenuNameVars);
+ // show
+ if (szMenuShowWhenVars<>nil) and (szMenuShowWhenVars^<>#0) then
+ AddAttr(result,ioMenuShow,szMenuShowWhenVars);
+ // used
+ AddAttrInt(result,ioMenuUsed,ord((menu_opt AND UAF_MENUUSE)<>0));
+ // separated
+ AddAttrInt(result,ioMenuSeparated,ord((menu_opt AND UAF_MENUSEP)<>0));
+ end;
+ end;
+end;
+
+procedure WriteUAction(root:JSONNODE;id:dword;name:pWideChar);
+var
+ i:integer;
+ lmenu:tMenuType;
+ pc:pWideChar;
+ actnode,sub:JSONNODE;
+ UA:pMyActionItem;
+begin
+ with jsonparser do
+ begin
+ for i:=0 to HIGH(UActionList) do
+ begin
+ if UActionList[i].dwActID=id then
+ begin
+ UA:=@UActionList[i];
+ actnode:=getChildByAttrValue(root,ioAction,ioName,name);
+ if actnode=0 then break;
+ // we don't need that node as is, just it's child for UA
+ actnode:=addChild(actnode,ioUA,nil);
+
+ // ----- Common -----
+ AddAttrInt(actnode,ioTwoState ,ORD((UA.flags and UAF_2STATE )<>0));
+ AddAttrInt(actnode,ioSaveState,ORD((UA.flags and UAF_SAVESTATE)<>0));
+
+ // sub:=AddChild(actnode,ioRegister,nil);
+ AddAttrInt(actnode,ioHotkey ,ORD((UA.flags and UAF_REGHOTKEY)<>0));
+ AddAttrInt(actnode,ioToolbar,ORD((UA.flags and UAF_REGTTBB )<>0));
+ AddAttrInt(actnode,ioTabSRMM,ORD((UA.flags and UAF_REGTABB )<>0));
+
+ // ----- Hotkey -----
+ // nothing
+
+ // ----- Modern CList toolbar -----
+ // source - ANSI text
+ if ((UA.szTTBTooltip <>nil) and (UA.szTTBTooltip^ <>#0)) or
+ ((UA.szTTBTooltipPressed<>nil) and (UA.szTTBTooltipPressed^<>#0)) then
+ begin
+ sub:=AddChild(actnode,ioToolbar,nil);
+ if (UA.szTTBTooltip<>nil) and (UA.szTTBTooltip^<>#0) then
+ begin
+ AnsiToWide(UA.szTTBTooltip,pc,MirandaCP);
+ AddAttr(sub,ioTooltip,pc);
+ mFreeMem(pc);
+ end;
+ if (UA.szTTBTooltipPressed<>nil) and (UA.szTTBTooltipPressed^<>#0) then
+ begin
+ AnsiToWide(UA.szTTBTooltipPressed,pc,MirandaCP);
+ AddAttr(sub,ioTooltipPressed,pc);
+ mFreeMem(pc);
+ end;
+ end;
+
+ // ----- TabSRMM toolbar -----
+ if ((UA.szTabBTooltip <>nil) and (UA.szTabBTooltip^ <>#0)) or
+ ((UA.szTabBTooltipPressed<>nil) and (UA.szTabBTooltipPressed^<>#0)) then
+ begin
+ sub:=AddChild(actnode,ioTabSRMM,nil);
+ if (UA.szTabBTooltip<>nil) and (UA.szTabBTooltip^<>#0) then
+ AddAttr(sub,ioTooltip,UA.szTabBTooltip);
+ if (UA.szTabBTooltipPressed<>nil) and (UA.szTabBTooltipPressed^<>#0) then
+ AddAttr(sub,ioTooltipPressed,UA.szTabBTooltipPressed);
+ end;
+
+ // ----- Menus -----
+ for lmenu:=main_menu to HIGH(tMenuType) do
+ begin
+ sub:=ExportMenuItems(actnode,UA.UAMenuItem[lmenu]);
+ AddAttrInt(sub,ioType,ORD(lmenu));
+ end;
+
+ break;
+ end;
+ end;
+ end;
+end;
+
+function Export(fname:pWideChar;aflags:dword):integer;
+var
+ i,num:integer;
+ f:THANDLE;
+ root:JSONNODE;
+ res:pWideChar;
+ ptr,ptr1:pChain;
+begin
+ result:=0;
+ CallService(MS_JSON_GETINTERFACE,0,lparam(@jsonparser));
+ with jsonparser do
+ begin
+ // we need append file, not rewrite
+ i:=GetFSize(fname);
+ if i=0 then exit;
+
+ mGetMem (res ,i+SizeOf(WideChar));
+ FillChar(res^,i+SizeOf(WideChar),0);
+ f:=Reset(fname);
+ BlockRead(f,res^,i);
+ CloseHandle(f);
+ root:=parseString(res,@i,nil);
+ mFreeMem(res);
+
+ num:=CallService(MS_ACT_GETLIST,0,LPARAM(@ptr));
+ if num>0 then
+ begin
+ ptr1:=ptr;
+ inc(pbyte(ptr),4);
+ for i:=0 to num-1 do
+ begin
+ if ((aflags and ACIO_SELECTED)=0) or
+ ((ptr.flags and ACCF_EXPORT)<>0) then
+ begin
+ WriteUAction(root,ptr.id,ptr.descr);
+ end;
+ inc(ptr);
+ end;
+ CallService(MS_ACT_FREELIST,0,LPARAM(ptr1));
+ end;
+
+ res:=toString(root,@i);
+
+ f:=Rewrite(fname);
+ BlockWrite(f,res^,i*SizeOf(WideChar));
+ CloseHandle(f);
+ xmlparser.FreeMem(res);
+ DestroyNode(root);
+ end;
+ result:=1;
+end;
+
+function ActInOut(wParam:WPARAM;lParam:LPARAM):int_ptr; cdecl;
+begin
+ if (wParam and ACIO_EXPORT)=0 then
+ begin
+ result:=Import(pWideChar(lParam),wParam);
+ end
+ else
+ begin
+ result:=Export(pWideChar(lParam),wParam);
+ end;
+end;
diff --git a/plugins/Actman30/ua/i_inoutxm.inc b/plugins/Actman30/ua/i_inoutxm.inc
new file mode 100644
index 0000000000..a052a5a0e0
--- /dev/null
+++ b/plugins/Actman30/ua/i_inoutxm.inc
@@ -0,0 +1,357 @@
+{}
+var
+ xmlparser:XML_API_W;
+
+const
+ ioAction :PWideChar = 'Action';
+ ioUA :PWideChar = 'UA';
+
+ ioName :PWideChar = 'name';
+
+ ioTwoState :PWideChar = 'twostate';
+ ioSaveState :PWideChar = 'savestate';
+
+ ioHotkey :PWideChar = 'Hotkey';
+ ioToolbar :PWideChar = 'Toolbar';
+ ioTabSRMM :PWideChar = 'TabSRMM';
+ ioMenuItem :PWideChar = 'Menu';
+
+ ioTooltip :PWideChar = 'tooltip';
+ ioTooltipPressed :PWideChar = 'tt_pressed';
+
+ ioType :PWideChar = 'type';
+ ioMenuPopup :PWideChar = 'Popup';
+ ioMenuName :PWideChar = 'Name';
+ ioMenuShow :PWideChar = 'Show';
+ ioMenuUsed :PWideChar = 'Used';
+ ioMenuSeparated :PWideChar = 'Separated';
+
+
+function ImportMenuItems(node:HXML;var MenuItem:tUAMenuItem):integer;
+begin
+ result:=0;
+
+ with xmlparser do
+ begin
+ with MenuItem do
+ begin
+ menu_opt:=0;
+ // popup
+ StrDupW(szMenuPopup,getAttrValue(node,ioMenuPopup));
+ // name
+ StrDupW(szMenuNameVars,getAttrValue(node,ioMenuName));
+ // show
+ StrDupW(szMenuShowWhenVars,getAttrValue(node,ioMenuShow));
+ // used
+ if StrToInt(getAttrValue(node,ioMenuUsed))<>0 then
+ menu_opt:=menu_opt or UAF_MENUUSE;
+ // separated
+ if StrToInt(getAttrValue(node,ioMenuSeparated))<>0 then
+ menu_opt:=menu_opt or UAF_MENUSEP;
+ end;
+ end;
+end;
+
+function ImportUAction(actnode:HXML;var UA:tMyActionItem):integer;
+var
+ num,i:integer;
+ sub:HXML;
+begin
+ result:=0;
+ if actnode=0 then exit;
+
+ with xmlparser do
+ begin
+ // we don't need that node as is, just it's child for UA
+// actnode:=GetNthChild(actnode,ioUA,0);
+
+ UA.flags:=0;
+ // ----- Common -----
+ if StrToInt(getAttrValue(actnode,ioTwoState))<>0 then
+ UA.flags:=UA.flags or UAF_2STATE;
+
+ if StrToInt(getAttrValue(actnode,ioSaveState))<>0 then
+ UA.flags:=UA.flags or UAF_SAVESTATE;
+
+ // sub:=AddChild(actnode,ioRegister,nil);
+ if StrToInt(getAttrValue(actnode,ioHotkey))<>0 then
+ UA.flags:=UA.flags or UAF_REGHOTKEY;
+ if StrToInt(getAttrValue(actnode,ioToolbar))<>0 then
+ UA.flags:=UA.flags or UAF_REGTTBB;
+ if StrToInt(getAttrValue(actnode,ioTabSRMM))<>0 then
+ UA.flags:=UA.flags or UAF_REGTABB;
+
+ // ----- Hotkey -----
+ // nothing
+
+ // ----- Modern CList toolbar -----
+ // source - ANSI text
+ sub:=GetNthChild(actnode,ioToolbar,0);
+ WideToAnsi(GetAttrValue(sub,ioTooltip ),UA.szTTBTooltip ,MirandaCP);
+ WideToAnsi(GetAttrValue(sub,ioTooltipPressed),UA.szTTBTooltipPressed,MirandaCP);
+
+ // ----- TabSRMM toolbar -----
+ sub:=GetNthChild(actnode,ioTabSRMM,0);
+ StrDupW(UA.szTabBTooltip ,getAttrValue(sub,ioTooltip));
+ StrDupW(UA.szTabBTooltipPressed,getAttrValue(sub,ioTooltipPressed));
+
+ // ----- Menus -----
+ num:=0;
+ repeat
+ sub:=getNextChild(actnode,ioMenuItem,@num);
+ if sub=0 then break;
+
+ i:=StrToInt(getAttrValue(sub,ioType));
+ ImportMenuItems(sub,
+ UA.UAMenuItem[tMenuType(i)]);
+ until false;
+ end;
+end;
+
+function Import(fname:PWideChar;aflags:dword):integer;
+var
+ i,j,act:integer;
+ root,actnode:HXML;
+ pcw,res:pWideChar;
+ f:THANDLE;
+ num,num1:integer;
+ ptr,ptr1:pChain;
+begin
+ result:=0;
+
+ if (fname=nil) or (fname^=#0) then
+ exit;
+ i:=GetFSize(fname);
+ if i=0 then
+ exit;
+
+ num:=CallService(MS_ACT_GETLIST,0,LPARAM(@ptr));
+ if num=0 then exit;
+ ptr1:=ptr;
+
+ mGetMem (res ,i+SizeOf(WideChar));
+ FillChar(res^,i+SizeOf(WideChar),0);
+ f:=Reset(fname);
+ BlockRead(f,res^,i);
+ CloseHandle(f);
+
+ xmlparser.cbSize:={XML_API_SIZEOF_V1;//}SizeOf(XML_API_W);
+ CallService(MS_SYSTEM_GET_XI,0,lparam(@xmlparser));
+ with xmlparser do
+ begin
+ root:=parseString(ChangeUnicode(res),@i,nil);
+ j:=0;
+ repeat
+ actnode:=getNthChild(root,ioAction,j);
+ if actnode=0 then break;
+ // search id by name?
+ pcw:=GetAttrValue(actnode,ioName);
+ ptr:=ptr1;
+ inc(pbyte(ptr),4);
+ for i:=0 to num-1 do
+ begin
+ if (ptr.flags and ACF_SELECTED)<>0 then
+ begin
+ if StrCmpw(pcw,ptr.descr)=0 then
+ begin
+ // delete old UA for overwrited actions
+ if (ptr.flags and ACF_OVERLOAD)<>0 then
+ begin
+ for act:=0 to HIGH(UActionList) do
+ begin
+ if ptr.id=UActionList[act].dwActID then
+ begin
+ DeleteUAction(act,true);
+ break;
+ end;
+ end;
+ end;
+ num1:=AddUAction(-1,ptr);
+ ImportUAction(getNthChild(actnode,ioUA,0),UActionList[num1]);
+ break;
+ end;
+ end;
+ inc(ptr);
+ end;
+
+ inc(j);
+ until false;
+
+ DestroyNode(root);
+ end;
+ CallService(MS_ACT_FREELIST,0,LPARAM(ptr1));
+ mFreeMem(res);
+ result:=1;
+ if settings<>0 then
+ begin
+ FillActionList(settings);
+ ShowAction(settings,-1);
+ end;
+end;
+
+//--------------------------
+
+function ExportMenuItems(node:HXML;const MenuItem:tUAMenuItem):HXML;
+begin
+ with xmlparser do
+ begin
+ result:=AddChild(node,ioMenuItem,nil);
+ with MenuItem do
+ begin
+ // popup
+ if (szMenuPopup<>nil) and (szMenuPopup^<>#0) then
+ AddAttr(result,ioMenuPopup,szMenuPopup);
+ // name
+ if (szMenuNameVars<>nil) and (szMenuNameVars^<>#0) then
+ AddAttr(result,ioMenuName,szMenuNameVars);
+ // show
+ if (szMenuShowWhenVars<>nil) and (szMenuShowWhenVars^<>#0) then
+ AddAttr(result,ioMenuShow,szMenuShowWhenVars);
+ // used
+ AddAttrInt(result,ioMenuUsed,ord((menu_opt AND UAF_MENUUSE)<>0));
+ // separated
+ AddAttrInt(result,ioMenuSeparated,ord((menu_opt AND UAF_MENUSEP)<>0));
+ end;
+ end;
+end;
+
+procedure WriteUAction(root:HXML;id:dword;name:pWideChar);
+var
+ i:integer;
+ lmenu:tMenuType;
+ pc:pWideChar;
+ actnode,sub:HXML;
+ UA:pMyActionItem;
+begin
+ with xmlparser do
+ begin
+ for i:=0 to HIGH(UActionList) do
+ begin
+ if UActionList[i].dwActID=id then
+ begin
+ UA:=@UActionList[i];
+ actnode:=getChildByAttrValue(root,ioAction,ioName,name);
+ if actnode=0 then break;
+ // we don't need that node as is, just it's child for UA
+ actnode:=addChild(actnode,ioUA,nil);
+
+ // ----- Common -----
+ AddAttrInt(actnode,ioTwoState ,ORD((UA.flags and UAF_2STATE )<>0));
+ AddAttrInt(actnode,ioSaveState,ORD((UA.flags and UAF_SAVESTATE)<>0));
+
+ // sub:=AddChild(actnode,ioRegister,nil);
+ AddAttrInt(actnode,ioHotkey ,ORD((UA.flags and UAF_REGHOTKEY)<>0));
+ AddAttrInt(actnode,ioToolbar,ORD((UA.flags and UAF_REGTTBB )<>0));
+ AddAttrInt(actnode,ioTabSRMM,ORD((UA.flags and UAF_REGTABB )<>0));
+
+ // ----- Hotkey -----
+ // nothing
+
+ // ----- Modern CList toolbar -----
+ // source - ANSI text
+ if ((UA.szTTBTooltip <>nil) and (UA.szTTBTooltip^ <>#0)) or
+ ((UA.szTTBTooltipPressed<>nil) and (UA.szTTBTooltipPressed^<>#0)) then
+ begin
+ sub:=AddChild(actnode,ioToolbar,nil);
+ if (UA.szTTBTooltip<>nil) and (UA.szTTBTooltip^<>#0) then
+ begin
+ AnsiToWide(UA.szTTBTooltip,pc,MirandaCP);
+ AddAttr(sub,ioTooltip,pc);
+ mFreeMem(pc);
+ end;
+ if (UA.szTTBTooltipPressed<>nil) and (UA.szTTBTooltipPressed^<>#0) then
+ begin
+ AnsiToWide(UA.szTTBTooltipPressed,pc,MirandaCP);
+ AddAttr(sub,ioTooltipPressed,pc);
+ mFreeMem(pc);
+ end;
+ end;
+
+ // ----- TabSRMM toolbar -----
+ if ((UA.szTabBTooltip <>nil) and (UA.szTabBTooltip^ <>#0)) or
+ ((UA.szTabBTooltipPressed<>nil) and (UA.szTabBTooltipPressed^<>#0)) then
+ begin
+ sub:=AddChild(actnode,ioTabSRMM,nil);
+ if (UA.szTabBTooltip<>nil) and (UA.szTabBTooltip^<>#0) then
+ AddAttr(sub,ioTooltip,UA.szTabBTooltip);
+ if (UA.szTabBTooltipPressed<>nil) and (UA.szTabBTooltipPressed^<>#0) then
+ AddAttr(sub,ioTooltipPressed,UA.szTabBTooltipPressed);
+ end;
+
+ // ----- Menus -----
+ for lmenu:=main_menu to HIGH(tMenuType) do
+ begin
+ sub:=ExportMenuItems(actnode,UA.UAMenuItem[lmenu]);
+ AddAttrInt(sub,ioType,ORD(lmenu));
+ end;
+
+ break;
+ end;
+ end;
+ end;
+end;
+
+function Export(fname:pWideChar;aflags:dword):integer;
+var
+ i,num:integer;
+ f:THANDLE;
+ root:HXML;
+ res:pWideChar;
+ ptr,ptr1:pChain;
+begin
+ result:=0;
+ xmlparser.cbSize:={XML_API_SIZEOF_V1;//}SizeOf(XML_API_W);
+ CallService(MS_SYSTEM_GET_XI,0,lparam(@xmlparser));
+ with xmlparser do
+ begin
+ // we need append file, not rewrite
+ i:=GetFSize(fname);
+ if i=0 then exit;
+
+ mGetMem (res ,i+SizeOf(WideChar));
+ FillChar(res^,i+SizeOf(WideChar),0);
+ f:=Reset(fname);
+ BlockRead(f,res^,i);
+ CloseHandle(f);
+ root:=parseString(res,@i,nil);
+ mFreeMem(res);
+
+ num:=CallService(MS_ACT_GETLIST,0,LPARAM(@ptr));
+ if num>0 then
+ begin
+ ptr1:=ptr;
+ inc(pbyte(ptr),4);
+ for i:=0 to num-1 do
+ begin
+ if ((aflags and ACIO_SELECTED)=0) or
+ ((ptr.flags and ACCF_EXPORT)<>0) then
+ begin
+ WriteUAction(root,ptr.id,ptr.descr);
+ end;
+ inc(ptr);
+ end;
+ CallService(MS_ACT_FREELIST,0,LPARAM(ptr1));
+ end;
+
+ res:=toString(root,@i);
+
+ f:=Rewrite(fname);
+ BlockWrite(f,res^,i*SizeOf(WideChar));
+ CloseHandle(f);
+ xmlparser.FreeMem(res);
+ DestroyNode(root);
+ end;
+ result:=1;
+end;
+
+function ActInOut(wParam:WPARAM;lParam:LPARAM):int_ptr; cdecl;
+begin
+ if (wParam and ACIO_EXPORT)=0 then
+ begin
+ result:=Import(pWideChar(lParam),wParam);
+ end
+ else
+ begin
+ result:=Export(pWideChar(lParam),wParam);
+ end;
+end;
diff --git a/plugins/Actman30/ua/i_opt_dlg.inc b/plugins/Actman30/ua/i_opt_dlg.inc
new file mode 100644
index 0000000000..b7ff28483a
--- /dev/null
+++ b/plugins/Actman30/ua/i_opt_dlg.inc
@@ -0,0 +1,572 @@
+{}
+const
+ settings:HWND = 0;
+const
+ NumControls = 17;
+
+ IDsArray:array [0..NumControls-1] of integer =(
+ // Menu settings controls
+ IDC_UA_SEPARATE ,IDC_UA_POPUPT ,IDC_UA_POPUPV,
+ IDC_UA_VARNAMEST,IDC_UA_VARNAMESV,IDC_UA_VARNAMESH,
+ IDC_UA_SHOWVART ,IDC_UA_SHOWVARV ,IDC_UA_SHOWVARH,
+ IDC_UA_TWOSTATE ,IDC_UA_SAVSTATE ,IDC_UA_COMMON,
+ // toolbar settings controls
+ IDC_UA_TTNORMALT,IDC_UA_TTNORMALV,IDC_UA_TTPRESSEDT,IDC_UA_TTPRESSEDV,
+ IDC_UA_GLOBAL
+ );
+
+ // Show-hide controls by place type
+ SHArray:array [0..NumTypes-1, 0..NumControls-1] of integer = (
+ // CList Modern toolbar
+ (SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE,SW_HIDE,SW_HIDE, SW_SHOW,SW_SHOW,SW_SHOW,
+ SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW,SW_SHOW, SW_HIDE),
+ // TabSRMM toolbar
+ (SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE,SW_HIDE,SW_HIDE,
+ SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW),
+ // Core Hotkey
+ (SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE,SW_HIDE,SW_HIDE,
+ SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE,SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE),
+ // Main menu
+ (SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW,
+ SW_SHOW,SW_SHOW,SW_SHOW, SW_HIDE,SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE),
+ // Contact menu
+ (SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW,
+ SW_SHOW,SW_SHOW,SW_SHOW, SW_HIDE,SW_HIDE,SW_HIDE,SW_HIDE, SW_SHOW),
+ // Tray menu
+ (SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW,
+ SW_SHOW,SW_SHOW,SW_SHOW, SW_HIDE,SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE),
+ // Protocol menu
+ (SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW,
+ SW_SHOW,SW_SHOW,SW_SHOW, SW_HIDE,SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE),
+ // Status menu
+ (SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW, SW_SHOW,SW_SHOW,SW_SHOW,
+ SW_SHOW,SW_SHOW,SW_SHOW, SW_HIDE,SW_HIDE,SW_HIDE,SW_HIDE, SW_HIDE)
+ );
+ // additional show/hide controls check by Variables installings (1 - need to check)
+ SHVarArray:array [0..NumControls-1] of byte = (
+ 0,0,0, 0,0,1, 1,1,1,
+ 0,0,0,0,0,0,0, 0);
+ // additional enable/disable controls check (1 - always enable)
+ EnDisArray:array [0..NumControls-1] of byte = (
+ 0,0,0, 0,0,0, 0,0,0,
+ 1,1,1,0,0,0,0, 1);
+
+var
+ hIC:THANDLE;
+
+procedure CheckPlacesAbility;
+var
+ i:integer;
+begin
+ for i:=0 to NumTypes-1 do
+ begin
+ with NamesArray[i] do
+ begin
+ enable:=(service=nil) or (ServiceExists(service)<>0);
+ end;
+ end;
+end;
+
+// Show or hide option items
+procedure SetupControls(Dialog:HWND;atype:integer;item:integer=-1);
+var
+ i: cardinal;
+ typ:integer;
+ wnd,wnd1:HWND;
+ enable:boolean;
+begin
+ if atype<0 then
+ begin
+ for i:=0 to NumControls-1 do
+ begin
+ ShowWindow(GetDlgItem(Dialog,IDsArray[i]),SW_HIDE);
+ end;
+ end
+ else
+ begin
+ wnd1:=GetDlgItem(Dialog,IDC_UA_PLACELIST);
+ if item<0 then
+ item:=SendMessage(wnd1,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+ enable:=ListView_GetCheckState(wnd1,item)<>0;
+
+ for i:=0 to NumControls-1 do
+ begin
+ typ:=SHArray[LoByte(atype)+HiByte(atype)][i];
+ if typ=SW_SHOW then
+ if (SHVarArray[i]<>0) and (not IsVarsInstalled) then
+ typ:=SW_HIDE;
+ wnd:=GetDlgItem(Dialog,IDsArray[i]);
+ ShowWindow(wnd,typ);
+ EnableWindow(wnd,enable or (EnDisArray[i]<>0));
+ end;
+
+ // common settings
+ EnableWindow(GetDlgItem(Dialog,IDC_UA_SAVSTATE),
+ IsDlgButtonChecked(Dialog,IDC_UA_TWOSTATE)<>BST_UNCHECKED);
+
+ // personal settings
+ case LoByte(atype) of
+ uaTTB, uaTAB: begin
+ enable:=false;
+ if IsDlgButtonChecked(Dialog,IDC_UA_TWOSTATE)<>BST_UNCHECKED then
+ if IsWindowEnabled(GetDlgItem(Dialog,IDC_UA_TTNORMALV)) then
+ enable:=true;
+ EnableWindow(GetDlgItem(Dialog,IDC_UA_TTPRESSEDV),enable);
+ end;
+ end;
+ end;
+end;
+
+// Clear all screen buttons/text fields (reset)
+procedure ClearControls(Dialog:HWND);
+var
+ s:HWND;
+begin
+ s:=settings;
+ settings:=0;
+ CheckDlgButton (Dialog,IDC_UA_TWOSTATE ,BST_UNCHECKED);
+ CheckDlgButton (Dialog,IDC_UA_SAVSTATE ,BST_UNCHECKED);
+
+ CheckDlgButton (Dialog,IDC_UA_SEPARATE ,BST_UNCHECKED);
+ SetDlgItemTextW(Dialog,IDC_UA_POPUPV ,nil);
+ SetDlgItemTextW(Dialog,IDC_UA_VARNAMESV,nil);
+ SetDlgItemTextW(Dialog,IDC_UA_SHOWVARV ,nil);
+ settings:=s;
+end;
+
+procedure ShowSubAction(Dialog:HWND;aType:integer;item:integer=-1);
+var
+ UA:pMyActionItem;
+ s:HWND;
+begin
+ s:=settings;
+ settings:=0;
+ ClearControls(Dialog);
+
+ // get UAction number
+ item:=LV_GetLParam(GetDlgItem(Dialog,IDC_UA_ACTIONLIST),item);
+
+ UA:=@UActionList[item];
+
+ // common settings
+ if (UA.flags and UAF_2STATE)<>0 then
+ CheckDlgButton(Dialog,IDC_UA_TWOSTATE,BST_CHECKED);
+
+ if (UA.flags and UAF_SAVESTATE)<>0 then
+ CheckDlgButton(Dialog,IDC_UA_SAVSTATE,BST_CHECKED);
+
+ if (UA.flags and UAF_GLOBAL)=0 then
+ CheckDlgButton(Dialog,IDC_UA_GLOBAL,BST_CHECKED);
+
+ // Show real UA settings
+ case LoByte(aType) of
+ uaTTB: begin // CList modern toolbar
+ SetDlgItemTextA(Dialog,IDC_UA_TTNORMALV ,UA.szTTBTooltip);
+ SetDlgItemTextA(Dialog,IDC_UA_TTPRESSEDV,UA.szTTBTooltipPressed);
+ SetDlgItemTextW(Dialog,IDC_UA_SHOWVARV ,UA.szTTBShowWhenVars);
+ end;
+
+ uaTAB: begin // TabSRMM toolbar
+ SetDlgItemTextW(Dialog,IDC_UA_TTNORMALV ,UA.szTabBTooltip);
+ SetDlgItemTextW(Dialog,IDC_UA_TTPRESSEDV,UA.szTabBTooltipPressed);
+ end;
+
+ uaMenu: begin
+ with UA.UAMenuItem[tMenuType(HiByte(aType))] do
+ begin
+ if (menu_opt and UAF_MENUSEP)<>0 then
+ CheckDlgButton(Dialog,IDC_UA_SEPARATE,BST_CHECKED);
+ SetDlgItemTextW(Dialog,IDC_UA_POPUPV ,szMenuPopup);
+ SetDlgItemTextW(Dialog,IDC_UA_VARNAMESV,szMenuNameVars);
+ SetDlgItemTextW(Dialog,IDC_UA_SHOWVARV ,szMenuShowWhenVars);
+ end;
+ end;
+
+ uaHotkey: begin // Hotkey
+ // Settings in Customize/Hotkeys
+ end;
+ end;
+ SetupControls(Dialog,aType,-1);
+ settings:=s;
+end;
+
+function isPlaceActive(idx,place:integer):boolean;
+begin
+ result:=false;
+ with UActionList[idx] do
+ case LoByte(place) of
+ uaTTB : result:=(flags and UAF_REGTTBB)<>0;
+ uaTAB : result:=(flags and UAF_REGTABB)<>0;
+ uaHotkey : result:=(flags and UAF_REGHOTKEY)<>0;
+ uaMenu: begin
+ result:=(UAMenuItem[tMenuType(HiByte(place))].menu_opt and UAF_MENUUSE)<>0
+ end;
+ end;
+end;
+
+procedure ShowAction(Dialog:HWND;item:integer=-1);
+var
+ i,j:integer;
+ wnd:HWND;
+ li:LV_ITEMW;
+ buf:array [0..255] of WideChar;
+ lset:HWND;
+begin
+ wnd:=GetDlgItem(Dialog,IDC_UA_PLACELIST);
+ SendMessage(wnd,LVM_DELETEALLITEMS,0,0);
+ j:=LV_GetLParam(GetDlgItem(Dialog,IDC_UA_ACTIONLIST),item);
+ if j>=0 then
+ begin
+ with UActionList[j] do
+ begin
+ lset:=settings;
+ settings:=0;
+ // make "places" list
+ for i:=0 to NumTypes-1 do
+ begin
+ with NamesArray[i] do
+ begin
+ if enable then // cached ability flag
+ begin
+ li.mask :=LVIF_TEXT+LVIF_PARAM;
+ li.iSubItem:=0;
+ li.iItem :=i;
+ li.lParam :=atype; //!!!!!! need to add subtype
+ li.pszText :=TranslateW(FastAnsiToWideBuf(name,buf));
+ li.iItem :=SendMessageW(wnd,LVM_INSERTITEMW,0,LPARAM(@li));
+
+ ListView_SetCheckState(wnd,li.iItem,isPlaceActive(j,atype));
+ end;
+ end;
+ end;
+ ListView_SetItemState(wnd,0,
+ LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+ // show first selected "place"
+ ShowSubAction(Dialog,LV_GetLParam(wnd));
+ settings:=lset;
+ end;
+ end
+ else
+ begin
+ ClearControls(Dialog);
+ SetupControls(Dialog,-1,-1);
+ end;
+end;
+
+procedure SetChangedFlag(Dialog:HWND);
+var
+ num,atype:integer;
+begin
+ num :=LV_GetLParam(GetDlgItem(Dialog,IDC_UA_ACTIONLIST),-1);
+ atype:=LV_GetLParam(GetDlgItem(Dialog,IDC_UA_PLACELIST ),-1);
+ UActionList[num].UAMenuItem[tMenuType(HiByte(atype))].changed:=true;
+end;
+
+procedure SaveMenuSubAction(Dialog:HWND;var MenuItem:tUAMenuItem);
+begin
+ with MenuItem do
+ begin
+ mFreeMem(szMenuPopup ); szMenuPopup :=GetDlgText(Dialog,IDC_UA_POPUPV);
+ mFreeMem(szMenuNameVars ); szMenuNameVars :=GetDlgText(Dialog,IDC_UA_VARNAMESV);
+ mFreeMem(szMenuShowWhenVars); szMenuShowWhenVars:=GetDlgText(Dialog,IDC_UA_SHOWVARV);
+ menu_opt:=0;
+ if IsDlgButtonchecked(Dialog,IDC_UA_SEPARATE)<>BST_UNCHECKED then
+ menu_opt:=menu_opt or UAF_MENUSEP;
+ end;
+end;
+
+procedure SetPlaceActive(idx,place:integer;active:boolean);
+begin
+ with UActionList[idx] do
+ case LoByte(place) of
+ uaTTB : if active then flags:=flags or UAF_REGTTBB else flags:=flags and not UAF_REGTTBB;
+ uaTAB : if active then flags:=flags or UAF_REGTABB else flags:=flags and not UAF_REGTABB;
+ uaHotkey: if active then flags:=flags or UAF_REGHOTKEY else flags:=flags and not UAF_REGHOTKEY;
+ uaMenu :
+ with UAMenuItem[tMenuType(HiByte(place))] do
+ if active then menu_opt:=menu_opt or UAF_MENUUSE
+ else menu_opt:=menu_opt and not UAF_MENUUSE;
+ end;
+end;
+
+procedure SaveAction(Dialog:HWND;item:integer=-1;atype:integer=-1);
+var
+ i,num:integer;
+ wnd:HWND;
+begin
+ num:=LV_GetLParam(GetDlgItem(Dialog,IDC_UA_ACTIONLIST),item);
+ if num<0 then exit;
+
+ wnd:=GetDlgItem(Dialog,IDC_UA_PLACELIST);
+ atype:=LV_GetLParam(wnd,atype);
+ with UActionList[num] do
+ begin
+ // main flags
+ flags:=flags and not UAF_USING;
+ // common section
+ if IsDlgButtonChecked(Dialog,IDC_UA_TWOSTATE)<>BST_UNCHECKED then
+ flags:=flags or UAF_2STATE
+ else
+ flags:=flags and not UAF_2STATE;
+
+ if IsDlgButtonChecked(Dialog,IDC_UA_SAVSTATE)<>BST_UNCHECKED then
+ flags:=flags or UAF_SAVESTATE
+ else
+ flags:=flags and not UAF_SAVESTATE;
+
+ if IsDlgButtonChecked(Dialog,IDC_UA_GLOBAL)=BST_UNCHECKED then
+ flags:=flags or UAF_GLOBAL
+ else
+ flags:=flags and not UAF_GLOBAL;
+
+ // custom data
+ case LoByte(atype) of
+ uaTTB: begin // CList modern toolbar
+ mFreeMem(szTTBTooltip ); szTTBTooltip :=GetDlgText(Dialog,IDC_UA_TTNORMALV ,true);
+ mFreeMem(szTTBTooltipPressed); szTTBTooltipPressed:=GetDlgText(Dialog,IDC_UA_TTPRESSEDV,true);
+ mFreeMem(szTTBShowWhenVars ); szTTBShowWhenVars :=GetDlgText(Dialog,IDC_UA_SHOWVARV);
+ end;
+
+ uaTAB: begin // TabSRMM toolbar
+ mFreeMem(szTabBTooltip ); szTabBTooltip :=GetDlgText(Dialog,IDC_UA_TTNORMALV);
+ mFreeMem(szTabBTooltipPressed); szTabBTooltipPressed:=GetDlgText(Dialog,IDC_UA_TTPRESSEDV);
+ end;
+
+ uaMenu: SaveMenuSubAction(Dialog,UAMenuItem[tMenuType(HiByte(atype))]);
+
+ uaHotkey: begin // Hotkey
+ // Settings in Customize/Hotkeys
+ end;
+ end;
+ for i:=0 to SendMessage(wnd,LVM_GETITEMCOUNT,0,0)-1 do
+ begin
+ SetPlaceActive(num,LV_GetLParam(wnd,i),ListView_GetCheckState(wnd,i)<>0);
+ end;
+ //just after Action (not place) changes
+ if item<0 then
+ SaveUA(num);
+ end;
+end;
+
+function CompareItem(lParam1,lParam2:LPARAM;SortType:LPARAM):int; stdcall;
+begin
+ result:=UActionList[lParam1].wSortIndex-UActionList[lParam2].wSortIndex;
+end;
+
+procedure FillActionList(wnd:HWND);
+var
+ i:integer;
+ li:LV_ITEMW;
+ il:HIMAGELIST;
+ lmenu:tMenuType;
+begin
+ wnd:=GetDlgItem(wnd,IDC_UA_ACTIONLIST);
+ SendMessage(wnd,LVM_DELETEALLITEMS,0,0);
+
+ il:=ImageList_Create(16,16,ILC_COLOR32 or ILC_MASK,0,1);
+ for i:=0 to HIGH(UActionList) do
+ begin
+ li.mask :=LVIF_TEXT+LVIF_PARAM+LVIF_IMAGE;
+ li.iSubItem:=0;
+ li.iItem :=i;
+ li.lParam :=i;
+ li.pszText :=UActionList[i].szActDescr;
+ li.iImage:=ImageList_AddIcon(il,
+ HICON(CallService(MS_SKIN2_GETICONBYHANDLE,0,LPARAM(UActionList[i].hIcolibIcon))));
+ li.iItem :=SendMessageW(wnd,LVM_INSERTITEMW,0,LPARAM(@li));
+
+ for lmenu:=main_menu to HIGH(tMenuType) do
+ UActionList[i].UAMenuItem[lmenu].changed:=false;
+ end;
+ ImageList_Destroy(SendMessage(wnd,LVM_SETIMAGELIST,LVSIL_SMALL,il));
+
+ SendMessage(wnd,LVM_SORTITEMS,0,LPARAM(@CompareItem));
+
+ ListView_SetItemState(wnd,0,
+ LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+end;
+
+// refresh icons in UA list (at least)
+function IconChanged(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+var
+ i:integer;
+ li:LV_ITEMW;
+ il:HIMAGELIST;
+ wnd:HWND;
+begin
+ result:=0;
+ wnd:=GetDlgItem(settings,IDC_UA_ACTIONLIST);
+
+ il:=ImageList_Create(16,16,ILC_COLOR32 or ILC_MASK,0,1);
+ for i:=0 to HIGH(UActionList) do
+ begin
+ li.mask :=LVIF_IMAGE;
+ li.iSubItem:=0;
+ li.iItem :=i;
+ li.iImage:=ImageList_AddIcon(il,
+ HICON(CallService(MS_SKIN2_GETICONBYHANDLE,0,TLPARAM(UActionList[i].hIcolibIcon))));
+ SendMessageW(wnd,LVM_SETITEM,0,TLPARAM(@li));
+ end;
+ ImageList_Destroy(SendMessage(wnd,LVM_SETIMAGELIST,LVSIL_SMALL,il));
+//!!refresh?
+end;
+
+function DlgProcOpt(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+var
+ wnd:HWND;
+ lv:LV_COLUMNW;
+ i:integer;
+begin
+ result:=0;
+ case hMessage of
+ WM_CLOSE: begin
+ settings:=0;
+ UnhookEvent(hIC);
+ end;
+
+ WM_INITDIALOG: begin
+ settings:=0;
+ TranslateDialogDefault(Dialog);
+
+ wnd:=GetDlgItem(Dialog,IDC_UA_PLACELIST);
+ SendMessage(wnd,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_CHECKBOXES,LVS_EX_CHECKBOXES);
+ SendMessage(wnd,LVM_SETUNICODEFORMAT,1,0);
+ zeromemory(@lv,sizeof(lv));
+ lv.mask:=LVCF_WIDTH;
+ lv.cx :=110;
+ SendMessageW(wnd,LVM_INSERTCOLUMNW ,0,tlparam(@lv));
+ SendMessageW(wnd,LVM_SETCOLUMNWIDTH,0,LVSCW_AUTOSIZE_USEHEADER);
+
+ wnd:=GetDlgItem(Dialog,IDC_UA_ACTIONLIST);
+// SendMessage(wnd,LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_CHECKBOXES,LVS_EX_CHECKBOXES);
+ SendMessage(wnd,LVM_SETUNICODEFORMAT,1,0);
+ zeromemory(@lv,sizeof(lv));
+ lv.mask:=LVCF_WIDTH;
+ lv.cx :=110;
+ SendMessageW(wnd,LVM_INSERTCOLUMNW ,0,tlparam(@lv));
+ SendMessageW(wnd,LVM_SETCOLUMNWIDTH,0,LVSCW_AUTOSIZE_USEHEADER);
+ FillActionList(Dialog);
+ ShowAction(Dialog,-1);
+
+// if isVarsInstalled then
+ begin
+ SendDlgItemMessage(Dialog,IDC_UA_VARNAMESH,BM_SETIMAGE,IMAGE_ICON,
+ CallService(MS_VARS_GETSKINITEM,0,VSI_HELPICON));
+ SendDlgItemMessage(Dialog,IDC_UA_SHOWVARH,BM_SETIMAGE,IMAGE_ICON,
+ CallService(MS_VARS_GETSKINITEM,0,VSI_HELPICON));
+// SendDlgItemMessage(Dialog,IDC_UA_VARNAMESH,BUTTONSETASFLATBTN,0,0);
+// SendDlgItemMessage(Dialog,IDC_UA_SHOWVARH ,BUTTONSETASFLATBTN,0,0);
+ end;
+
+ settings:=Dialog;
+ hIC:=HookEvent(ME_SKIN2_ICONSCHANGED,@IconChanged);
+ end;
+
+ WM_COMMAND: begin
+ case wParam shr 16 of
+ EN_CHANGE: begin
+ if settings<>0 then
+ begin
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ if loword(wParam)=IDC_UA_POPUPV then
+ SetChangedFlag(Dialog);
+ end;
+ end;
+
+ BN_CLICKED: begin
+ if settings<>0 then
+ begin
+ case loword(wParam) of
+ IDC_UA_TWOSTATE: begin
+ SetupControls(Dialog,
+ LV_GetLParam(GetDlgItem(Dialog,IDC_UA_PLACELIST)),-1);
+ {
+ EnableWindow(GetDlgItem(Dialog,IDC_UA_TTPRESSEDV),
+ IsDlgButtonChecked(Dialog,IDC_UA_TWOSTATE)<>BST_UNCHECKED);
+ }
+ if IsDlgButtonChecked(Dialog,IDC_UA_TWOSTATE)=BST_UNCHECKED then
+ DeleteIcolibIconP(
+ UActionList[LV_GetLParam(GetDlgItem(Dialog,IDC_UA_ACTIONLIST),-1)])
+ else
+ AddIcolibIconP(
+ UActionList[LV_GetLParam(GetDlgItem(Dialog,IDC_UA_ACTIONLIST),-1)]);
+
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end;
+
+ IDC_UA_VARNAMESH: ShowVarHelp(Dialog,IDC_UA_VARNAMESV);
+ IDC_UA_SHOWVARH : ShowVarHelp(Dialog,IDC_UA_SHOWVARV);
+
+//was commented. why?
+ IDC_UA_SAVSTATE,
+ IDC_UA_GLOBAL: SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+
+ IDC_UA_SEPARATE: begin
+ SetChangedFlag(Dialog);
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end;
+ end;
+ end;
+ end;
+ end;
+ end;
+
+ WM_NOTIFY: begin
+ case integer(PNMHdr(lParam)^.code) of
+ PSN_APPLY: begin
+ SaveAction(Dialog);
+ SaveUAs;
+ FillChar(arMenuRec[0],Length(arMenuRec)*SizeOf(tuaMenuRecA),0);
+ for i:=0 to HIGH(UActionList) do
+ begin
+ SetAllActionUsers(UActionList[i],false);
+ end;
+ end;
+
+ LVN_ITEMCHANGED: begin
+ if settings=0 then exit;
+ if PNMLISTVIEW(lParam)^.uChanged=LVIF_STATE then
+ begin
+ i:=(PNMLISTVIEW(lParam)^.uOldState and LVNI_FOCUSED)-
+ (PNMLISTVIEW(lParam)^.uNewState and LVNI_FOCUSED);
+
+ if i>0 then // old focus
+ begin
+ if wParam=IDC_UA_ACTIONLIST then
+ SaveAction(Dialog,PNMLISTVIEW(lParam)^.iItem)
+ else //if wParam=IDC_UA_PLACELIST then
+ SaveAction(Dialog,-1,PNMLISTVIEW(lParam)^.iItem);
+ end
+ else if i<0 then // new focus
+ begin
+ if wParam=IDC_UA_ACTIONLIST then
+ ShowAction(Dialog,PNMLISTVIEW(lParam)^.iItem)
+ else//if wParam=IDC_UA_PLACELIST then
+ ShowSubAction(Dialog,
+ LV_GetLParam(GetDlgItem(Dialog,IDC_UA_PLACELIST),
+ PNMLISTVIEW(lParam)^.iItem));
+ end
+ else if (settings<>0) and
+ ((PNMLISTVIEW(lParam)^.uOldState or PNMLISTVIEW(lParam)^.uNewState)=$3000) then
+ begin
+ // which type
+ wnd:=GetDlgItem(Dialog,IDC_UA_PLACELIST);
+ if PNMLISTVIEW(lParam)^.iItem<>
+ SendMessage(wnd,LVM_GETNEXTITEM,-1,LVNI_FOCUSED) then
+ ListView_SetItemState(wnd,PNMLISTVIEW(lParam)^.iItem,
+ LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED)
+ else
+ SetupControls(Dialog,LV_GetLParam(wnd,PNMLISTVIEW(lParam)^.iItem),
+ PNMLISTVIEW(lParam)^.iItem);
+
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ end;
+ end;
+ end;
+ end;
+ end;
+ end;
+end;
diff --git a/plugins/Actman30/ua/i_options.inc b/plugins/Actman30/ua/i_options.inc
new file mode 100644
index 0000000000..977ff7891b
--- /dev/null
+++ b/plugins/Actman30/ua/i_options.inc
@@ -0,0 +1,252 @@
+{}
+const
+ opt_TTBTooltip :pAnsiChar = 'MTBTooltip';
+ opt_TTBTooltipPressed :pAnsiChar = 'MTBTooltipPressed';
+ opt_TTBShowWhenVars :pAnsiChar = 'MTBVarStr';
+
+ opt_TabBTooltip :pAnsiChar = 'TabBTooltip';
+ opt_TabBTooltipPressed:pAnsiChar = 'TabBTooltipPressed';
+
+ opt_MenuPopup :pAnsiChar = 'MenuPopup';
+ opt_MenuNameVars :pAnsiChar = 'MenuName';
+ opt_MenuShowWhenVars:pAnsiChar = 'MenuVarStr';
+ opt_MenuOptions :pAnsiChar = 'MenuOptions';
+
+{}
+procedure DeleteUASettings(idx:integer);
+var
+ setting:array [0..63] of AnsiChar;
+ p,pm:pAnsiChar;
+ lmenu:tMenuType;
+begin
+ with UActionList[idx] do
+ begin
+ p:=GetUABranch(setting,dwActID);
+ if p<>nil then
+ begin
+ p:=StrCopyE(p,opt_UA);
+ p^:='/'; inc(p);
+{!!
+ p^:='*'; inc(p); p^:=#0;
+ DBDeleteGroup(0,DBBranch,setting);
+!!}
+ StrCopy(p,opt_Flags); DBDeleteSetting(0,DBBranch,setting);
+
+ StrCopy(p,opt_TTBTooltip ); DBDeleteSetting(0,DBBranch,setting);
+ StrCopy(p,opt_TTBTooltipPressed ); DBDeleteSetting(0,DBBranch,setting);
+ StrCopy(p,opt_TTBShowWhenVars ); DBDeleteSetting(0,DBBranch,setting);
+
+ StrCopy(p,opt_TabBTooltip ); DBDeleteSetting(0,DBBranch,setting);
+ StrCopy(p,opt_TabBTooltipPressed); DBDeleteSetting(0,DBBranch,setting);
+
+ for lmenu:=main_menu to HIGH(tMenuType) do
+ begin
+ pm:=p;
+ pm^:=AnsiChar(ORD(lmenu)+ORD('0')); inc(pm);
+ pm^:='_'; inc(pm);
+ StrCopy(pm,opt_MenuPopup ); DBDeleteSetting(0,DBBranch,setting);
+ StrCopy(pm,opt_MenuNameVars ); DBDeleteSetting(0,DBBranch,setting);
+ StrCopy(pm,opt_MenuShowWhenVars); DBDeleteSetting(0,DBBranch,setting);
+ StrCopy(pm,opt_MenuOptions ); DBDeleteSetting(0,DBBranch,setting);
+ end;
+ end;
+ end;
+end;
+
+procedure addSaveUA(setting:pAnsiChar;txt:pWideChar); overload;
+begin
+ if (txt=nil) or (txt^=#0) then DBDeleteSetting(0,DBBranch,setting)
+ else DBWriteUnicode(0,DBBranch,setting,txt);
+end;
+
+procedure addSaveUA(setting:pAnsiChar;txt:pAnsiChar); overload;
+begin
+ if (txt=nil) or (txt^=#0) then DBDeleteSetting(0,DBBranch,setting)
+ else DBWriteString(0,DBBranch,setting,txt);
+end;
+
+procedure SaveUA(idx:integer);
+var
+ setting:array [0..63] of AnsiChar;
+ p,pm:pAnsiChar;
+ lmenu:tMenuType;
+begin
+ with UActionList[idx] do
+ begin
+ p:=GetUABranch(setting,dwActID);
+ if p<>nil then
+ begin
+ p:=StrCopyE(p,opt_UA);
+ p^:='/'; inc(p);
+
+ StrCopy(p,opt_Flags); DBWriteDWord(0,DBBranch,setting,
+ flags and not (UAF_REALTIME OR UAF_SPECIAL));
+
+ StrCopy(p,opt_TTBTooltip ); addSaveUA(setting,szTTBTooltip);
+ StrCopy(p,opt_TTBTooltipPressed); addSaveUA(setting,szTTBTooltipPressed);
+ StrCopy(p,opt_TTBShowWhenVars ); addSaveUA(setting,szTTBShowWhenVars);
+
+ StrCopy(p,opt_TabBTooltip ); addSaveUA(setting,szTabBTooltip);
+ StrCopy(p,opt_TabBTooltipPressed); addSaveUA(setting,szTabBTooltipPressed);
+
+ for lmenu:=main_menu to HIGH(tMenuType) do
+ begin
+ pm:=p;
+ pm^:=AnsiChar(ORD(lmenu)+ORD('0')); inc(pm);
+ pm^:='_'; inc(pm);
+ with UAMenuItem[lmenu] do
+ begin
+ StrCopy(pm,opt_MenuPopup ); addSaveUA(setting,szMenuPopup);
+ StrCopy(pm,opt_MenuNameVars ); addSaveUA(setting,szMenuNameVars);
+ StrCopy(pm,opt_MenuShowWhenVars); addSaveUA(setting,szMenuShowWhenVars);
+ StrCopy(pm,opt_MenuOptions ); DBWriteWord(0,DBBranch,setting,menu_opt);
+ end;
+ end;
+ end;
+ end;
+end;
+
+procedure SaveUAs;
+var
+ i:integer;
+begin
+ for i:=0 to HIGH(UActionList) do
+ SaveUA(i);
+end;
+
+function LoadUA(idx:integer):integer;
+var
+ setting:array [0..63] of AnsiChar;
+ p,pm:pAnsiChar;
+ lmenu:tMenuType;
+begin
+ result:=0;
+ with UActionList[idx] do
+ begin
+ p:=GetUABranch(setting,dwActID);
+ if p<>nil then
+ begin
+ p:=StrCopyE(p,opt_UA);
+ p^:='/'; inc(p);
+
+ StrCopy(p,opt_Flags);
+ flags:=DBReadDWord(0,DBBranch,setting,dword(UAF_SPECIAL));
+ if flags=dword(UAF_SPECIAL) then // no settings
+ begin
+ flags:=0;
+ exit;
+ end;
+ // no need to use previous "pressed" state
+ if (flags and UAF_SAVESTATE)=0 then
+ flags:=flags and not UAF_PRESSED;
+
+ flags:=flags and not UAF_REALTIME;
+ result:=1;
+
+ StrCopy(p,opt_TTBTooltip ); szTTBTooltip :=DBReadString (0,DBBranch,setting);
+ StrCopy(p,opt_TTBTooltipPressed); szTTBTooltipPressed:=DBReadString (0,DBBranch,setting);
+ StrCopy(p,opt_TTBShowWhenVars ); szTTBShowWhenVars :=DBReadUnicode(0,DBBranch,setting);
+
+ StrCopy(p,opt_TabBTooltip ); szTabBTooltip :=DBReadUnicode(0,DBBranch,setting);
+ StrCopy(p,opt_TabBTooltipPressed); szTabBTooltipPressed:=DBReadUnicode(0,DBBranch,setting);
+
+ for lmenu:=main_menu to HIGH(tMenuType) do
+ begin
+ pm:=p;
+ pm^:=AnsiChar(ORD(lmenu)+ORD('0')); inc(pm);
+ pm^:='_'; inc(pm);
+ with UAMenuItem[lmenu] do
+ begin
+ StrCopy(pm,opt_MenuPopup ); szMenuPopup :=DBReadUnicode(0,DBBranch,setting);
+ StrCopy(pm,opt_MenuNameVars ); szMenuNameVars :=DBReadUnicode(0,DBBranch,setting);
+ StrCopy(pm,opt_MenuShowWhenVars); szMenuShowWhenVars:=DBReadUnicode(0,DBBranch,setting);
+ StrCopy(pm,opt_MenuOptions ); menu_opt :=DBReadWord (0,DBBranch,setting);
+ end;
+ end;
+ end;
+ end;
+end;
+(*
+function LoadUAs:integer;
+{
+var
+ section:array [0..63] of AnsiChar;
+ p:PAnsiChar;
+ i:integer;
+}
+begin
+ result:=0;
+{
+ MaxTasks:=DBReadByte(0,opt_tasks,opt_count);
+ result:=MaxTasks;
+ if MaxTasks>0 then
+ begin
+ GetMem (TaskList ,MaxTasks*SizeOf(tTaskRec));
+ FillChar(TaskList^,MaxTasks*SizeOf(tTaskRec),0);
+ for i:=0 to MaxTasks-1 do
+ begin
+ p:=StrEnd(IntToStr(section,i));
+ with TaskList[i] do
+ begin
+ StrCopy(p,opt_flags ); flags :=DBReadDWord (0,opt_tasks,section);
+ StrCopy(p,opt_name ); name :=DBReadUnicode(0,opt_tasks,section);
+ StrCopy(p,opt_action); action :=DBReadDWord (0,opt_tasks,section);
+ end;
+ end;
+ end;
+}
+end;
+*)
+procedure SetAllActionUsers(var ActionItem:tMyActionItem; initial:boolean);
+var
+ luse:boolean;
+ lmenu:tMenuType;
+begin
+ if NamesArray[uaHotkey].enable then
+ begin
+ if (ActionItem.flags and UAF_REGHOTKEY)<>0 then
+ AddCoreHotkey(ActionItem)
+ else
+ DeleteCoreHotkey(ActionItem);
+ end;
+ if not initial then
+ begin
+ if NamesArray[uaTTB].enable then
+ begin
+ DeleteTTBButton(ActionItem); // no modify command there, just delete, then insert back
+ if (ActionItem.flags and UAF_REGTTBB)<>0 then
+ AddTTBButton(ActionItem);
+ end;
+
+ if NamesArray[uaTAB].enable then
+ begin
+ if (ActionItem.flags and UAF_REGTABB)<>0 then
+ AddTabBBButton(ActionItem)
+ else
+ DeleteTabBBButton(ActionItem);
+ end;
+ end;
+
+ luse:=false;
+ for lmenu:=main_menu to HIGH(tMenuType) do
+ begin
+ if NamesArray[uaMenu+ORD(lmenu)].enable then
+ begin
+ if (ActionItem.UAMenuItem[lmenu].menu_opt and UAF_MENUUSE)<>0 then
+ begin
+ luse:=true;
+ if ActionItem.UAMenuItem[lmenu].changed then
+ DeleteMenuItem(ActionItem,lmenu);
+ CreateMenuItem(ActionItem,lmenu);
+ end
+ else
+ DeleteMenuItem(ActionItem,lmenu);
+ end;
+ end;
+
+ if (not luse) and (ActionItem.hMenuService<>0) then
+ begin
+ DestroyServiceFunction(ActionItem.hMenuService);
+ ActionItem.hMenuService:=0;
+ end;
+end;
diff --git a/plugins/Actman30/ua/i_ua.inc b/plugins/Actman30/ua/i_ua.inc
new file mode 100644
index 0000000000..18cd78a9c7
--- /dev/null
+++ b/plugins/Actman30/ua/i_ua.inc
@@ -0,0 +1,219 @@
+{}
+function AddUAction(idx:integer; ptr:pChain):integer;
+var
+ buf:array [0..127] of AnsiChar;
+begin
+ if idx<0 then idx:=Length(UActionList);
+ if idx=Length(UActionList) then
+ SetLength(UActionList,Length(UActionList)+1);
+
+ FillChar(UActionList[idx],SizeOf(tMyActionItem),0);
+
+ with UActionList[idx] do
+ begin
+ // get Action settings
+ dwActID:=ptr^.id;
+ StrDupW(szActDescr,ptr^.descr);
+ wSortIndex:=idx;
+
+ // prepare for work
+ IntToStr(StrCopyE(buf,'Actions/Action_'),ptr^.id);
+ StrDup(szNameID,@buf);
+ AddIcolibIcon (UActionList[idx]);
+ end;
+
+ SetLength(arMenuRec,Length(UActionList)+1);
+ FillChar (arMenuRec[HIGH(arMenuRec)],SizeOf(tuaMenuRecA),0);
+ result:=idx;
+end;
+
+function CreateUActionList:integer;
+var
+ ptr,ptr1:pChain;
+ i:integer;
+begin
+ result:=CallService(MS_ACT_GETLIST,0,LPARAM(@ptr));
+ SetLength(UActionList,result);
+
+ SetLength(arMenuRec, result+1);
+ FillChar (arMenuRec[0],(result+1)*SizeOf(tuaMenuRecA),0);
+
+ if result>0 then
+ begin
+ ptr1:=ptr;
+ inc(pbyte(ptr),4);
+ for i:=0 to result-1 do
+ begin
+ AddUAction(i,ptr);
+ LoadUA(i); // just here coz at list changes for new we don't have settings
+ if (UActionList[i].flags and UAF_2STATE)<>0 then
+ AddIcolibIconP(UActionList[i]);
+ SetAllActionUsers(UActionList[i],true);
+ inc(ptr);
+ end;
+ CallService(MS_ACT_FREELIST,0,LPARAM(ptr1));
+ end;
+end;
+
+// "compact" means need to compact list/delete settings (Delete, not just exit)
+procedure DeleteUAction(num:integer;compact:boolean);
+var
+ ActionItem:pMyActionItem;
+ luse:boolean;
+ lmenu:tMenuType;
+begin
+ if compact then
+ DeleteUASettings(num);
+
+ ActionItem:=@UActionList[num];
+
+ DeleteIcolibIcon(ActionItem^);
+
+ if (ActionItem.flags and UAF_REGHOTKEY)<>0 then
+ DeleteCoreHotkey(ActionItem^);
+
+ if (ActionItem.flags and UAF_REGTTBB)<>0 then
+ DeleteTTBButton(ActionItem^);
+ mFreeMem(ActionItem.szTTBTooltip);
+ mFreeMem(ActionItem.szTTBTooltipPressed);
+ mFreeMem(ActionItem.szTTBShowWhenVars);
+
+ if (ActionItem.flags and UAF_REGTABB)<>0 then
+ DeleteTabBBButton(ActionItem^);
+ mFreeMem(ActionItem.szTabBTooltip);
+ mFreeMem(ActionItem.szTabBTooltipPressed);
+
+ luse:=false;
+ for lmenu:=main_menu to HIGH(tMenuType) do
+ begin
+ with ActionItem.UAMenuItem[lmenu] do
+ begin
+ if (menu_opt and UAF_MENUUSE)<>0 then
+ begin
+ luse:=true;
+ DeleteMenuItem(ActionItem^,lmenu);
+ end;
+ mFreeMem(szMenuPopup);
+ mFreeMem(szMenuNameVars);
+ mFreeMem(szMenuShowWhenVars);
+ end;
+ end;
+
+ if (not luse) and (ActionItem.hMenuService<>0) then
+ begin
+ DestroyServiceFunction(ActionItem.hMenuService);
+ ActionItem.hMenuService:=0;
+ end;
+
+ // Free Memory
+ mFreeMem(ActionItem.szNameID);
+ mFreeMem(ActionItem.szActDescr);
+
+ if compact then
+ begin
+ // compact list
+ if num<HIGH(UActionList) then
+ begin
+ move(UActionList[num+1],UActionList[num],(HIGH(UACtionList)-num)*SizeOf(tMyActionItem));
+ end;
+ SetLength(UActionList,Length(UActionList)-1);
+ end;
+end;
+
+function ActListChange(wParam:WPARAM;lParam:LPARAM):integer; cdecl;
+var
+ ptr,ptr1:pChain;
+ idx,i,j,count:integer;
+ bFound:boolean;
+begin
+ result:=0;
+
+ count:=CallService(MS_ACT_GETLIST,0,TLPARAM(@ptr));
+
+ if count>0 then
+ begin
+ ptr1:=ptr;
+ inc(pbyte(ptr),4);
+ if wParam<>0 then
+// if (wParam and (ACTM_NEW or ACTM_RENAME or ACTM_SORT or ACTM_DELETE))<>0 then
+ for i:=0 to count-1 do
+ begin
+ // search corresponding element
+ idx:=-1;
+ for j:=0 to HIGH(UActionList) do
+ begin
+ if UActionList[j].dwActID=ptr^.id then
+ begin
+ idx:=j;
+ break;
+ end;
+ end;
+ // if we have no item in list for this action - then add new one
+ if idx<0 then
+ begin
+ idx:=AddUAction(-1,ptr);
+ end
+ else
+ begin
+ if (wParam and ACTM_RENAME)<>0 then
+ begin
+ // check for time economy - no need to change ALL items
+ if StrCmpW(UActionList[idx].szActDescr,ptr^.descr)<>0 then
+ begin
+ mFreeMem(UActionList[idx].szActDescr);
+ StrDupW (UActionList[idx].szActDescr,ptr^.descr);
+ end;
+ end;
+ end;
+// not so necessary to check really
+// if (wParam and (ACTM_SORT or ACTM_DELETE or ACTM_NEW))<>0 then
+ UActionList[idx].wSortIndex:=i;
+
+ inc(ptr);
+ end;
+ end
+ else
+ ptr1:=nil;
+
+ // now search deleted items
+ if (wParam and ACTM_DELETE)<>0 then
+ begin
+ for j:=HIGH(UActionList) downto 0 do
+ begin
+ bFound:=false;
+ if count>0 then
+ begin
+ ptr:=ptr1;
+ inc(pbyte(ptr),4);
+ for i:=0 to count-1 do
+ begin
+ if UActionList[j].dwActID=ptr^.id then
+ begin
+ bFound:=true;
+ break;
+ end;
+ inc(ptr);
+ end;
+ end;
+ if not bFound then
+ DeleteUAction(j,true);
+ end;
+ end;
+
+ if count>0 then
+ CallService(MS_ACT_FREELIST,0,TLPARAM(ptr1));
+
+ // show changes in dialog
+ if settings<>0 then
+ begin
+ FillActionList(settings);
+ ShowAction(settings,-1);
+ end;
+
+ SaveUAs;
+ FillChar(arMenuRec[0],Length(arMenuRec)*SizeOf(tuaMenuRecA),0);
+ for i:=0 to HIGH(UActionList) do
+ begin
+ SetAllActionUsers(UActionList[i],false);
+ end;
+end;
diff --git a/plugins/Actman30/ua/i_uaplaces.inc b/plugins/Actman30/ua/i_uaplaces.inc
new file mode 100644
index 0000000000..0b8ee9468d
--- /dev/null
+++ b/plugins/Actman30/ua/i_uaplaces.inc
@@ -0,0 +1,832 @@
+{}
+(*
+const
+ MenuServices:array [tMenuType] of pAnsiChar = (
+ 'CList/AddMainMenuItem' {MS_CLIST_ADDMAINMENUITEM },
+ 'CList/AddContactMenuItem'{MS_CLIST_ADDCONTACTMENUITEM},
+ 'CList/AddTrayMenuItem' {MS_CLIST_ADDTRAYMENUITEM },
+ 'CList/AddProtoMenuItem' {MS_CLIST_ADDPROTOMENUITEM },
+ 'CList/AddStatusMenuItem' {MS_CLIST_ADDSTATUSMENUITEM }
+ );
+*)
+type
+ tuaMenuRec = record
+ hMenuRoot:HMENU;
+ position :integer;
+ end;
+ tuaMenuRecA = array [tMenuType] of tuaMenuRec;
+
+var
+ arMenuRec: array of tuaMenuRecA;
+
+//===== Support =====
+
+function ServiceCallWithLParam(wParam:WPARAM; lParam:LPARAM):int_ptr; cdecl;
+begin
+ result:=CallService(MS_ACT_RUNBYID, lParam, wParam);
+end;
+
+procedure SetTTBState(const ActionItem:tMyActionItem);
+var
+ lflag:integer;
+begin
+ if ActionItem.hTTBButton=0 then exit;
+ if (ActionItem.flags and UAF_2STATE)=0 then exit;
+
+ lflag:=CallService(MS_TTB_GETBUTTONSTATE,ActionItem.hTTBButton,0);
+ if lflag=TTBST_PUSHED then
+ begin
+ if (ActionItem.flags and (UAF_2STATE+UAF_PRESSED))<>(UAF_2STATE+UAF_PRESSED) then exit;
+ lflag:=TTBST_RELEASED;
+ end
+ else
+ begin
+ if (ActionItem.flags and (UAF_2STATE+UAF_PRESSED))=(UAF_2STATE+UAF_PRESSED) then exit;
+ if (ActionItem.flags and UAF_PRESSED)=0 then exit;
+ lflag:=TTBST_PUSHED;
+ end;
+ CallService(MS_TTB_SETBUTTONSTATE,ActionItem.hTTBButton,lflag);
+end;
+
+procedure SetTABState(hContact:THANDLE;const ActionItem:tMyActionItem;pressed:integer);
+var
+ tabb:BBButton;
+ pc:pWideChar;
+begin
+ FillChar(tabb,SizeOf(tabb),0);
+ tabb.cbSize :=SizeOf(tabb);
+ tabb.dwButtonID :=ActionItem.dwActID;
+ tabb.pszModuleName:=MODULE_NAME;
+
+ if pressed<>0 then
+ begin
+ pc:=ActionItem.szTabBTooltipPressed;
+ if pc=nil then pc:=ActionItem.szTabBTooltip;
+ tabb.hIcon:=ActionItem.hIcolibIconPressed;
+ tabb.bbbFlags:=BBSF_PUSHED;
+ end
+ else
+ begin
+ pc:=ActionItem.szTabBTooltip;
+ tabb.hIcon:=ActionItem.hIcolibIcon;
+ tabb.bbbFlags:=BBSF_RELEASED;
+ end;
+ if pc=nil then pc:=ActionItem.szActDescr;
+ tabb.szTooltip.w:=pc;
+ CallService(MS_BB_SETBUTTONSTATE,hContact,TLPARAM(@tabb));
+end;
+
+function IsLocalItem(const UAItem:tMyActionItem):boolean;
+begin
+ result:=((UAItem.flags and UAF_GLOBAL)=0) and
+ (UAItem.UAMenuItem[main_menu ].hMenuItem=0) and
+ (UAItem.UAMenuItem[tray_menu ].hMenuItem=0) and
+ (UAItem.UAMenuItem[proto_menu ].hMenuItem=0) and
+ (UAItem.UAMenuItem[status_menu].hMenuItem=0) and
+ (UAItem.hTTBButton=0);
+end;
+
+function ServiceCallWithFParam(wParam:WPARAM; lParam:LPARAM; fParam:LPARAM):int_ptr; cdecl;
+var
+ i:integer;
+ setting:array [0..63] of AnsiChar;
+ p:pAnsiChar;
+ cnt:THANDLE;
+ state:integer;
+begin
+ for i:=0 to HIGH(UActionList) do
+ begin
+ with UActionList[i] do
+ if dwActID=cardinal(fParam) then
+ if (flags and UAF_2STATE)<>0 then
+ begin
+ // sync buttons/menus
+ if IsLocalItem(UActionList[i]) then
+ begin
+ // if (flags and UAF_SAVESTATE)<>0 then
+ begin
+ state:=DBReadByte(lastContact,opt_ua,szNameID);
+ state:=state xor 1;
+ DBWriteByte(lastContact,opt_ua,szNameID,state);
+ cnt:=lastContact;
+ end;
+ end
+ else
+ begin
+ flags:=flags xor UAF_PRESSED;
+ // save "pressed" state
+ if (flags and UAF_SAVESTATE)<>0 then
+ begin
+ p:=GetUABranch(setting,dwActID);
+ if p<>nil then
+ begin
+ p:=StrCopyE(p,opt_ua);
+ p^:='/'; inc(p);
+ StrCopy(p,opt_flags);
+ DBWriteDWord(0,DBBranch,setting,flags and not UAF_REALTIME);
+ end;
+ end;
+
+ if hTTBButton<>0 then
+ SetTTBState(UActionList[i]);
+
+ cnt:=0;
+ state:=ORD(flags and UAF_PRESSED);
+ end;
+ if (flags and UAF_REGTABB)<>0 then
+ SetTABState(cnt,UActionList[i],state);
+
+ break;
+ end;
+ end;
+
+ result:=CallService(MS_ACT_RUNBYID, fParam, wParam);
+end;
+
+function AddIcolibIconP(var ActionItem:tMyActionItem):THANDLE;
+var
+ sid:TSKINICONDESC;
+ buf,buf1:array [0..63] of WideChar;
+begin
+ if (ActionItem.hIcolibIconPressed=0) or
+ (ActionItem.hIcolibIconPressed=ActionItem.hIcolibIcon) then
+ begin
+ // add icon for action to icolib
+ fillChar(sid,SizeOf(sid),0);
+ sid.cbSize :=sizeof(sid);
+ sid.szSection .w:=ICOLIB_ACTSECTION;
+ sid.szDefaultFile.w:=szMyPath;
+ sid.iDefaultIndex :=-IDI_ACTION;
+ sid.cx :=16;
+ sid.cy :=16;
+ sid.flags :=SIDF_ALL_UNICODE;
+ // icon "off"
+ StrCopyW(StrCopyEW(buf,ActionItem.szActDescr),' (pressed)');
+ sid.szDescription.w:=@buf;
+ StrCopy(StrCopyE(@buf1,ActionItem.szNameID),'_pressed');
+ sid.pszName :=@buf1;
+ ActionItem.hIcolibIconPressed:=Skin_AddIcon(@sid);
+ end;
+ result:=ActionItem.hIcolibIconPressed;
+end;
+
+function AddIcolibIcon(var ActionItem:tMyActionItem):THANDLE;
+var
+ sid:TSKINICONDESC;
+begin
+ if ActionItem.hIcolibIcon=0 then
+ begin
+ // add icon for action to icolib
+ fillChar(sid,SizeOf(sid),0);
+ sid.cbSize :=sizeof(sid);
+ sid.szSection .w:=ICOLIB_ACTSECTION;
+ sid.szDefaultFile.w:=szMyPath;
+ sid.iDefaultIndex :=-IDI_ACTION;
+ sid.cx :=16;
+ sid.cy :=16;
+ sid.flags :=SIDF_ALL_UNICODE;
+ // icon "on"
+ sid.szDescription.w:=ActionItem.szActDescr;
+ sid.pszName :=ActionItem.szNameID;
+ ActionItem.hIcolibIcon:=Skin_AddIcon(@sid);
+ end;
+ result:=ActionItem.hIcolibIcon;
+end;
+
+procedure DeleteIcolibIconP(var ActionItem:tMyActionItem);
+var
+ buf1:array [0..63] of WideChar;
+begin
+ if (ActionItem.hIcolibIconPressed<>0) and
+ (ActionItem.hIcolibIconPressed<>ActionItem.hIcolibIcon) then
+ begin
+ StrCopy(StrCopyE(@buf1,ActionItem.szNameID),'_pressed');
+ CallService(MS_SKIN2_REMOVEICON,0,LPARAM(@buf1));
+ ActionItem.hIcolibIconPressed:=ActionItem.hIcolibIcon;
+ end;
+end;
+
+procedure DeleteIcolibIcon(var ActionItem:tMyActionItem);
+begin
+ DeleteIcolibIconP(ActionItem);
+ CallService(MS_SKIN2_REMOVEICON,0,LPARAM(ActionItem.szNameID));
+ ActionItem.hIcolibIcon :=0;
+ ActionItem.hIcolibIconPressed:=0;
+end;
+
+//===== Really places =====
+
+//----- Hotkeys -----
+
+function AddCoreHotkey(var ActionItem:tMyActionItem):boolean;
+var
+ hkd:THOTKEYDESC;
+begin
+ if (ActionItem.flags and UAF_HKREGGED)=0 then
+ begin
+ FillChar(hkd,SizeOf(hkd),0);
+ hkd.cbSize := SizeOf(hkd); // HOTKEYDESC_SIZE_V1 for pre-0.9
+ hkd.dwFlags := HKD_UNICODE; // since 0.9 only
+ hkd.pszName := ActionItem.szNameID;
+ hkd.pszDescription.w:= ActionItem.szActDescr;
+ hkd.pszSection .w:= MODULE_NAME;
+ hkd.pszService := SERVICE_WITH_LPARAM_NAME;
+ hkd.lParam := ActionItem.dwActID;
+ result:=Hotkey_Register(@hkd)<>0;
+ if result then
+ ActionItem.flags:=ActionItem.flags or UAF_HKREGGED;
+ end
+ else
+ result:=true; //!!
+end;
+
+procedure DeleteCoreHotkey(var ActionItem:tMyActionItem);
+begin
+ if // bCoreHotkeyPresents and
+ // (ServiceExists(MS_HOTKEY_UNREGISTER)<>0) and
+ ((ActionItem.flags and UAF_HKREGGED)<>0) then
+ begin
+ CallService(MS_HOTKEY_UNREGISTER,0,LParam(ActionItem.szNameID));
+ ActionItem.flags:=ActionItem.flags and not UAF_HKREGGED;
+ end;
+end;
+
+//----- Common menu functions -----
+
+function AddRootMenuIcon(szPopupName:pWideChar):THANDLE;
+var
+ sid:TSKINICONDESC;
+begin
+ FillChar(sid,SizeOf(sid),0);
+ //first - register icon for root popup
+ sid.cbSize := sizeof(sid);
+ sid.szSection.w := ICOLIB_MNUSECTION;
+ sid.flags := SIDF_ALL_UNICODE;
+ sid.cx := 16;
+ sid.cy := 16;
+ sid.szDescription.w:= szPopupName;
+ sid.szDefaultFile.w:= szMyPath;
+ sid.iDefaultIndex := -IDI_ACTION;
+ WideToAnsi(szPopupName,sid.pszName);
+ result:=Skin_AddIcon(@sid);
+ mFreeMem(sid.pszName);
+end;
+
+procedure DeleteMenuItem(var ActionItem:tMyActionItem;mtype:tMenuType);
+var
+ i:integer;
+ hMenuRoot:THANDLE;
+ p:pMyActionItem;
+begin
+ with ActionItem.UAMenuItem[mtype] do
+ begin
+ if hMenuItem=0 then exit;
+ CallService(MO_REMOVEMENUITEM,hMenuItem,0);
+ hMenuItem:=0;
+ end;
+
+ hMenuRoot:=ActionItem.UAMenuItem[mtype].hMenuRoot;
+ if hMenuRoot<>0 then
+ begin
+ for i:=0 to HIGH(UActionList) do
+ begin
+ p:=@UActionList[i];
+ // presents somethere else
+ if (p<>@ActionItem) and (p.UAMenuItem[mtype].hMenuRoot=hMenuRoot) then
+ exit;
+ end;
+ // menu array cleanup now?
+ for i:=0 to HIGH(arMenuRec) do
+ begin
+ if arMenuRec[i][mtype].hMenuRoot=hMenuRoot then
+ begin
+ FillChar(arMenuRec[i][mtype],SizeOf(tuaMenuRec),0);
+// arMenuRec[i][mtype].hMenuRoot:=0;
+ break;
+ end;
+ end;
+ CallService(MO_REMOVEMENUITEM,hMenuRoot,0);
+ ActionItem.UAMenuItem[mtype].hMenuRoot:=0;
+ end;
+end;
+
+function GetMenuPosition(hMenu:HMENU;mtype:tMenuType;toset:boolean):integer;
+var
+ i:integer;
+begin
+ result:=0;
+ for i:=0 to HIGH(arMenuRec) do
+ begin
+ if arMenuRec[i][mtype].hMenuRoot=hMenu then
+ begin
+ if toset then
+ inc(arMenuRec[i][mtype].position,100000);
+ result:=arMenuRec[i][mtype].position;
+ break;
+ end;
+ end;
+end;
+
+function MakeMenuItem(mtype:tMenuType;clmi:PCListMenuItem):THANDLE;
+begin
+ case mtype of
+ main_menu : result:=Menu_AddMainMenuItem(clmi);
+ contact_menu: result:=Menu_AddContactMenuItem(clmi);
+ tray_menu : result:=Menu_AddTrayMenuItem(clmi);
+ proto_menu : result:=Menu_AddProtoMenuItem(clmi);
+ status_menu : result:=Menu_AddStatusMenuItem(clmi);
+ else
+ result:=0;
+ end;
+end;
+
+procedure CreateMenuItem(var ActionItem:tMyActionItem;mtype:tMenuType);
+var
+ i:integer;
+ ActItem:pMyActionItem;
+ ActMItem,UAMenuItem:pUAMenuItem;
+ clmi:TCListMenuItem;
+ res:boolean;
+ extra:pWideChar;
+begin
+{}
+ UAMenuItem:=@ActionItem.UAMenuItem[mtype];
+ if UAMenuItem.hMenuItem<>0 then exit;
+
+ // create popup menu
+{}{}
+ res:=true;
+ if (UAMenuItem.szMenuPopup<>nil) and (UAMenuItem.szMenuPopup^<>#0) then
+ begin
+ res:=false;
+ for i:=0 to HIGH(UActionList) do
+ begin
+ // try to find root popup with same name (if we already created one)
+ ActItem :=@UActionList[i];
+ ActMItem:=@ActItem.UAMenuItem[mtype];
+
+ if (ActMItem.szMenuPopup<>nil) and
+ (ActMItem.hMenuRoot<>0) and
+ ( (ActItem<>@ActionItem) and
+ (StrCmpW(ActMItem.szMenuPopup,UAMenuItem.szMenuPopup)=0) ) then
+ begin
+ UAMenuItem.hMenuRoot:=ActMItem.hMenuRoot;
+ res:=true;
+ break;
+ end;
+ end;
+ end;
+ // popup menu not found
+ if not res then
+ begin
+ FillChar(clmi,SizeOf(clmi),0);
+ clmi.cbSize:=SizeOf(clmi);
+ clmi.flags :=CMIF_UNICODE{ or CMIF_ICONFROMICOLIB};
+
+ if (UAMenuItem.szMenuPopup<>nil) and (UAMenuItem.szMenuPopup^<>#0) then
+ clmi.szName.w:=ParseVarString(UAMenuItem.szMenuPopup)
+ else
+ clmi.szName.w:=ActionItem.szActDescr;
+
+ clmi.hIcon :=AddRootMenuIcon(clmi.szName.w);
+ clmi.position:=ActionItem.wSortIndex*10;
+
+ // position in Root Menu
+ inc(clmi.position,GetMenuPosition(0,mtype,
+ (UAMenuItem.menu_opt and UAF_MENUSEP)<>0));
+
+ UAMenuItem.hMenuRoot:=MakeMenuItem(mtype,@clmi);
+ //CallService(MenuServices[mtype],0,LPARAM(@clmi));
+ if clmi.szName.w<>ActionItem.szActDescr then
+ mFreeMem(clmi.szName.w);
+
+ for i:=1 to HIGH(arMenuRec) do
+ begin
+ with arMenuRec[i][mtype] do
+ if hMenuRoot=0 then
+ begin
+// MenuName :=ActionItem.szActDescr;
+ hMenuRoot:=UAMenuItem.hMenuRoot;
+ break;
+ end;
+ end;
+
+ end;
+{}{}
+
+ // Now Menu Item preparing
+{}{}
+ FillChar(clmi,SizeOf(clmi),0);
+ clmi.cbSize:=SizeOf(clmi);
+ clmi.flags:=CMIF_UNICODE{ or CMIF_ICONFROMICOLIB};
+ if (ActionItem.flags and (UAF_2STATE+UAF_PRESSED))<>(UAF_2STATE+UAF_PRESSED) then
+ begin
+ clmi.hIcon:=ActionItem.hIcolibIcon;
+ extra:='0';
+ end
+ else
+ begin
+ clmi.hIcon:=ActionItem.hIcolibIconPressed;
+ clmi.flags:=CMIF_UNICODE {or CMIF_ICONFROMICOLIB }or CMIF_CHECKED;
+ extra:='1';
+ end;
+
+ with ActionItem.UAMenuItem[mtype] do
+ begin
+ if (szMenuNameVars<>nil) and (szMenuNameVars^<>#0) then
+ clmi.szName.w:=ParseVarString(szMenuNameVars,0,extra)
+ else
+ clmi.szName.w:=ActionItem.szActDescr;
+
+ if hMenuRoot<>0 then
+ begin
+ clmi.flags:=clmi.flags or CMIF_ROOTHANDLE;
+ clmi.szPopupName.w:=pWideChar(hMenuRoot);
+ end;
+ end;
+
+ clmi.pszService:=ActionItem.szNameID;
+ if ActionItem.hMenuService=0 then
+ ActionItem.hMenuService:=CreateServiceFunctionParam(
+ clmi.pszService,@ServiceCallWithFParam,ActionItem.dwActID);
+
+ clmi.position:=ActionItem.wSortIndex*10;
+{}{}
+ inc(clmi.position,GetMenuPosition(UAMenuItem.hMenuRoot,mtype,
+ (UAMenuItem.menu_opt and UAF_MENUSEP)<>0));
+
+ UAMenuItem.hMenuItem:=MakeMenuItem(mtype,@clmi);
+ //CallService(MenuServices[mtype],0,LPARAM(@clmi));
+ if clmi.szName.w<>ActionItem.szActDescr then
+ mFreeMem(clmi.szName.w);
+{}
+
+end;
+
+function PreBuildMenu(mtype:tMenuType;hContact:THANDLE=0):int;
+var
+ i:integer;
+ mi:TCListMenuItem;
+ p,extra:pWideChar;
+begin
+ result:=0;
+
+ FillChar(mi,SizeOf(mi),0);
+ mi.cbSize:=SizeOf(mi);
+
+ for i:=0 to HIGH(UActionList) do
+ begin
+ mi.flags:=CMIM_FLAGS;
+ p:=nil;
+ with UActionList[i] do
+ begin
+ with UAMenuItem[mtype] do
+ begin
+ if hMenuItem<>0 then // it means, we process that item here
+ begin
+ mi.szName.w:=nil;
+ // Show / hide
+ if isVarsInstalled then
+ begin
+ if (szMenuShowWhenVars<>nil) and (szMenuShowWhenVars^<>#0) then
+ begin
+ p:=ParseVarString(szMenuShowWhenVars,hContact);
+ if p<>nil then
+ begin
+ if StrCmpW(p,'1')<>0 then
+ mi.flags:=CMIM_FLAGS or CMIF_HIDDEN;
+ mFreeMem(p);
+ end;
+ end;
+ end;
+
+ // change if need to show only
+ // (popup can be used by many items, keep unchanged)
+ if (mi.flags and CMIF_HIDDEN)=0 then
+ begin
+ //!!!! icon (check for contact menu)
+ mi.flags:=mi.flags or CMIM_ICON or CMIM_FLAGS{ or CMIF_ICONFROMICOLIB};
+
+ if (mtype=contact_menu) and IsLocalItem(UActionList[i]) then
+ begin
+ lastContact:=hContact;
+ if ((flags and UAF_2STATE)<>0) and
+ (DBReadByte(hContact,opt_ua,szNameID)<>0) then
+ begin
+ mi.flags:=mi.flags or CMIF_CHECKED;
+ mi.hIcon:=hIcolibIconPressed;
+ extra:='1';
+ flags:=flags or UAF_PRESSED;
+ end
+ else
+ begin
+ mi.hIcon:=hIcolibIcon;
+ flags:=flags and not UAF_PRESSED;
+ extra:='0';
+ end;
+
+ end
+ else
+ begin
+ if (flags and (UAF_2STATE+UAF_PRESSED))=(UAF_2STATE+UAF_PRESSED) then
+ begin
+ mi.flags:=mi.flags or CMIF_CHECKED;
+ mi.hIcon:=hIcolibIconPressed;
+ extra:='1';
+ end
+ else
+ begin
+ mi.hIcon:=hIcolibIcon;
+ extra:='0';
+ end;
+ end;
+
+ // new name
+ mi.flags:=mi.flags or CMIM_NAME or CMIF_UNICODE;
+ if (szMenuNameVars<>nil) and (szMenuNameVars^<>#0) then
+ mi.szName.w:=ParseVarString(szMenuNameVars,hContact,extra);
+
+ if mi.szName.w=nil then
+ mi.szName.w:=szActDescr;
+ end;
+
+ CallService(MS_CLIST_MODIFYMENUITEM,hMenuItem,LPARAM(@mi));
+ if mi.szName.w<>szActDescr then
+ mFreeMem(mi.szName.w);
+ end;
+ end;
+ end;
+
+ end;
+end;
+
+function PreBuildMainMenu(wParam:WPARAM;lParam:LPARAM):int; cdecl;
+begin
+ result:=PreBuildMenu(main_menu,wParam);
+end;
+
+function PreBuildContactMenu(wParam:WPARAM;lParam:LPARAM):int; cdecl;
+begin
+ result:=PreBuildMenu(contact_menu,wParam);
+end;
+
+function PreBuildTrayMenu(wParam:WPARAM;lParam:LPARAM):int; cdecl;
+begin
+ result:=PreBuildMenu(tray_menu,wParam);
+end;
+
+//----- TopToolbar -----
+
+procedure AddTTBButton(var ActionItem:tMyActionItem);
+var
+ mtButton:TTBButton;
+ pc,pc1,pc2:pAnsiChar;
+ res:boolean;
+ p:pWideChar;
+begin
+ if not NamesArray[uaTTB].enable then exit;
+
+ if ActionItem.hTTBButton=0 then
+ begin
+ // Add or not
+ if isVarsInstalled then
+ begin
+ if (ActionItem.szTTBShowWhenVars<>nil) and (ActionItem.szTTBShowWhenVars^<>#0) then
+ begin
+ p:=ParseVarString(ActionItem.szTTBShowWhenVars);
+ if p<>nil then
+ begin
+ res:=StrCmpW(p,'1')<>0;
+ mFreeMem(p);
+ end
+ else
+ res:=true;
+ if res then
+ exit;
+ end;
+ end;
+
+ FillChar(mtButton,SizeOf(mtButton),0);
+ mtButton.cbSize :=SizeOf(mtButton);
+
+ mtButton.pszService:=TTB_SERVICE_NAME;//SERVICE_WITH_LPARAM_NAME;
+ mtButton.lParamUp :=ActionItem.dwActID;
+ mtButton.lParamDown:=ActionItem.dwActID;
+
+ mtButton.hIconUp:=ActionItem.hIcolibIcon;
+ mtButton.hIconDn:=ActionItem.hIcolibIconPressed;
+
+ WideToAnsi(ActionItem.szActDescr,pc);
+
+ if (ActionItem.flags and UAF_2STATE)<>0 then
+ mtButton.dwFlags:=TTBBF_VISIBLE or TTBBF_SHOWTOOLTIP{ or TTBBF_ASPUSHBUTTON}
+ else
+ mtButton.dwFlags:=TTBBF_VISIBLE or TTBBF_SHOWTOOLTIP;
+
+ if ActionItem.szTTBTooltip =nil then
+ pc1:=pc
+ else pc1:=ActionItem.szTTBTooltip;
+
+ if ((ActionItem.flags and UAF_2STATE)=0) or
+ (ActionItem.szTTBTooltipPressed=nil) then
+ pc2:=pc1
+ else
+ pc2:=ActionItem.szTTBTooltipPressed;
+
+ mtButton.Name :=pc;
+ mtButton.pszTooltipUp :=pc1;
+ mtButton.pszTooltipDn :=pc2;
+
+ ActionItem.hTTBButton:=TopToolbar_AddButton(@mtButton);
+ if ActionItem.hTTBButton=THANDLE(-1) then
+ ActionItem.hTTBButton:=0;
+ mFreeMem(pc);
+ end;
+end;
+
+procedure DeleteTTBButton(var ActionItem:tMyActionItem);
+begin
+ if ActionItem.hTTBButton<>0 then
+ begin
+ CallService(MS_TTB_REMOVEBUTTON,ActionItem.hTTBButton,0);
+ ActionItem.hTTBButton:=0;
+ end;
+end;
+
+function TTBServiceCall(wParam:WPARAM; lParam:LPARAM):int_ptr; cdecl;
+var
+ i,lflag:integer;
+begin
+ result:=0;
+ for i:=0 to HIGH(UActionList) do
+ begin
+ if TLPARAM(UActionList[i].dwActID)=lParam then
+ begin
+ with UActionList[i] do
+ begin
+ if (flags and UAF_2STATE)<>0 then
+ begin
+ if CallService(MS_TTB_GETBUTTONSTATE,hTTBButton,0)=TTBST_PUSHED then
+ begin
+ lflag:=TTBST_RELEASED;
+ end
+ else
+ begin
+ lflag:=TTBST_PUSHED;
+ end;
+ CallService(MS_TTB_SETBUTTONSTATE,hTTBButton,lflag);
+ end;
+ end;
+
+ result:=ServiceCallWithFParam(0,0,lParam);
+ break;
+ end;
+ end;
+end;
+
+function OnTTBLoaded(wParam:WPARAM;lParam:LPARAM):int; cdecl;
+var
+ i:integer;
+begin
+ result:=0;
+ for i:=HIGH(UActionList) downto 0 do
+ begin
+ if (UActionList[i].flags and UAF_REGTTBB)<>0 then
+ AddTTBButton(UActionList[i]);
+ end;
+end;
+
+//----- TabSRMM Toolbar -----
+
+const
+ TABTOOLBAR_INITPOS = 350;
+
+procedure AddTabBBButton(var ActionItem:tMyActionItem);
+var
+ tabb:BBButton;
+begin
+ if not NamesArray[uaTAB].enable then exit;
+
+ if (ActionItem.flags and UAF_TBREGGED)=0 then
+ begin
+ FillChar(tabb,SizeOf(tabb),0);
+ // register Tab ButtonBar button
+ tabb.cbSize :=SizeOf(tabb);
+ tabb.dwButtonID :=ActionItem.dwActID;
+ tabb.pszModuleName:=MODULE_NAME;
+ tabb.dwDefPos :=(TABTOOLBAR_INITPOS+ActionItem.wSortIndex*10) and $7FFF;
+ tabb.iButtonWidth :=0;
+ tabb.hIcon :=ActionItem.hIcolibIcon;
+ if (ActionItem.flags and UAF_2STATE)<>0 then
+ tabb.bbbFlags:=BBBF_ISIMBUTTON or BBBF_ISLSIDEBUTTON or
+ BBBF_ISCHATBUTTON or BBBF_ISPUSHBUTTON
+ else
+ tabb.bbbFlags:=BBBF_ISIMBUTTON or BBBF_ISLSIDEBUTTON or
+ BBBF_ISCHATBUTTON;
+
+ if ActionItem.szTabBTooltip<>nil then
+ tabb.szTooltip.w:=ActionItem.szTabBTooltip
+ else
+ tabb.szTooltip.w:=ActionItem.szActDescr;
+
+ if CallService(MS_BB_ADDBUTTON,0,LPARAM(@tabb))=0 then
+ ActionItem.flags:=ActionItem.flags or UAF_TBREGGED;
+ end;
+end;
+
+procedure DeleteTabBBButton(var ActionItem:tMyActionItem);
+var
+ tabb:BBButton;
+begin
+ if (ActionItem.flags and UAF_TBREGGED)<>0 then
+ begin
+ FillChar(tabb,SizeOf(tabb),0);
+ tabb.cbSize :=SizeOf(tabb);
+ tabb.dwButtonID :=ActionItem.dwActID;
+ tabb.pszModuleName:=MODULE_NAME;
+ CallService(MS_BB_REMOVEBUTTON,0,LPARAM(@tabb));
+ ActionItem.flags:=ActionItem.flags and not UAF_TBREGGED;
+ end;
+end;
+
+function OnTabButtonPressed(wParam:WPARAM;lParam:LPARAM):int; cdecl;
+var
+ cbcd:pCustomButtonClickData;
+// tabb:BBButton;
+// pc:pWideChar;
+ i:integer;
+begin
+ result:=0;
+ cbcd:=pointer(lParam);
+ if StrCmp(cbcd.pszModule,MODULE_NAME)<>0 then
+ exit;
+
+ for i:=0 to HIGH(UActionList) do
+ begin
+ with UActionList[i] do
+ begin
+ if cbcd.dwButtonId=dwActID then
+ begin
+{
+ FillChar(tabb,SizeOf(tabb),0);
+ tabb.cbSize :=SizeOf(tabb);
+ tabb.dwButtonID :=cbcd.dwButtonId;
+ tabb.pszModuleName:=MODULE_NAME;
+ if (flags and UAF_2STATE)<>0 then
+ begin
+ CallService(MS_BB_GETBUTTONSTATE,cbcd.hContact,TLPARAM(@tabb));
+ if IsLocalItem(UActionList[i]) then
+ begin
+ if DBReadByte(hContact,opt_ua,szNameID)<>0 then
+ end
+ else
+ begin
+ if (tabb.bbbFlags and BBSF_PUSHED)<>0 then
+ begin
+ pc:=szTabBTooltipPressed;
+ if pc=nil then pc:=szTabBTooltip;
+ tabb.hIcon:=hIcolibIconPressed;
+ end
+ else
+ begin
+ pc:=szTabBTooltip;
+ tabb.hIcon:=hIcolibIcon;
+ end;
+ if pc=nil then pc:=szActDescr;
+ tabb.szTooltip.w:=pc;
+ tabb.bbbFlags :=BBBF_ISIMBUTTON or BBBF_ISLSIDEBUTTON or
+ BBBF_ISCHATBUTTON or BBBF_ISPUSHBUTTON;
+ end
+ else
+ begin
+ tabb.hIcon:=hIcolibIcon;
+ tabb.szTooltip.w:=szTabBTooltip;
+ if tabb.szTooltip.w=nil then tabb.szTooltip.w:=szActDescr;
+ tabb.bbbFlags :=BBBF_ISIMBUTTON or BBBF_ISLSIDEBUTTON or
+ BBBF_ISCHATBUTTON;
+ end;
+
+ tabb.iButtonWidth:=0;
+ tabb.dwDefPos :=(TABTOOLBAR_INITPOS+wSortIndex*10) and $7FFF;
+ CallService(MS_BB_MODIFYBUTTON,0,TLPARAM(@tabb));
+}
+ ServiceCallWithFParam(cbcd.hContact,0,cbcd.dwButtonId);
+ result:=1;
+ break;
+ end;
+ end;
+ end;
+
+end;
+
+function OnTabBBLoaded(wParam:WPARAM;lParam:LPARAM):int; cdecl;
+var
+ i:integer;
+begin
+ result:=0;
+ for i:=HIGH(UActionList) downto 0 do
+ begin
+ if (UActionList[i].flags and UAF_REGTABB)<>0 then
+ AddTabBBButton(UActionList[i]);
+ end;
+end;
diff --git a/plugins/Actman30/ua/i_uavars.inc b/plugins/Actman30/ua/i_uavars.inc
new file mode 100644
index 0000000000..5b53cde26a
--- /dev/null
+++ b/plugins/Actman30/ua/i_uavars.inc
@@ -0,0 +1,121 @@
+{}
+const
+ MODULE_NAME = 'Actions';
+const
+ opt_groups:PAnsiChar = 'Group';
+ opt_ua :PAnsiChar = 'UA';
+ opt_id :PAnsiChar = 'id';
+ opt_flags :PAnsiChar = 'Flags';
+
+const
+ ICOLIB_ACTSECTION = MODULE_NAME+'/Registered actions';
+ ICOLIB_MNUSECTION = MODULE_NAME+'/Menu icons';
+
+ SERVICE_WITH_LPARAM_NAME = MODULE_NAME+'/CallAction';
+ TTB_SERVICE_NAME = MODULE_NAME+'/TTBAction';
+
+type
+ tMenuType = (main_menu,contact_menu,tray_menu,proto_menu,status_menu);
+ pUAMenuItem = ^tUAMenuItem;
+ tUAMenuItem = record
+ hMenuItem :THANDLE;
+ szMenuPopup :pWideChar;
+ szMenuNameVars :pWideChar;
+ szMenuShowWhenVars:pWideChar;
+ hMenuRoot :THANDLE;
+ menu_opt :dword;
+ changed :boolean;
+ end;
+type
+ pMyActionItem = ^tMyActionItem;
+ tMyActionItem = record
+ flags :dword;
+ dwActID :dword; // action ID
+ wSortIndex :word; // list/menu/toolbar order
+ // UseActions/Action_ID
+ szNameID :pAnsiChar; // uaction ID
+ szActDescr :pWideChar; // action name
+
+ hIcolibIcon,
+ hIcolibIconPressed :THANDLE;
+
+ hTTBButton :THANDLE; // TopToolbar button
+ szTTBTooltip :PAnsiChar;
+ szTTBTooltipPressed :PAnsiChar;
+ szTTBShowWhenVars :pWideChar;
+
+ szTabBTooltip :PWideChar; // TabSRMM toolbar button
+ szTabBTooltipPressed:PWideChar;
+
+ lastContact :THANDLE; // for contact menu
+ hMenuService :THANDLE; // common menu service
+ UAMenuItem :array [tMenuType] of tUAMenuItem;
+ end;
+
+const
+ UAF_NONE = 0;
+
+ UAF_REGHOTKEY = 1 shl 0; // hotkey
+ UAF_REGTTBB = 1 shl 1; // modern toolbar
+
+ UAF_REGTABB = 1 shl 5; // TabSRMM toolbar
+ UAF_USING = UAF_REGHOTKEY or UAF_REGTTBB or UAF_REGTABB;
+
+ UAF_2STATE = 1 shl 11; // Buttons/menu items are 2-state
+ UAF_PRESSED = 1 shl 12; // Button pressed/menu item selected
+ UAF_SAVESTATE = 1 shl 13; // Save or not "pressed" state
+ UAF_GLOBAL = 1 shl 14; // not contact related even if in contact menu only
+
+ // realtime, no save
+ UAF_HKREGGED = 1 shl 16; // hotkey registered
+ UAF_TBREGGED = 1 shl 17; // TabSRMM button registered
+ UAF_DISABLED = 1 shl 30; // action disabled atm
+ UAF_REALTIME = UAF_HKREGGED or UAF_TBREGGED or UAF_DISABLED;
+
+ UAF_SPECIAL = 1 shl 31; // for settings read
+
+ // menu options
+ UAF_MENUSEP = 1 shl 1; // menu item separated
+ UAF_MENUUSE = 1 shl 8; // use this menu
+
+type
+ tNameRec = record
+ name :PAnsiChar;
+ service:PAnsiChar;
+ mask :dword;
+ atype :word;
+ enable :boolean;
+ end;
+
+const
+ NumTypes = 8;
+const
+ uaTTB = 0;
+ uaTAB = 1;
+ uaHotkey = 2;
+ uaMenu = 3;
+
+const
+ NamesArray: array [0..NumTypes-1] of tNameRec = (
+ (name:'TopToolbar'; service:'TopToolBar/AddButton';
+ mask:UAF_REGTTBB ; atype:uaTTB; enable:false),
+ (name:'TabSRMM toolbar' ; service:'TabSRMM/ButtonsBar/AddButton';
+ mask:UAF_REGTABB ; atype:uaTAB; enable:false),
+ (name:'Core Hotkey' ; service:nil{MS_HOTKEY_REGISTER};
+ mask:UAF_REGHOTKEY; atype:uaHotkey; enable:false),
+ (name:'Main menu' ; service:nil;
+ mask:0; atype:uaMenu+(ORD(main_menu ) shl 8); enable:false),
+ (name:'Contact menu' ; service:nil;
+ mask:0; atype:uaMenu+(ORD(contact_menu) shl 8); enable:false),
+ (name:'Tray menu' ; service:'CList/AddTrayMenuItem';
+ mask:0; atype:uaMenu+(ORD(tray_menu ) shl 8); enable:false),
+ (name:'Protocol menus' ; service:'CList/AddProtoMenuItem';
+ mask:0; atype:uaMenu+(ORD(proto_menu ) shl 8); enable:false),
+ (name:'Status menu' ; service:'CList/AddStatusMenuItem';
+ mask:0; atype:uaMenu+(ORD(status_menu ) shl 8); enable:false)
+ );
+
+var
+ UActionList:array of tMyActionItem;
+var
+ szMyPath:array [0..MAX_PATH] of WideChar;
diff --git a/plugins/Actman30/ua/i_uconst.inc b/plugins/Actman30/ua/i_uconst.inc
new file mode 100644
index 0000000000..34dde3ee9e
--- /dev/null
+++ b/plugins/Actman30/ua/i_uconst.inc
@@ -0,0 +1,34 @@
+{resource constants}
+const
+ IDD_UA = 1031;
+
+ IDC_UA_ACTIONLIST = 1025;
+ IDC_UA_PLACELIST = 1026;
+
+ // menu settings
+ IDC_UA_SEPARATE = 1027;
+ IDC_UA_POPUPT = 1028;
+ IDC_UA_POPUPV = 1029;
+
+ IDC_UA_VARNAMEST = 1030;
+ IDC_UA_VARNAMESV = 1031;
+ IDC_UA_VARNAMESH = 1032;
+
+ IDC_UA_SHOWVART = 1033;
+ IDC_UA_SHOWVARV = 1034;
+ IDC_UA_SHOWVARH = 1035;
+
+ // toolbar settings
+ IDC_UA_TTNORMALT = 2028;
+ IDC_UA_TTNORMALV = 2029;
+ IDC_UA_TTPRESSEDT = 2030;
+ IDC_UA_TTPRESSEDV = 2031;
+
+ // common
+ IDC_UA_COMMON = 2000;
+ IDC_UA_TWOSTATE = 2001;
+ IDC_UA_SAVSTATE = 2002;
+
+ IDC_UA_GLOBAL = 2003;
+
+ IDI_ACTION = 101;
diff --git a/plugins/Actman30/ua/ua.pas b/plugins/Actman30/ua/ua.pas
new file mode 100644
index 0000000000..4aad8e1793
--- /dev/null
+++ b/plugins/Actman30/ua/ua.pas
@@ -0,0 +1,108 @@
+unit ua;
+
+interface
+
+implementation
+
+uses
+ windows, commctrl, messages,
+ mirutils, common, dbsettings, io, m_api, wrapper,
+ global;
+
+{$R ua.res}
+
+{$include m_actman.inc}
+
+{$include i_uconst.inc}
+{$include i_uavars.inc}
+
+// in - Action ID, out - action (group) number
+function GetUABranch(setting:pAnsiChar;id:cardinal):pAnsiChar;
+var
+ i:integer;
+ p,p1:pAnsiChar;
+begin
+ result:=nil;
+ p1:=StrCopyE(setting,opt_groups);
+ for i:=0 to CallService(MS_ACT_GETLIST,0,0)-1 do
+ begin
+ p:=StrEnd(IntToStr(p1,i));
+ p^:='/'; inc(p);
+ StrCopy(p,opt_id);
+ if DBReadDWord(0,DBBranch,setting)=id then
+ begin
+ p^:=#0;
+ result:=p;
+ break;
+ end;
+ end;
+end;
+
+var
+ amLink:tActionLink;
+
+{$include i_uaplaces.inc}
+{$include i_options.inc}
+{$include i_opt_dlg.inc}
+{$include i_ua.inc}
+{$include i_inoutxm.inc}
+
+// ------------ base interface functions -------------
+
+procedure Init;
+begin
+ GetModuleFileNameW(hInstance,szMyPath,MAX_PATH);
+
+ CreateServiceFunction(SERVICE_WITH_LPARAM_NAME,@ServiceCallWithLParam);
+ CreateServiceFunction(TTB_SERVICE_NAME ,@TTBServiceCall);
+ CheckPlacesAbility;
+
+ CreateUActionList;
+
+ HookEvent(ME_TTB_MODULELOADED ,@OnTTBLoaded);
+ HookEvent(ME_MSG_TOOLBARLOADED,@OnTabBBLoaded);
+ HookEvent(ME_MSG_BUTTONPRESSED,@OnTabButtonPressed);
+ HookEvent(ME_ACT_CHANGED ,@ActListChange);
+
+ HookEvent(ME_CLIST_PREBUILDMAINMENU , PreBuildMainMenu);
+ HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PreBuildContactMenu);
+ HookEvent(ME_CLIST_PREBUILDTRAYMENU , PreBuildTrayMenu);
+
+ HookEvent(ME_ACT_INOUT,@ActInOut);
+end;
+
+procedure DeInit;
+var
+ i:integer;
+begin
+ if Length(UActionList)>0 then
+ begin
+ for i:=HIGH(UActionList) downto 0 do
+ begin
+ DeleteUAction(i,false);
+ end;
+ SetLength(UActionList,0);
+ end;
+ SetLength(arMenuRec,0);
+end;
+
+function AddOptionPage(var tmpl:pAnsiChar;var proc:pointer;var name:PAnsiChar):integer;
+begin
+ result:=0;
+ tmpl:=PAnsiChar(IDD_UA);
+ proc:=@DlgProcOpt;
+ name:='Use Actions';
+end;
+
+procedure InitLink;
+begin
+ amLink.Next :=ActionLink;
+ amLink.Init :=@Init;
+ amLink.DeInit :=@DeInit;
+ amLink.AddOption:=@AddOptionPage;
+ ActionLink :=@amLink;
+end;
+
+initialization
+ InitLink;
+end.
diff --git a/plugins/Actman30/ua/ua.rc b/plugins/Actman30/ua/ua.rc
new file mode 100644
index 0000000000..76d8c0ad77
--- /dev/null
+++ b/plugins/Actman30/ua/ua.rc
@@ -0,0 +1,51 @@
+#include "i_uconst.inc"
+
+LANGUAGE 0,0
+
+IDD_UA DIALOGEX 0, 0, 304, 226, 0
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0
+{
+ CTEXT "Action list",-1, 2,2,132,10, SS_CENTERIMAGE
+ CONTROL "", IDC_UA_ACTIONLIST, "SysListView32",
+ WS_BORDER | WS_TABSTOP |
+ LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS | LVS_REPORT | LVS_SINGLESEL,
+ 2, 12, 132, 212, WS_EX_CONTROLPARENT
+
+ CTEXT "Where to use",-1, 138,2,160,10, SS_CENTERIMAGE
+ CONTROL "", IDC_UA_PLACELIST, "SysListView32",
+ WS_BORDER | WS_TABSTOP |
+ LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS | LVS_REPORT | LVS_SINGLESEL,
+ 138, 12, 160, 74, WS_EX_CONTROLPARENT
+
+ GROUPBOX "Common" , IDC_UA_COMMON , 138, 88,160,38
+ AUTOCHECKBOX "2 state button/item" , IDC_UA_TWOSTATE, 140, 96,156,14, BS_LEFTTEXT | BS_RIGHT
+ AUTOCHECKBOX "Save button/item state", IDC_UA_SAVSTATE, 140,110,156,14, BS_LEFTTEXT | BS_RIGHT
+
+ AUTOCHECKBOX "Contact related", IDC_UA_GLOBAL, 138,128,160,14, BS_LEFTTEXT | BS_RIGHT
+
+ // Buttons settings block
+ RTEXT "Normal button tooltip",IDC_UA_TTNORMALT, 138,148,160,8
+ EDITTEXT IDC_UA_TTNORMALV, 138,158,160,12, ES_AUTOHSCROLL
+
+ RTEXT "Pressed button tooltip",IDC_UA_TTPRESSEDT, 138,172,160,8
+ EDITTEXT IDC_UA_TTPRESSEDV, 138,182,160,12, ES_AUTOHSCROLL
+
+ // Menu settings block
+ AUTOCHECKBOX "Separated",IDC_UA_SEPARATE, 138,142,160,14, BS_LEFTTEXT | BS_RIGHT
+
+ RTEXT "Root popup:",IDC_UA_POPUPT,138,158,80,12, SS_CENTERIMAGE
+ EDITTEXT IDC_UA_POPUPV, 218,158,80,12, ES_AUTOHSCROLL
+
+ RTEXT "Menu item name:",IDC_UA_VARNAMEST, 138,172,140,8
+ EDITTEXT IDC_UA_VARNAMESV, 138,182,140,12, ES_AUTOHSCROLL
+ CONTROL "V",IDC_UA_VARNAMESH,"MButtonClass",WS_TABSTOP, 282,180,16,16, $18000000
+
+ RTEXT "Show only if variables return 1",IDC_UA_SHOWVART, 138,200,140,8
+ EDITTEXT IDC_UA_SHOWVARV,138,210,140,12,ES_AUTOHSCROLL
+ CONTROL "V",IDC_UA_SHOWVARH,"MButtonClass",WS_TABSTOP, 282,208,16,16, $18000000
+
+}
+
+IDI_ACTION ICON "action.ico"