From 6eb843fa1f9d7c63f1a89a152e93d9b38f893009 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Sun, 16 Feb 2014 12:47:53 +0000 Subject: MetaContacts moved to deprecated git-svn-id: http://svn.miranda-ng.org/main/trunk@8134 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- .../MetaContacts/MetaContacts_10.vcxproj | 218 +++ .../MetaContacts/MetaContacts_10.vcxproj.filters | 68 + .../MetaContacts/MetaContacts_11.vcxproj | 221 +++ .../MetaContacts/MetaContacts_11.vcxproj.filters | 68 + .../MetaContacts/MetaContacts_12.vcxproj | 221 +++ .../MetaContacts/MetaContacts_12.vcxproj.filters | 68 + .../Proto_MetaContacts_10.vcxproj | 131 ++ .../Proto_MetaContacts_10.vcxproj.filters | 23 + .../Proto_MetaContacts_11.vcxproj | 135 ++ .../Proto_MetaContacts_11.vcxproj.filters | 23 + .../Proto_MetaContacts_12.vcxproj | 135 ++ .../Proto_MetaContacts_12.vcxproj.filters | 23 + .../MetaContacts/proto_metacontacts/res/Away.ico | Bin 0 -> 1150 bytes .../MetaContacts/proto_metacontacts/res/DND.ico | Bin 0 -> 1150 bytes .../MetaContacts/proto_metacontacts/res/FFC.ico | Bin 0 -> 1150 bytes .../proto_metacontacts/res/Invisible.ico | Bin 0 -> 1150 bytes .../MetaContacts/proto_metacontacts/res/Lunch.ico | Bin 0 -> 1150 bytes .../MetaContacts/proto_metacontacts/res/NA.ico | Bin 0 -> 1150 bytes .../proto_metacontacts/res/Occupied.ico | Bin 0 -> 1150 bytes .../proto_metacontacts/res/Offline.ico | Bin 0 -> 1150 bytes .../MetaContacts/proto_metacontacts/res/Online.ico | Bin 0 -> 1150 bytes .../MetaContacts/proto_metacontacts/res/Phone.ico | Bin 0 -> 1150 bytes .../proto_metacontacts/res/Proto_MetaContacts.rc | Bin 0 -> 4362 bytes .../MetaContacts/proto_metacontacts/src/resource.h | Bin 0 -> 1738 bytes .../!Deprecated/MetaContacts/res/MetaContacts.rc | 263 ++++ plugins/!Deprecated/MetaContacts/res/mcmenu.ico | Bin 0 -> 1150 bytes plugins/!Deprecated/MetaContacts/res/mcmenuof.ico | Bin 0 -> 1150 bytes plugins/!Deprecated/MetaContacts/res/meta_add.ico | Bin 0 -> 1150 bytes .../!Deprecated/MetaContacts/res/meta_convert.ico | Bin 0 -> 1150 bytes plugins/!Deprecated/MetaContacts/res/meta_edit.ico | Bin 0 -> 1150 bytes .../!Deprecated/MetaContacts/res/meta_remove2.ico | Bin 0 -> 1150 bytes .../MetaContacts/res/meta_set_as_default.ico | Bin 0 -> 1150 bytes plugins/!Deprecated/MetaContacts/res/version.rc | 38 + plugins/!Deprecated/MetaContacts/src/addto.cpp | 211 +++ plugins/!Deprecated/MetaContacts/src/edit.cpp | 465 +++++++ plugins/!Deprecated/MetaContacts/src/icons.cpp | 26 + plugins/!Deprecated/MetaContacts/src/meta_api.cpp | 242 ++++ plugins/!Deprecated/MetaContacts/src/meta_main.cpp | 208 +++ plugins/!Deprecated/MetaContacts/src/meta_menu.cpp | 431 ++++++ .../!Deprecated/MetaContacts/src/meta_options.cpp | 609 ++++++++ .../!Deprecated/MetaContacts/src/meta_services.cpp | 1453 ++++++++++++++++++++ .../!Deprecated/MetaContacts/src/meta_utils.cpp | 1431 +++++++++++++++++++ .../!Deprecated/MetaContacts/src/metacontacts.h | 224 +++ plugins/!Deprecated/MetaContacts/src/resource.h | 75 + plugins/!Deprecated/MetaContacts/src/stdafx.cpp | 18 + plugins/!Deprecated/MetaContacts/src/version.h | 14 + 46 files changed, 7042 insertions(+) create mode 100644 plugins/!Deprecated/MetaContacts/MetaContacts_10.vcxproj create mode 100644 plugins/!Deprecated/MetaContacts/MetaContacts_10.vcxproj.filters create mode 100644 plugins/!Deprecated/MetaContacts/MetaContacts_11.vcxproj create mode 100644 plugins/!Deprecated/MetaContacts/MetaContacts_11.vcxproj.filters create mode 100644 plugins/!Deprecated/MetaContacts/MetaContacts_12.vcxproj create mode 100644 plugins/!Deprecated/MetaContacts/MetaContacts_12.vcxproj.filters create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_10.vcxproj create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_10.vcxproj.filters create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_11.vcxproj create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_11.vcxproj.filters create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_12.vcxproj create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_12.vcxproj.filters create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Away.ico create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/res/DND.ico create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/res/FFC.ico create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Invisible.ico create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Lunch.ico create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/res/NA.ico create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Occupied.ico create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Offline.ico create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Online.ico create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Phone.ico create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Proto_MetaContacts.rc create mode 100644 plugins/!Deprecated/MetaContacts/proto_metacontacts/src/resource.h create mode 100644 plugins/!Deprecated/MetaContacts/res/MetaContacts.rc create mode 100644 plugins/!Deprecated/MetaContacts/res/mcmenu.ico create mode 100644 plugins/!Deprecated/MetaContacts/res/mcmenuof.ico create mode 100644 plugins/!Deprecated/MetaContacts/res/meta_add.ico create mode 100644 plugins/!Deprecated/MetaContacts/res/meta_convert.ico create mode 100644 plugins/!Deprecated/MetaContacts/res/meta_edit.ico create mode 100644 plugins/!Deprecated/MetaContacts/res/meta_remove2.ico create mode 100644 plugins/!Deprecated/MetaContacts/res/meta_set_as_default.ico create mode 100644 plugins/!Deprecated/MetaContacts/res/version.rc create mode 100644 plugins/!Deprecated/MetaContacts/src/addto.cpp create mode 100644 plugins/!Deprecated/MetaContacts/src/edit.cpp create mode 100644 plugins/!Deprecated/MetaContacts/src/icons.cpp create mode 100644 plugins/!Deprecated/MetaContacts/src/meta_api.cpp create mode 100644 plugins/!Deprecated/MetaContacts/src/meta_main.cpp create mode 100644 plugins/!Deprecated/MetaContacts/src/meta_menu.cpp create mode 100644 plugins/!Deprecated/MetaContacts/src/meta_options.cpp create mode 100644 plugins/!Deprecated/MetaContacts/src/meta_services.cpp create mode 100644 plugins/!Deprecated/MetaContacts/src/meta_utils.cpp create mode 100644 plugins/!Deprecated/MetaContacts/src/metacontacts.h create mode 100644 plugins/!Deprecated/MetaContacts/src/resource.h create mode 100644 plugins/!Deprecated/MetaContacts/src/stdafx.cpp create mode 100644 plugins/!Deprecated/MetaContacts/src/version.h (limited to 'plugins/!Deprecated') diff --git a/plugins/!Deprecated/MetaContacts/MetaContacts_10.vcxproj b/plugins/!Deprecated/MetaContacts/MetaContacts_10.vcxproj new file mode 100644 index 0000000000..f1d9227c4d --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/MetaContacts_10.vcxproj @@ -0,0 +1,218 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + MetaContacts + {0007BE9F-DD4D-4E9B-B1C8-C5049538F862} + + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Plugins\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Plugins\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + true + + + + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Use + metacontacts.h + Level3 + EditAndContinue + Disabled + false + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + comctl32.lib;%(AdditionalDependencies) + true + false + $(IntDir)$(TargetName).lib + Windows + 0x22010000 + $(ProfileDir)..\..\bin10\lib + + + + + Full + OnlyExplicitInline + Size + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + false + true + Fast + Use + metacontacts.h + Level3 + false + false + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + comctl32.lib;%(AdditionalDependencies) + true + 0x22010000 + false + $(IntDir)$(TargetName).lib + true + true + Windows + $(ProfileDir)..\..\bin10\lib + /PDBALTPATH:%_PDB% + + + + + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + EnableFastChecks + MultiThreadedDebugDLL + Disabled + Level3 + _DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + Use + metacontacts.h + false + + + $(IntDir)$(TargetName).lib + true + Windows + false + comctl32.lib;%(AdditionalDependencies) + 0x22010000 + $(ProfileDir)..\..\bin10\lib + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + + + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + Full + OnlyExplicitInline + Size + false + Level3 + NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + Use + metacontacts.h + true + false + false + true + + + $(IntDir)$(TargetName).lib + true + true + true + Windows + false + comctl32.lib;%(AdditionalDependencies) + 0x22010000 + $(ProfileDir)..\..\bin10\lib + /PDBALTPATH:%_PDB% + + + ..\..\include\msapi + NDEBUG;%(PreprocessorDefinitions) + + + + + + + + + Create + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/!Deprecated/MetaContacts/MetaContacts_10.vcxproj.filters b/plugins/!Deprecated/MetaContacts/MetaContacts_10.vcxproj.filters new file mode 100644 index 0000000000..68ef7fcc59 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/MetaContacts_10.vcxproj.filters @@ -0,0 +1,68 @@ + + + + + {4a8bb46c-4423-42fc-9576-78cd8badfcff} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {a442bb73-5e8b-4eb0-b6c0-0534f3ca4b87} + h;hpp;hxx;hm;inl + + + {b4847f2a-7aa8-4577-a5a1-f7adf03537ec} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + Resource Files + + + \ No newline at end of file diff --git a/plugins/!Deprecated/MetaContacts/MetaContacts_11.vcxproj b/plugins/!Deprecated/MetaContacts/MetaContacts_11.vcxproj new file mode 100644 index 0000000000..8c12852f46 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/MetaContacts_11.vcxproj @@ -0,0 +1,221 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + MetaContacts + {0007BE9F-DD4D-4E9B-B1C8-C5049538F862} + + + + DynamicLibrary + Unicode + true + v110_xp + + + DynamicLibrary + Unicode + v110_xp + + + DynamicLibrary + true + Unicode + v110_xp + + + DynamicLibrary + Unicode + v110_xp + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Plugins\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Plugins\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + true + + + + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Use + metacontacts.h + Level3 + EditAndContinue + Disabled + false + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + comctl32.lib;%(AdditionalDependencies) + true + false + $(IntDir)$(TargetName).lib + Windows + 0x22010000 + $(ProfileDir)..\..\bin11\lib + false + + + + + Full + OnlyExplicitInline + Size + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + false + true + Fast + Use + metacontacts.h + Level3 + false + false + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + comctl32.lib;%(AdditionalDependencies) + true + 0x22010000 + false + $(IntDir)$(TargetName).lib + true + true + Windows + $(ProfileDir)..\..\bin11\lib + + + + + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + EnableFastChecks + MultiThreadedDebugDLL + Disabled + Level3 + _DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + Use + metacontacts.h + false + + + $(IntDir)$(TargetName).lib + true + Windows + false + comctl32.lib;%(AdditionalDependencies) + 0x22010000 + $(ProfileDir)..\..\bin11\lib + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + + + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + Full + OnlyExplicitInline + Size + false + Level3 + NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + Use + metacontacts.h + true + false + false + true + + + $(IntDir)$(TargetName).lib + true + true + true + Windows + false + comctl32.lib;%(AdditionalDependencies) + 0x22010000 + $(ProfileDir)..\..\bin11\lib + + + ..\..\include\msapi + NDEBUG;%(PreprocessorDefinitions) + + + + + + + + + Create + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/!Deprecated/MetaContacts/MetaContacts_11.vcxproj.filters b/plugins/!Deprecated/MetaContacts/MetaContacts_11.vcxproj.filters new file mode 100644 index 0000000000..68ef7fcc59 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/MetaContacts_11.vcxproj.filters @@ -0,0 +1,68 @@ + + + + + {4a8bb46c-4423-42fc-9576-78cd8badfcff} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {a442bb73-5e8b-4eb0-b6c0-0534f3ca4b87} + h;hpp;hxx;hm;inl + + + {b4847f2a-7aa8-4577-a5a1-f7adf03537ec} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + Resource Files + + + \ No newline at end of file diff --git a/plugins/!Deprecated/MetaContacts/MetaContacts_12.vcxproj b/plugins/!Deprecated/MetaContacts/MetaContacts_12.vcxproj new file mode 100644 index 0000000000..41edf86361 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/MetaContacts_12.vcxproj @@ -0,0 +1,221 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + MetaContacts + {0007BE9F-DD4D-4E9B-B1C8-C5049538F862} + + + + DynamicLibrary + Unicode + true + v120_xp + + + DynamicLibrary + Unicode + v120_xp + + + DynamicLibrary + true + Unicode + v120_xp + + + DynamicLibrary + Unicode + v120_xp + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Plugins\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Plugins\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + true + + + + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Use + metacontacts.h + Level3 + EditAndContinue + Disabled + false + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + comctl32.lib;%(AdditionalDependencies) + true + false + $(IntDir)$(TargetName).lib + Windows + 0x22010000 + $(ProfileDir)..\..\bin12\lib + false + + + + + Full + OnlyExplicitInline + Size + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + false + true + Fast + Use + metacontacts.h + Level3 + false + false + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + comctl32.lib;%(AdditionalDependencies) + true + 0x22010000 + false + $(IntDir)$(TargetName).lib + true + true + Windows + $(ProfileDir)..\..\bin12\lib + + + + + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + EnableFastChecks + MultiThreadedDebugDLL + Disabled + Level3 + _DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + Use + metacontacts.h + false + + + $(IntDir)$(TargetName).lib + true + Windows + false + comctl32.lib;%(AdditionalDependencies) + 0x22010000 + $(ProfileDir)..\..\bin12\lib + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + + + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + Full + OnlyExplicitInline + Size + false + Level3 + NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + Use + metacontacts.h + true + false + false + true + + + $(IntDir)$(TargetName).lib + true + true + true + Windows + false + comctl32.lib;%(AdditionalDependencies) + 0x22010000 + $(ProfileDir)..\..\bin12\lib + + + ..\..\include\msapi + NDEBUG;%(PreprocessorDefinitions) + + + + + + + + + Create + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/!Deprecated/MetaContacts/MetaContacts_12.vcxproj.filters b/plugins/!Deprecated/MetaContacts/MetaContacts_12.vcxproj.filters new file mode 100644 index 0000000000..68ef7fcc59 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/MetaContacts_12.vcxproj.filters @@ -0,0 +1,68 @@ + + + + + {4a8bb46c-4423-42fc-9576-78cd8badfcff} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {a442bb73-5e8b-4eb0-b6c0-0534f3ca4b87} + h;hpp;hxx;hm;inl + + + {b4847f2a-7aa8-4577-a5a1-f7adf03537ec} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + Resource Files + + + \ No newline at end of file diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_10.vcxproj b/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_10.vcxproj new file mode 100644 index 0000000000..b4d76b9124 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_10.vcxproj @@ -0,0 +1,131 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {793B6174-89B0-4682-A957-A32BE7F61502} + Proto_MetaContacts + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\Icons\ + $(SolutionDir)$(Configuration)64\Icons\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)\Icons\ + $(SolutionDir)$(Configuration)64\Icons\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + true + + + + Windows + true + false + $(SolutionDir)\lib + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\..\include\msapi + + + + + Windows + true + false + $(SolutionDir)\lib + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\..\include\msapi + + + + + Windows + true + false + $(SolutionDir)\lib + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\..\include\msapi + + + + + Windows + true + false + $(SolutionDir)\lib + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\..\include\msapi + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_10.vcxproj.filters b/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_10.vcxproj.filters new file mode 100644 index 0000000000..af73080618 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_10.vcxproj.filters @@ -0,0 +1,23 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_11.vcxproj b/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_11.vcxproj new file mode 100644 index 0000000000..60e8cfd258 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_11.vcxproj @@ -0,0 +1,135 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {793B6174-89B0-4682-A957-A32BE7F61502} + Proto_MetaContacts + + + + DynamicLibrary + true + Unicode + v110_xp + + + DynamicLibrary + true + Unicode + v110_xp + + + DynamicLibrary + false + Unicode + v110_xp + + + DynamicLibrary + false + Unicode + v110_xp + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\Icons\ + $(SolutionDir)$(Configuration)64\Icons\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)\Icons\ + $(SolutionDir)$(Configuration)64\Icons\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + true + + + + Windows + true + false + $(SolutionDir)\lib + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\..\include\msapi + + + + + Windows + true + false + $(SolutionDir)\lib + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\..\include\msapi + + + + + Windows + true + false + $(SolutionDir)\lib + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\..\include\msapi + + + + + Windows + true + false + $(SolutionDir)\lib + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\..\include\msapi + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_11.vcxproj.filters b/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_11.vcxproj.filters new file mode 100644 index 0000000000..af73080618 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_11.vcxproj.filters @@ -0,0 +1,23 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_12.vcxproj b/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_12.vcxproj new file mode 100644 index 0000000000..e2b2d3752a --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_12.vcxproj @@ -0,0 +1,135 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {793B6174-89B0-4682-A957-A32BE7F61502} + Proto_MetaContacts + + + + DynamicLibrary + true + Unicode + v120_xp + + + DynamicLibrary + true + Unicode + v120_xp + + + DynamicLibrary + false + Unicode + v120_xp + + + DynamicLibrary + false + Unicode + v120_xp + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\Icons\ + $(SolutionDir)$(Configuration)64\Icons\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)\Icons\ + $(SolutionDir)$(Configuration)64\Icons\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + true + + + + Windows + true + false + $(SolutionDir)\lib + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\..\include\msapi + + + + + Windows + true + false + $(SolutionDir)\lib + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\..\include\msapi + + + + + Windows + true + false + $(SolutionDir)\lib + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\..\include\msapi + + + + + Windows + true + false + $(SolutionDir)\lib + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\..\include\msapi + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_12.vcxproj.filters b/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_12.vcxproj.filters new file mode 100644 index 0000000000..af73080618 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/proto_metacontacts/Proto_MetaContacts_12.vcxproj.filters @@ -0,0 +1,23 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Away.ico b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Away.ico new file mode 100644 index 0000000000..ec58bf2369 Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Away.ico differ diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/DND.ico b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/DND.ico new file mode 100644 index 0000000000..0f3c019483 Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/DND.ico differ diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/FFC.ico b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/FFC.ico new file mode 100644 index 0000000000..dbe9292758 Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/FFC.ico differ diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Invisible.ico b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Invisible.ico new file mode 100644 index 0000000000..e32aa49672 Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Invisible.ico differ diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Lunch.ico b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Lunch.ico new file mode 100644 index 0000000000..347b03474d Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Lunch.ico differ diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/NA.ico b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/NA.ico new file mode 100644 index 0000000000..e5e28a5b78 Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/NA.ico differ diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Occupied.ico b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Occupied.ico new file mode 100644 index 0000000000..585d356f01 Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Occupied.ico differ diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Offline.ico b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Offline.ico new file mode 100644 index 0000000000..64a5750fbc Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Offline.ico differ diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Online.ico b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Online.ico new file mode 100644 index 0000000000..2e1fdcdf78 Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Online.ico differ diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Phone.ico b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Phone.ico new file mode 100644 index 0000000000..899a340ec9 Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Phone.ico differ diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Proto_MetaContacts.rc b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Proto_MetaContacts.rc new file mode 100644 index 0000000000..26065a3aec Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/proto_metacontacts/res/Proto_MetaContacts.rc differ diff --git a/plugins/!Deprecated/MetaContacts/proto_metacontacts/src/resource.h b/plugins/!Deprecated/MetaContacts/proto_metacontacts/src/resource.h new file mode 100644 index 0000000000..6a73a87039 Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/proto_metacontacts/src/resource.h differ diff --git a/plugins/!Deprecated/MetaContacts/res/MetaContacts.rc b/plugins/!Deprecated/MetaContacts/res/MetaContacts.rc new file mode 100644 index 0000000000..836d0c8f05 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/res/MetaContacts.rc @@ -0,0 +1,263 @@ +// Microsoft Visual C++ generated resource script. +// +#include "..\src\resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral (Default) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUD) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_DEFAULT +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_METASELECT, DIALOG + BEGIN + LEFTMARGIN, 3 + RIGHTMARGIN, 252 + TOPMARGIN, 4 + BOTTOMMARGIN, 252 + END + + IDD_METAEDIT, DIALOG + BEGIN + LEFTMARGIN, 5 + RIGHTMARGIN, 378 + TOPMARGIN, 4 + BOTTOMMARGIN, 255 + END + + IDD_OPTIONS, DIALOG + BEGIN + VERTGUIDE, 4 + VERTGUIDE, 9 + VERTGUIDE, 137 + VERTGUIDE, 173 + HORZGUIDE, 74 + END + + IDD_COPYPROGRESS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 83 + END + + IDD_DELPROGRESS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 83 + END + + IDD_PRIORITIES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 259 + TOPMARGIN, 7 + BOTTOMMARGIN, 150 + END + + IDD_HISTORY, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 280 + TOPMARGIN, 7 + BOTTOMMARGIN, 102 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_METASELECT DIALOGEX 0, 0, 256, 259 +STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Add to Existing MetaContact" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CTEXT "Please select a MetaContact:",IDC_STATIC,27,11,201,14 + DEFPUSHBUTTON "&OK",IDOK,73,238,48,14 + PUSHBUTTON "&Cancel",IDCANCEL,133,238,48,14 + LISTBOX IDC_METALIST,44,28,168,168,LBS_NOINTEGRALHEIGHT | WS_VSCROLL + CONTROL "Sort Alphabetically",IDC_CHK_SRT,"Button",BS_AUTOCHECKBOX | BS_VCENTER | WS_TABSTOP,78,210,124,13 +END + +IDD_METAEDIT DIALOGEX 0, 0, 383, 260 +STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_STATICEDGE +CAPTION "Editing" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + DEFPUSHBUTTON "&OK",IDOK,106,241,50,14 + PUSHBUTTON "&Cancel",IDCANCEL,166,241,50,14 + LTEXT "Name:",IDC_STATIC,108,26,42,8 + GROUPBOX "Information",IDC_STATIC,5,4,373,45 + GROUPBOX "Contacts",IDC_FRAME,5,54,373,180 + PUSHBUTTON "&Apply",IDC_VALIDATE,226,241,50,14 + DEFPUSHBUTTON "&Remove",IDC_BTN_REM,53,181,50,14 + PUSHBUTTON "&Set as Default",IDC_BTN_SETDEFAULT,107,181,50,14 + PUSHBUTTON "Move &Up",IDC_BTN_UP,224,181,50,14 + PUSHBUTTON "Move &Down",IDC_BTN_DOWN,279,181,50,14 + EDITTEXT IDC_ED_NAME,158,23,135,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP + CONTROL "List1",IDC_LST_CONTACTS,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,53,79,276,89,WS_EX_CLIENTEDGE + GROUPBOX "",IDC_STATIC,35,66,313,138 + CONTROL "Force use of default for sending (even if offline)",IDC_CHK_FORCEDEFAULT,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,110,215,209,10 + PUSHBUTTON "Send &Offline",IDC_BTN_SETOFFLINE,161,181,50,14 +END + +IDD_OPTIONS DIALOGEX 0, 0, 298, 178 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + CONTROL "Set default contact on receipt of message",IDC_CHK_SETDEFAULTRECV,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,9,290,10 + CONTROL "Always send to default contact if not offline",IDC_CHK_ALWAYSUSEDEFAULT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,31,290,10 + GROUPBOX "Options",IDC_STATIC,0,0,297,178 + CONTROL "Suppress status notification for subcontacts",IDC_CHK_SUPPRESSSTATUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,42,290,10 + GROUPBOX "Context Menu",IDC_STATIC,4,79,289,58 + CONTROL "Use contact's unique ID",IDC_RAD_UID,"Button",BS_AUTORADIOBUTTON | WS_GROUP,13,100,112,10 + CONTROL "Use contact's display name",IDC_RAD_DID,"Button",BS_AUTORADIOBUTTON | WS_GROUP,13,114,112,10 + GROUPBOX "Contact Labels",IDC_STATIC,9,87,120,45,WS_GROUP + GROUPBOX "Function",IDC_STATIC,133,87,155,45,WS_GROUP + CONTROL "Set default and open message window",IDC_RAD_MSG,"Button",BS_AUTORADIOBUTTON | WS_GROUP,137,98,148,10 + CONTROL "Show subcontact context menu",IDC_RAD_MENU,"Button",BS_AUTORADIOBUTTON | WS_GROUP,137,108,148,10 + CONTROL "Show user information",IDC_RAD_INFO,"Button",BS_AUTORADIOBUTTON | WS_GROUP,137,118,148,10 + GROUPBOX "Contact List",IDC_STATIC,4,139,289,33,WS_GROUP + CONTROL "Display subcontact nickname",IDC_RAD_NICK,"Button",BS_AUTORADIOBUTTON | WS_GROUP,9,149,144,10 + CONTROL "Display subcontact display name",IDC_RAD_NAME,"Button",BS_AUTORADIOBUTTON | WS_GROUP,9,160,144,10 + CONTROL "Use subcontact message windows",IDC_CHK_SUBWINDOW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,64,155,10 + CONTROL "Copy subcontact data",IDC_CHK_COPYDATA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,162,64,133,10 + CONTROL "Lock name to first contact",IDC_CHK_LOCKHANDLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,155,115,10 + CONTROL "but only for the current conversation",IDC_CHK_TEMPDEFAULT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,20,260,10 +END + +IDD_COPYPROGRESS DIALOG 0, 0, 186, 90 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION +CAPTION "History Copy" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Progress1",IDC_PROG,"msctls_progress32",0x0,28,49,130,13 + CTEXT "Please wait while the contact's history is copied.",IDC_STATIC,3,27,182,8 +END + +IDD_DELPROGRESS DIALOG 0, 0, 186, 90 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION +CAPTION "History Remove" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Progress1",IDC_PROG,"msctls_progress32",0x0,28,49,130,13 + CTEXT "Please wait while the contact's history is removed.",IDC_STATIC,3,27,182,8 +END + +IDD_PRIORITIES DIALOGEX 0, 0, 266, 157 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Subcontact Priorities",IDC_STATIC,7,7,252,143 + EDITTEXT IDC_ED_PRIORITY,157,78,40,14,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SP_PRIORITY,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,195,78,11,14 + RTEXT "Rank:",IDC_STATIC,42,81,49,8 + RTEXT "Status:",IDC_STATIC,30,57,61,8 + COMBOBOX IDC_CMB_STATUS,98,53,112,87,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + RTEXT "Protocol:",IDC_STATIC,30,31,61,8 + COMBOBOX IDC_CMB_PROTOCOL,98,28,112,112,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Reset All",IDC_BTN_RESET,87,119,91,14 + CONTROL "Default",IDC_CHK_DEFAULT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,97,81,58,10 + CTEXT "(Lower ranks are preferred)",IDC_STATIC,51,99,162,8 +END + +IDD_HISTORY DIALOGEX 0, 0, 287, 109 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "Copy subcontact history to MetaContact when creating or adding",IDC_CHK_COPYHISTORY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,23,258,10 + RTEXT "Number of days to copy (0=all):",IDC_STATIC,13,37,125,8 + EDITTEXT IDC_ED_DAYS,158,35,31,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER + CONTROL "Keep MetaContact history synchronized with subcontacts",IDC_CHK_METAHISTORY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,60,258,10 + CONTROL "Keep subcontact history synchronized with MetaContact",IDC_CHK_SUBHISTORY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,78,258,10 + GROUPBOX "History (** beware - change at your own risk **)",IDC_STATIC,7,7,273,95,WS_GROUP +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "..\\src\\resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_MCMENU ICON "mcmenu.ico" +IDI_MCMENUOFF ICON "mcmenuof.ico" +IDI_MCEDIT ICON "meta_edit.ico" +IDI_MCREMOVE ICON "meta_remove2.ico" +IDI_MCCONVERT ICON "meta_convert.ico" +IDI_MCADD ICON "meta_add.ico" +IDI_MCSETDEFAULT ICON "meta_set_as_default.ico" +#endif // Neutral (Default) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/!Deprecated/MetaContacts/res/mcmenu.ico b/plugins/!Deprecated/MetaContacts/res/mcmenu.ico new file mode 100644 index 0000000000..2e1fdcdf78 Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/res/mcmenu.ico differ diff --git a/plugins/!Deprecated/MetaContacts/res/mcmenuof.ico b/plugins/!Deprecated/MetaContacts/res/mcmenuof.ico new file mode 100644 index 0000000000..779fe3db15 Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/res/mcmenuof.ico differ diff --git a/plugins/!Deprecated/MetaContacts/res/meta_add.ico b/plugins/!Deprecated/MetaContacts/res/meta_add.ico new file mode 100644 index 0000000000..814383341c Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/res/meta_add.ico differ diff --git a/plugins/!Deprecated/MetaContacts/res/meta_convert.ico b/plugins/!Deprecated/MetaContacts/res/meta_convert.ico new file mode 100644 index 0000000000..51417bdb8c Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/res/meta_convert.ico differ diff --git a/plugins/!Deprecated/MetaContacts/res/meta_edit.ico b/plugins/!Deprecated/MetaContacts/res/meta_edit.ico new file mode 100644 index 0000000000..9696507f31 Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/res/meta_edit.ico differ diff --git a/plugins/!Deprecated/MetaContacts/res/meta_remove2.ico b/plugins/!Deprecated/MetaContacts/res/meta_remove2.ico new file mode 100644 index 0000000000..c05c19eb8f Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/res/meta_remove2.ico differ diff --git a/plugins/!Deprecated/MetaContacts/res/meta_set_as_default.ico b/plugins/!Deprecated/MetaContacts/res/meta_set_as_default.ico new file mode 100644 index 0000000000..e880efd0d1 Binary files /dev/null and b/plugins/!Deprecated/MetaContacts/res/meta_set_as_default.ico differ diff --git a/plugins/!Deprecated/MetaContacts/res/version.rc b/plugins/!Deprecated/MetaContacts/res/version.rc new file mode 100644 index 0000000000..5bfbab4754 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/res/version.rc @@ -0,0 +1,38 @@ +// Microsoft Visual C++ generated resource script. +// +#ifdef APSTUDIO_INVOKED +#error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + +#include "afxres.h" +#include "..\src\version.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION __FILEVERSION_STRING + PRODUCTVERSION __FILEVERSION_STRING + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "FileDescription", __DESCRIPTION + VALUE "InternalName", __PLUGIN_NAME + VALUE "LegalCopyright", __COPYRIGHT + VALUE "OriginalFilename", __FILENAME + VALUE "ProductName", __PLUGIN_NAME + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/plugins/!Deprecated/MetaContacts/src/addto.cpp b/plugins/!Deprecated/MetaContacts/src/addto.cpp new file mode 100644 index 0000000000..a97461eb4a --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/src/addto.cpp @@ -0,0 +1,211 @@ +/* +MetaContacts Plugin for Miranda IM. + +Copyright © 2004 Universite Louis PASTEUR, STRASBOURG. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/** @file addto.c +* +* Functions for the 'Add To' Dialog. +* Contains all the functions and all the structures +* needed to display and control the 'Add To' Dialog. +*/ +#include "metacontacts.h" + +//! Holds information about a contact. +typedef struct { + char *name; //!< Name of the contact + char *proto; //!< Protocol under which the contact has been registered + HANDLE hUser; //!< Identifier of the contact in the DB. +}USERINFO; + +//! Holds information for the callback function. +typedef struct { + USERINFO uInfo; //!< Information about the contact to add +}ADDTO_INFO; + +/** Adds all the metacontacts desired in the listview. +* +* Adds all the metacontacts present in the database in the list, +* +* @param list : \c HANDLE to the list which will contain the columns. +* @param nb_contacts : Number of loaded contacts. +* @param contacts : A list of the contacts' identifiers +* +* @param id : Reference to a list of the MetaContacts IDs loaded in the listview. +* Since this list is resized, its address must be passed. +* +* @return An integer specifying the number of rows added in the list. +*/ +int FillList(HWND list, BOOL sort) +{ + int i=0; + + // The DB is searched through, to get all the metacontacts + for (MCONTACT hMetaUser = db_find_first(); hMetaUser; hMetaUser = db_find_next(hMetaUser)) { + // if it's not a MetaContact, go to the next + if ( db_get_dw(hMetaUser, META_PROTO, META_ID, (DWORD)-1) == (DWORD)-1) + continue; + + // get contact display name from clist + TCHAR *swzContactDisplayName = pcli->pfnGetContactDisplayName(hMetaUser, GCDNF_TCHAR); + // don't insert huge strings that we have to compare with later + if (_tcslen(swzContactDisplayName) > 1023) + swzContactDisplayName[1024] = 0; + + int pos = -1; + if (sort) { + for (pos = 0; pos < i; pos++) { + TCHAR buff[1024]; + SendMessage(list, LB_GETTEXT, pos, (LPARAM)buff); + if ( _tcscmp(buff, swzContactDisplayName) > 0) { + break; + } + } + } + + int index = SendMessage(list, LB_INSERTSTRING, (WPARAM)pos, (LPARAM)swzContactDisplayName); + SendMessage(list, LB_SETITEMDATA, index, (LPARAM)hMetaUser); + + i++; + } + return i; +} + +/** Build or update the list. +* +* @param list : \c HANDLE to the list which will contain the columns +* @param id : Reference to a list that will contain all the MetaContacts IDs loaded in the listview +* otherwise the list is only refilled \n (Warning : this value must be +* set to \c TRUE only once per Dialog display, otherwise all columns will be doubled) +* +* @returns An integer specifying the number of rows inserted or \c -1 if there was a problem +*/ + +int BuildList(HWND list, BOOL sort) +{ + SendMessage(list, LB_RESETCONTENT, 0, 0); + return FillList(list, sort); +} + +/** Callback function for the 'Add To' Dialog. +* +* All the UI is controlled here, from display to functionnalities. +* +* @param hwndDlg : \c HANDLE to the 'Add To' \c Dialog. +* @param uMsg : Specifies the message received by this dialog. +* @param wParam : Specifies additional message-specific information. +* @param lParam : Specifies additional message-specific information. +* +* @return \c TRUE if the dialog processed the message, \c FALSE if it did not. +*/ + +#define szConvMsg LPGEN("Either there is no MetaContact in the database (in this case you should first convert a contact into one)\n\ +or there is none that can host this contact.\n\ +Another solution could be to convert this contact into a new MetaContact.\n\nConvert this contact into a new MetaContact?") + +INT_PTR CALLBACK Meta_SelectDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + + if ( db_get_dw(lParam, META_PROTO, META_ID, (DWORD)-1) != (DWORD)-1) { + MessageBox(hwndDlg, + TranslateT("This contact is a MetaContact.\nYou can't add a MetaContact to another MetaContact.\n\nPlease choose another."), + TranslateT("MetaContact Conflict"),MB_ICONERROR); + DestroyWindow(hwndDlg); + return TRUE; + } + + if ( db_get_dw(lParam, META_PROTO, META_LINK, (DWORD)-1) != (DWORD)-1) { + MessageBox(hwndDlg, + TranslateT("This contact is already associated to a MetaContact.\nYou cannot add a contact to multiple MetaContacts."), + TranslateT("Multiple MetaContacts"),MB_ICONERROR); + DestroyWindow(hwndDlg); + return TRUE; + } + + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); // user data is contact handle + + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIconEx(I_ADD)); + + // Initialize the graphical part + CheckDlgButton(hwndDlg, IDC_ONLYAVAIL, BST_CHECKED); // Initially checked; display all metacontacts is only an option + // Besides, we can check if there is at least one metacontact to add the contact to. + if ( BuildList(GetDlgItem(hwndDlg, IDC_METALIST), FALSE) <= 0) { + if ( MessageBox(hwndDlg, TranslateT(szConvMsg), TranslateT("No suitable MetaContact found"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1) == IDYES) + Meta_Convert((WPARAM)lParam,0); + DestroyWindow(hwndDlg); + return TRUE; + } + else { + // get contact display name from clist + TCHAR *ptszCDN = pcli->pfnGetContactDisplayName(lParam, GCDNF_TCHAR); + if (!ptszCDN) + ptszCDN = TranslateT("a contact"); + + // ... and set it to the Window title. + TCHAR buf[256]; + mir_sntprintf(buf, SIZEOF(buf), TranslateT("Adding %s..."), ptszCDN); + SetWindowText(hwndDlg, buf); + } + ShowWindow(hwndDlg,SW_SHOWNORMAL); + return TRUE; + + case WM_COMMAND: + if (HIWORD(wParam)!=BN_CLICKED) + break; // Only clicks of buttons are relevant, let other COMMANDs through + + switch(LOWORD(wParam)) { + case IDOK: + { + int item = SendMessage(GetDlgItem(hwndDlg, IDC_METALIST),LB_GETCURSEL, 0, 0); // Get the index of the selected metacontact + if (item == -1) + return IDOK == MessageBox(hwndDlg, TranslateT("Please select a MetaContact"), TranslateT("No MetaContact selected"), MB_ICONHAND); + + MCONTACT hContact = (MCONTACT)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + MCONTACT hMeta = (MCONTACT)SendMessage(GetDlgItem(hwndDlg, IDC_METALIST), LB_GETITEMDATA, (WPARAM)item, 0); + if (!Meta_Assign(hContact, hMeta, FALSE)) + MessageBox(hwndDlg, TranslateT("Assignment to the MetaContact failed."), TranslateT("Assignment failure"),MB_ICONERROR); + } + case IDCANCEL: + DestroyWindow(hwndDlg); + break; + + case IDC_CHK_SRT: + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_METALIST), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_METALIST), GWL_STYLE) ^ LBS_SORT); + if (BuildList(GetDlgItem(hwndDlg,IDC_METALIST), IsDlgButtonChecked(hwndDlg, IDC_CHK_SRT) ? TRUE : FALSE) <= 0) { + if (MessageBox(hwndDlg, TranslateT(szConvMsg), TranslateT("No suitable MetaContact found"),MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON1) == IDYES) + Meta_Convert((WPARAM)lParam, 0); + DestroyWindow(hwndDlg); + return TRUE; + } + break; + } + break; + + case WM_DESTROY: + // Free all allocated memory and return the focus to the CList + HWND clist = GetParent(hwndDlg); + Skin_ReleaseIcon((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, 0)); + EndDialog(hwndDlg,TRUE); + SetFocus(clist); + return TRUE; + } + return FALSE; // All other Message are not handled +} diff --git a/plugins/!Deprecated/MetaContacts/src/edit.cpp b/plugins/!Deprecated/MetaContacts/src/edit.cpp new file mode 100644 index 0000000000..7a1a2cc303 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/src/edit.cpp @@ -0,0 +1,465 @@ +/* +MetaContacts Plugin for Miranda IM. + +Copyright © 2004 Universite Louis PASTEUR, STRASBOURG. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/** @file edit.c +* +* Functions for the 'Edit' Dialog. +* Contains all the functions and all the structures +* needed to display and control the 'Edit' Dialog. +*/ + +#include "metacontacts.h" + +//! Holds the differents changes that have to made +typedef struct tag_CHANGES { + MCONTACT hMeta; //!< \c HANDLE of the MetaContact that is edited. + MCONTACT hDefaultContact; //!< \c HANDLE of the new default contact + MCONTACT hOfflineContact; + int num_deleted, //!< \c DWORD number of deleted contacts + num_contacts; //!< \c DWORD number of contacts + MCONTACT hDeletedContacts[MAX_CONTACTS]; //!< \c HANDLEs of the subcontacts to be removed from this metacontact + MCONTACT hContact[MAX_CONTACTS]; //!< \c HANDLEs of the subcontacts, in the order they should be in + int force_default; +} CHANGES; + +CHANGES changes; //!< \c global CHANGES structure + +/** Fills the list of contacts +* +* @param chg : Structure holding all the change info (See CHANGES). +*/ + +void FillContactList(HWND hWndDlg, CHANGES *chg) +{ + HWND hList = GetDlgItem(hWndDlg, IDC_LST_CONTACTS); + TCHAR buff[256]; + + SendMessage(hList, LVM_DELETEALLITEMS, 0, 0); + + LVITEM LvItem = { 0 }; + LvItem.mask = LVIF_TEXT; // Text Style + LvItem.cchTextMax = 256; // Max size of test + + for (int i = 0; i < chg->num_contacts; i++) { + LvItem.iItem = i; + + TCHAR *ptszCDN = pcli->pfnGetContactDisplayName(chg->hContact[i], GCDNF_TCHAR); + if (ptszCDN == NULL) + ptszCDN = TranslateT("(Unknown Contact)"); + + LvItem.iSubItem = 0; // clist display name + LvItem.pszText = ptszCDN; + ListView_InsertItem(hList, &LvItem); + + LvItem.iSubItem = 1; // id + char *szProto = GetContactProto(chg->hContact[i]); + if (szProto) { + char *szField = (char *)CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); + + DBVARIANT dbv; + if ( !db_get(chg->hContact[i], szProto, szField, &dbv)) { + switch(dbv.type) { + case DBVT_ASCIIZ: + _tcsncpy(buff, _A2T(dbv.pszVal), SIZEOF(buff)); + break; + case DBVT_WCHAR: + _tcsncpy(buff, dbv.ptszVal, SIZEOF(buff)); + break; + case DBVT_BYTE: + _itot(dbv.bVal, buff, 10); + break; + case DBVT_WORD: + _itot(dbv.wVal, buff, 10); + break; + case DBVT_DWORD: + _itot(dbv.dVal, buff, 10); + break; + default: + buff[0] = 0; + } + db_free(&dbv); + } + else buff[0] = 0; + + LvItem.pszText = buff; + SendMessage(hList,LVM_SETITEM,0,(LPARAM)&LvItem); // Enter text to SubItems + + LvItem.iSubItem = 2; // protocol + _tcsncpy(buff, _A2T(szProto), SIZEOF(buff)); + ListView_SetItem(hList, &LvItem); + } + else { + LvItem.pszText = _T("Unknown"); + ListView_SetItem(hList, &LvItem); + + LvItem.iSubItem = 2; // protocol + ListView_SetItem(hList, &LvItem); + } + LvItem.iSubItem = 3; // Default (Yes/No) + LvItem.pszText = (chg->hContact[i] == chg->hDefaultContact ? TranslateT("Yes") : TranslateT("No")); + ListView_SetItem(hList, &LvItem); + + LvItem.iSubItem = 4; // Offline (Yes/No) + LvItem.pszText = (chg->hContact[i] == chg->hOfflineContact ? TranslateT("Yes") : TranslateT("No")); + ListView_SetItem(hList, &LvItem); + } +} + +void SetListSelection(HWND hList, int sel) +{ + ListView_SetItemState(hList, sel, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); +} + +/** Scans the \c CHANGES and call the appropriate function for each change. +* +* @param chg : Structure holding all the change info (See CHANGES). +*/ + +void ApplyChanges(CHANGES *chg) +{ + int i; + + // remove removed contacts + for (i = 0; i < chg->num_deleted; i++) { + Meta_Delete((WPARAM)chg->hDeletedContacts[i], 0); + if (chg->hDeletedContacts[i] == chg->hDefaultContact) + chg->hDefaultContact = 0; + if (chg->hDeletedContacts[i] == chg->hOfflineContact) + chg->hOfflineContact = 0; + } + + // set contact positions + for (i = 0; i < chg->num_contacts; i++) { + if (Meta_GetContactNumber(chg->hContact[i]) != i) + Meta_SwapContacts(chg->hMeta, Meta_GetContactNumber(chg->hContact[i]), i); + } + + NotifyEventHooks(hSubcontactsChanged, (WPARAM)chg->hMeta, (LPARAM)chg->hDefaultContact); + + // set default + if (chg->hDefaultContact) + db_set_dw(chg->hMeta, META_PROTO, "Default", Meta_GetContactNumber(chg->hDefaultContact)); + else + db_set_dw(chg->hMeta, META_PROTO, "Default", 0); + NotifyEventHooks(hEventDefaultChanged, (WPARAM)chg->hMeta, (LPARAM)chg->hDefaultContact); + + // set offline + if (chg->hOfflineContact) + db_set_dw(chg->hMeta, META_PROTO, "OfflineSend", Meta_GetContactNumber(chg->hOfflineContact)); + else + db_set_dw(chg->hMeta, META_PROTO, "OfflineSend", (DWORD)-1); + + // fix nick + MCONTACT most_online = Meta_GetMostOnline(chg->hMeta); + Meta_CopyContactNick(chg->hMeta, most_online); + + // fix status + Meta_FixStatus(chg->hMeta); + + // fix avatar + most_online = Meta_GetMostOnlineSupporting(chg->hMeta, PFLAGNUM_4, PF4_AVATARS); + if (most_online) { + PROTO_AVATAR_INFORMATIONT AI; + + AI.cbSize = sizeof(AI); + AI.hContact = chg->hMeta; + AI.format = PA_FORMAT_UNKNOWN; + _tcscpy(AI.filename, _T("X")); + + if ((int)CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) + db_set_ts(chg->hMeta, "ContactPhoto", "File",AI.filename); + } + + if (MetaAPI_GetForceState((WPARAM)chg->hMeta, 0) != chg->force_default) + MetaAPI_ForceDefault((WPARAM)chg->hMeta, 0); +} + +LRESULT ProcessCustomDraw (LPARAM lParam) +{ + LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam; + switch(lplvcd->nmcd.dwDrawStage) { + case CDDS_PREPAINT : //Before the paint cycle begins + //request notifications for individual listview items + return CDRF_NOTIFYITEMDRAW; + + case CDDS_ITEMPREPAINT: //Before an item is drawn + if (changes.hContact[(int)lplvcd->nmcd.dwItemSpec] == changes.hDefaultContact) { + lplvcd->clrText = RGB(255, 0, 0); + } + return CDRF_NEWFONT; + } + + return 0; +} + +/** Callback function for the 'Edit' Dialog. +* +* All the UI is controlled here, from display to functionnalities. +* +* @param hwndDlg : \c HANDLE to the 'Edit' \c Dialog. +* @param uMsg : Specifies the message received by this dialog. +* @param wParam : Specifies additional message-specific information. +* @param lParam : Specifies additional message-specific information (handle of MetaContact to edit) +* +* @return \c TRUE if the dialog processed the message, \c FALSE if it did not. +*/ + +#define WMU_SETTITLE (WM_USER + 1) + +INT_PTR CALLBACK Meta_EditDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND hwnd; + int sel, i; + + switch(msg) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIconEx(I_EDIT)); + { + // Disable the 'Apply' button. + EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),FALSE); + + hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); + ListView_SetExtendedListViewStyle(hwnd, LVS_EX_FULLROWSELECT); + + // Create list columns + LVCOLUMN LvCol = { 0 }; + LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + + LvCol.pszText = TranslateT("Contact"); + LvCol.cx = 100; + ListView_InsertColumn(hwnd, 0, &LvCol); + + LvCol.pszText = TranslateT("ID"); + LvCol.cx = 130; + ListView_InsertColumn(hwnd, 1, &LvCol); + + LvCol.pszText = TranslateT("Protocol"); + LvCol.cx = 100; + ListView_InsertColumn(hwnd, 2, &LvCol); + + LvCol.pszText = TranslateT("Default"); + LvCol.cx = 60; + ListView_InsertColumn(hwnd, 3, &LvCol); + + LvCol.pszText = TranslateT("Send Offline"); + LvCol.cx = 85; + ListView_InsertColumn(hwnd, 4, &LvCol); + + // disable buttons until a selection is made in the list + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_REM), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_SETDEFAULT), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_SETOFFLINE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UP), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_DOWN), FALSE); + + int nb_contacts = db_get_dw(lParam, META_PROTO, "NumContacts", 0); + int default_contact_number = db_get_dw(lParam, META_PROTO, "Default", (DWORD)-1); + int offline_contact_number = db_get_dw(lParam, META_PROTO, "OfflineSend", (DWORD)-1); + + changes.hMeta = lParam; + changes.num_contacts = nb_contacts; + changes.num_deleted = 0; + changes.hDefaultContact = Meta_GetContactHandle(lParam, default_contact_number); + changes.hOfflineContact = Meta_GetContactHandle(lParam, offline_contact_number); + for (i = 0; i < nb_contacts; i++) + changes.hContact[i] = Meta_GetContactHandle(lParam, i); + changes.force_default = MetaAPI_GetForceState((WPARAM)lParam, 0); + + SendMessage(hwndDlg, WMU_SETTITLE, 0, lParam); + + CheckDlgButton(hwndDlg, IDC_CHK_FORCEDEFAULT, changes.force_default); + + FillContactList(hwndDlg, &changes); + } + return TRUE; + + case WMU_SETTITLE: + { + TCHAR *ptszCDN = pcli->pfnGetContactDisplayName(lParam, GCDNF_TCHAR); + if (ptszCDN == NULL) + ptszCDN = TranslateT("(Unknown Contact)"); + + SetWindowText(GetDlgItem(hwndDlg, IDC_ED_NAME), ptszCDN); + } + return TRUE; + + case WM_NOTIFY: // the message that is being sent always + switch(LOWORD(wParam)) { // hit control + case IDC_LST_CONTACTS: // did we hit our ListView contorl? + if (((LPNMHDR)lParam)->code == NM_CLICK) { + sel = ListView_GetNextItem(GetDlgItem(hwndDlg, IDC_LST_CONTACTS), -1, LVNI_FOCUSED|LVNI_SELECTED); // return item selected + + // enable buttons + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_REM), sel != -1); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_SETDEFAULT), sel != -1 && changes.hContact[sel] != changes.hDefaultContact); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_SETOFFLINE), sel != -1 && changes.hContact[sel] != changes.hOfflineContact); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UP), sel > 0); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_DOWN), (sel != -1 && sel < changes.num_contacts - 1)); + } + } + break; + + case WM_COMMAND: + switch(HIWORD(wParam)) { + case BN_CLICKED: // A button ('Remove', 'OK', 'Cancel' or 'Apply', normally) has been clicked + switch(LOWORD(wParam)) { + case IDC_VALIDATE: // Apply changes, if there is still one contact attached to the metacontact. + if (changes.num_contacts == 0) { // Otherwise, delete the metacontact. + if (IDYES == MessageBox(hwndDlg, TranslateT(szDelMsg), TranslateT("Delete MetaContact?"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1)) { + Meta_Delete((WPARAM)changes.hMeta, 0); + DestroyWindow(hwndDlg); + } + return TRUE; + } + ApplyChanges(&changes); + + // Disable the 'Apply' button. + EnableWindow(GetDlgItem(hwndDlg, IDC_VALIDATE), FALSE); + break; + + case IDOK: + if ( IsWindowEnabled(GetDlgItem(hwndDlg, IDC_VALIDATE))) { // If there are changes that could be made, + if (changes.num_contacts == 0) { // do the work that would have be done if the 'Apply' button was clicked. + if (IDYES == MessageBox(hwndDlg, TranslateT(szDelMsg), TranslateT("Delete MetaContact?"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1)) { + Meta_Delete((WPARAM)changes.hMeta,0); + DestroyWindow(hwndDlg); + } + return TRUE; + } + ApplyChanges(&changes); + } + EndDialog(hwndDlg, IDOK); + return TRUE; + + case IDCANCEL: // Simply close the dialog + EndDialog(hwndDlg, IDCANCEL); + return TRUE; + + case IDC_BTN_SETDEFAULT: + hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); + sel = ListView_GetNextItem(hwnd, -1, LVNI_FOCUSED | LVNI_SELECTED); + InvalidateRect(hwnd, 0, TRUE); + changes.hDefaultContact = changes.hContact[sel]; + SendMessage(hwndDlg, WMU_SETTITLE, 0, (LPARAM)changes.hContact[sel]); + + FillContactList(hwndDlg, &changes); + SetListSelection(hwnd, sel); + EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_SETDEFAULT),FALSE); + EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); + return TRUE; + + case IDC_BTN_SETOFFLINE: + hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); + sel = ListView_GetNextItem(hwnd, -1, LVNI_FOCUSED | LVNI_SELECTED); + InvalidateRect(hwnd, 0, TRUE); + changes.hOfflineContact = changes.hContact[sel]; + + FillContactList(hwndDlg, &changes); + SetListSelection(hwnd, sel); + EnableWindow(GetDlgItem(hwndDlg,IDC_BTN_SETOFFLINE),FALSE); + EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); + return TRUE; + + case IDC_BTN_REM: + hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); + sel = ListView_GetNextItem(hwnd, -1, LVNI_FOCUSED | LVNI_SELECTED); + changes.num_contacts--; + changes.hDeletedContacts[changes.num_deleted++] = changes.hContact[sel]; + if (changes.hDefaultContact == changes.hContact[sel]) { + if (changes.num_contacts > 0) { + changes.hDefaultContact = changes.hContact[0]; + SetWindowText(GetDlgItem(hwndDlg,IDC_ED_DEFAULT), pcli->pfnGetContactDisplayName(changes.hDefaultContact, GCDNF_TCHAR)); + } + else { + changes.hDefaultContact = 0; + SetWindowText(GetDlgItem(hwndDlg,IDC_ED_DEFAULT), _T("None")); + } + } + + for (i = sel; i < changes.num_contacts; i++) + changes.hContact[i] = changes.hContact[i + 1]; + FillContactList(hwndDlg, &changes); + + // disable buttons + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_REM), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_SETDEFAULT), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_SETOFFLINE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UP), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_DOWN), FALSE); + + // Enable the 'Apply' button. + EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); + return TRUE; + + case IDC_BTN_UP: + hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); + sel = ListView_GetNextItem(hwnd, -1, LVNI_FOCUSED | LVNI_SELECTED); + { + MCONTACT temp = changes.hContact[sel]; + changes.hContact[sel] = changes.hContact[sel - 1]; + changes.hContact[sel-1] = temp; + } + FillContactList(hwndDlg, &changes); + sel--; + SetListSelection(hwnd, sel); + + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UP), (sel > 0)); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_DOWN), (sel < changes.num_contacts - 1)); + EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); + return TRUE; + + case IDC_BTN_DOWN: + hwnd = GetDlgItem(hwndDlg, IDC_LST_CONTACTS); + sel = ListView_GetNextItem(hwnd, -1, LVNI_FOCUSED | LVNI_SELECTED); + { + MCONTACT temp = changes.hContact[sel]; + changes.hContact[sel] = changes.hContact[sel + 1]; + changes.hContact[sel + 1] = temp; + } + FillContactList(hwndDlg, &changes); + sel++; + SetListSelection(hwnd, sel); + + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_UP), (sel > 0)); + EnableWindow(GetDlgItem(hwndDlg, IDC_BTN_DOWN), (sel < changes.num_contacts - 1)); + EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); + return TRUE; + + case IDC_CHK_FORCEDEFAULT: + changes.force_default = IsDlgButtonChecked(hwndDlg, IDC_CHK_FORCEDEFAULT); + EnableWindow(GetDlgItem(hwndDlg,IDC_VALIDATE),TRUE); + return TRUE; + } + } + break; + + case WM_CLOSE: + DestroyWindow(hwndDlg); + return TRUE; + + case WM_DESTROY: + Skin_ReleaseIcon((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, 0)); + EndDialog(hwndDlg, IDCANCEL); + break; + } + + return FALSE; +} diff --git a/plugins/!Deprecated/MetaContacts/src/icons.cpp b/plugins/!Deprecated/MetaContacts/src/icons.cpp new file mode 100644 index 0000000000..508fe50425 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/src/icons.cpp @@ -0,0 +1,26 @@ +#include "metacontacts.h" + +static IconItem iconList[] = { + { LPGEN("Toggle Off"), "off", IDI_MCMENUOFF }, + { LPGEN("Toggle On"), "on", IDI_MCMENU }, + { LPGEN("Convert to MetaContact"), "convert", IDI_MCCONVERT }, + { LPGEN("Add to Existing"), "add", IDI_MCADD }, + { LPGEN("Edit"), "edit", IDI_MCEDIT }, + { LPGEN("Set to Default"), "default", IDI_MCSETDEFAULT }, + { LPGEN("Remove"), "remove", IDI_MCREMOVE }, +}; + +HANDLE GetIconHandle(IconIndex i) +{ + return iconList[i].hIcolib; +} + +HICON LoadIconEx(IconIndex i) +{ + return Skin_GetIcon(iconList[i].szName); +} + +void InitIcons(void) +{ + Icon_Register(hInstance, META_PROTO, iconList, SIZEOF(iconList), "mc"); +} diff --git a/plugins/!Deprecated/MetaContacts/src/meta_api.cpp b/plugins/!Deprecated/MetaContacts/src/meta_api.cpp new file mode 100644 index 0000000000..600249cefb --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/src/meta_api.cpp @@ -0,0 +1,242 @@ +/* +MetaContacts Plugin for Miranda IM. + +Copyright © 2004 Universite Louis PASTEUR, STRASBOURG. +Copyright © 2004 Scott Ellis (www.scottellis.com.au mail@scottellis.com.au) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/** @file meta_api.c +* +* API functions needed to handle MetaContacts. +* Centralizes functions called by other plugins. +*/ + +#include "metacontacts.h" + +//get the handle for a contact's parent metacontact +//wParam=(HANDLE)hSubContact +//lParam=0 +//returns a handle to the parent metacontact, or null if this contact is not a subcontact +INT_PTR MetaAPI_GetMeta(WPARAM wParam, LPARAM lParam) { + return (INT_PTR)(HANDLE)db_get_dw(wParam, META_PROTO, "Handle", 0); +} + +//gets the handle for the default contact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns a handle to the default contact, or null on failure +INT_PTR MetaAPI_GetDefault(WPARAM wParam, LPARAM lParam) { + DWORD default_contact_number = db_get_dw(wParam, META_PROTO, "Default", -1); + if (default_contact_number != -1) { + return (INT_PTR)Meta_GetContactHandle(wParam, default_contact_number); + } + return 0; +} + +//gets the contact number for the default contact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns a DWORD contact number, or -1 on failure +INT_PTR MetaAPI_GetDefaultNum(WPARAM wParam, LPARAM lParam) { + return db_get_dw(wParam, META_PROTO, "Default", -1); +} + +//gets the handle for the 'most online' contact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns a handle to the 'most online' contact +INT_PTR MetaAPI_GetMostOnline(WPARAM wParam, LPARAM lParam) { + return (INT_PTR)Meta_GetMostOnline(wParam); +} + +//gets the number of subcontacts for a metacontact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns a DWORD representing the number of subcontacts for the given metacontact +INT_PTR MetaAPI_GetNumContacts(WPARAM wParam, LPARAM lParam) { + DWORD num_contacts = db_get_dw(wParam, META_PROTO, "NumContacts", -1); + return num_contacts; +} + +//gets the handle of a subcontact, using the subcontact's number +//wParam=(HANDLE)hMetaContact +//lParam=(DWORD)contact number +//returns a handle to the specified subcontact +INT_PTR MetaAPI_GetContact(WPARAM wParam, LPARAM lParam) { + return (INT_PTR)Meta_GetContactHandle(wParam, (DWORD)lParam); +} + +//sets the default contact, using the subcontact's contact number +//wParam=(HANDLE)hMetaContact +//lParam=(DWORD)contact number +//returns 0 on success +INT_PTR MetaAPI_SetDefaultContactNum(WPARAM wParam, LPARAM lParam) { + DWORD num_contacts = db_get_dw(wParam, META_PROTO, "NumContacts", -1); + if (num_contacts == -1) + return 1; + if ((DWORD)lParam >= num_contacts || (DWORD)lParam < 0) + return 1; + if (db_set_dw(wParam, META_PROTO, "Default", (DWORD)lParam)) + return 1; + + NotifyEventHooks(hEventDefaultChanged, wParam, (LPARAM)Meta_GetContactHandle(wParam, (int)lParam)); + return 0; +} + +//sets the default contact, using the subcontact's handle +//wParam=(HANDLE)hMetaContact +//lParam=(HANDLE)hSubcontact +//returns 0 on success +INT_PTR MetaAPI_SetDefaultContact(WPARAM wParam, LPARAM lParam) { + MCONTACT hMeta = (MCONTACT)db_get_dw(lParam, META_PROTO, "Handle", 0); + DWORD contact_number = Meta_GetContactNumber(lParam); + if (contact_number == -1 || !hMeta || hMeta != wParam) + return 1; + if (db_set_dw(hMeta, META_PROTO, "Default", contact_number)) + return 1; + + NotifyEventHooks(hEventDefaultChanged, wParam, lParam); + return 0; +} + +//forces the metacontact to send using a specific subcontact, using the subcontact's contact number +//wParam=(HANDLE)hMetaContact +//lParam=(DWORD)contact number +//returns 0 on success +INT_PTR MetaAPI_ForceSendContactNum(WPARAM wParam, LPARAM lParam) { + MCONTACT hContact = Meta_GetContactHandle(wParam, (int)lParam); + MCONTACT hMeta = (MCONTACT)db_get_dw(hContact, META_PROTO, "Handle", 0); + if (!hContact || !hMeta || hMeta != wParam || db_get_b(hMeta, META_PROTO, "ForceDefault", 0)) + return 1; + + db_set_dw(hMeta, META_PROTO, "ForceSend", (DWORD)hContact); + + NotifyEventHooks(hEventForceSend, wParam, (LPARAM)hContact); + return 0; +} + +//forces the metacontact to send using a specific subcontact, using the subcontact's handle +//wParam=(HANDLE)hMetaContact +//lParam=(HANDLE)hSubcontact +//returns 0 on success (will fail if 'force default' is in effect) +INT_PTR MetaAPI_ForceSendContact(WPARAM wParam, LPARAM lParam) { + MCONTACT hContact = lParam; + MCONTACT hMeta = (MCONTACT)db_get_dw(hContact, META_PROTO, "Handle", 0); + if (!hContact || !hMeta || hMeta != wParam || db_get_b(hMeta, META_PROTO, "ForceDefault", 0)) + return 1; + + db_set_dw(hMeta, META_PROTO, "ForceSend", (DWORD)hContact); + + NotifyEventHooks(hEventForceSend, wParam, lParam); + return 0; +} + +//'unforces' the metacontact to send using a specific subcontact +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns 0 on success (will fail if 'force default' is in effect) +INT_PTR MetaAPI_UnforceSendContact(WPARAM wParam, LPARAM lParam) { + if (db_get_b(wParam, META_PROTO, "ForceDefault", 0)) + return 1; + + db_set_dw(wParam, META_PROTO, "ForceSend", 0); + + NotifyEventHooks(hEventUnforceSend, wParam, lParam); + return 0; +} + + +//'forces' or 'unforces' (i.e. toggles) the metacontact to send using it's default contact +// overrides 'force send' above, and will even force use of offline contacts +// will send ME_MC_FORCESEND event +//wParam=(HANDLE)hMetaContact +//lParam=0 +//returns 1(true) or 0(false) representing new state of 'force default' +INT_PTR MetaAPI_ForceDefault(WPARAM wParam, LPARAM lParam) { + // forward to menu function + Meta_ForceDefault(wParam, lParam); + return db_get_b(wParam, META_PROTO, "ForceDefault", 0); +} + +// method to get state of 'force' for a metacontact +// wParam=(HANDLE)hMetaContact +// lParam= (DWORD)&contact_number or NULL +// if lparam supplied, the contact_number of the contatct 'in force' will be copied to the address it points to, +// or if none is in force, the value (DWORD)-1 will be copied +// (v0.8.0.8+ returns 1 if 'force default' is true with *lParam == default contact number, else returns 0 with *lParam as above) +INT_PTR MetaAPI_GetForceState(WPARAM wParam, LPARAM lParam) { + MCONTACT hMeta = wParam; + if ( !hMeta) return 0; + + if (db_get_b(hMeta, META_PROTO, "ForceDefault", 0)) { + if (lParam) *(DWORD *)lParam = db_get_dw(wParam, META_PROTO, "Default", -1); + return 1; + } + + MCONTACT hContact = (MCONTACT)db_get_dw(hMeta, META_PROTO, "ForceSend", 0); + if ( !hContact) { + if (lParam) *(DWORD *)lParam = -1; + } else { + if (lParam) *(DWORD *)lParam = (DWORD)Meta_GetContactNumber(hContact); + } + + return 0; +} + +// method to get protocol name - used to be sure you're dealing with a "real" metacontacts plugin :) +// wParam=lParam=0 +INT_PTR MetaAPI_GetProtoName(WPARAM wParam, LPARAM lParam) { + return (INT_PTR)META_PROTO; +} + +// added 0.9.5.0 (22/3/05) +// wParam=(HANDLE)hContact +// lParam=0 +// convert a given contact into a metacontact +INT_PTR MetaAPI_ConvertToMeta(WPARAM wParam, LPARAM lParam) { + return Meta_Convert(wParam, lParam); +} + +// added 0.9.5.0 (22/3/05) +// wParam=(HANDLE)hContact +// lParam=(HANDLE)hMeta +// add an existing contact to a metacontact +INT_PTR MetaAPI_AddToMeta(WPARAM wParam, LPARAM lParam) { + return Meta_Assign(wParam, lParam, FALSE); +} + +// added 0.9.5.0 (22/3/05) +// wParam=0 +// lParam=(HANDLE)hContact +// remove a contact from a metacontact +INT_PTR MetaAPI_RemoveFromMeta(WPARAM wParam, LPARAM lParam) { + // notice we switch args - to keep the API function consistent with the others + return Meta_Delete((WPARAM)lParam, (LPARAM)wParam); +} + +// added 0.9.13.2 (6/10/05) +// wParam=(BOOL)disable +// lParam=0 +// enable/disable the 'hidden group hack' - for clists that support subcontact hiding using 'IsSubcontact' setting +// should be called once in your 'onmodulesloaded' event handler + +BOOL meta_group_hack_disabled = FALSE; // this global flag is used in utils 'SetGroup' function + +INT_PTR MetaAPI_DisableHiddenGroup(WPARAM wParam, LPARAM lParam) { + meta_group_hack_disabled = (BOOL)wParam; + return 0; +} diff --git a/plugins/!Deprecated/MetaContacts/src/meta_main.cpp b/plugins/!Deprecated/MetaContacts/src/meta_main.cpp new file mode 100644 index 0000000000..6f245ff501 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/src/meta_main.cpp @@ -0,0 +1,208 @@ +/* +MetaContacts Plugin for Miranda IM. + +Copyright © 2004 Universite Louis PASTEUR, STRASBOURG. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/** @file meta_main.c +* +* Functions used by Miranda to launch the plugin. +* Centralizes functions needed by Miranda to get +* information about the plugin and to initialize it +* and to dispose of it properly. +*/ + +/*! \mainpage MetaContacts plugin + * \image html ulp.gif + * \section desc Description + * This library is a plugin for Miranda IM.\n + * It allows the user to group several contacts from different + * protocols (such as AIM or ICQ) into one unique metacontact.\n + * + * \section principle How does it work ? + * Only one protocol will be used at a time (the default protocol).\n + * This protocol is referenced in the proper field of the MetaContact + * section in the Database. + * + * \subsection send Emission of messages + * The plugin will search through the Database to get the default protocol + * (i.e. the protocol used to communicate with),\n and then call the Send function + * provided by this protocol. + * + * \subsection recv Reception of messages + * When a contact is converted to a metacontact, or when it is added to an existing + * metacontact, it gets a pseudo protocol \n (named "MetaContacts") in the protocol chain.\n + * Usually, when a message is received, all the protocols in the chain get this message, + * the real protocol (for example ICQ) at the end.\n But here, the message will be intercepted + * by the MetaContact protocol, which will inhibit the further reception.\n The message will + * then be redirected to the MetaContact, that will display it normally. + * + * \subsection handling Handling MetaContacts + * There are four functionnality for handling MetaContacts : + * \li Convert a contact to a MetaContact. + * \li Add a contact to an existing MetaContact. + * \li Edit a MetaContact. + * \li Delete a MetaContact. + * + * They all are accessible via the context-menu displayed when a right click has occured, + * but not at the same time : The 2 first will appear when the menu concerns a simple contact.\n + * whereas the 2 last are only accessible from a MetaContact.\n + * Those functions are self-explanatory, and a MessageBox is shown before any modification, so, for + * further information, take a look at the Dialogs shown when they are called.\n + * + * \section cvats Caveats + * Several functionnalities have not yet been developped : + * \li Assigning contacts by Drag'n'Drop + * \li Updating dynamically the status of the MetaContact + * \li Merging history of all the contacts attached to MetaContact + * \li Handling Files and URLs as well as Messages + * \li and some other little functionnalities... + * + * Some of those functionnalities will not be developped due to the architecture + * of Miranda (the 2 first, for example) + * + * \section mail Contact + * For any comment, suggestion or question, send a mail to shaalj@free.fr.\n + * This code is provided as-is, and I cannot be held responsible for any harm + * done to your database by this plugin.\n + * Test it first on a fake database before using it normally. + */ + +#include "metacontacts.h" + +BOOL os_unicode_enabled = FALSE; +int hLangpack; +CLIST_INTERFACE *pcli = NULL; + +//! Information gathered by Miranda, displayed in the plugin pane of the Option Dialog +PLUGININFOEX pluginInfo={ + sizeof(PLUGININFOEX), + __PLUGIN_NAME, + PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), + __DESCRIPTION, + __AUTHOR, + __AUTHOREMAIL, + __COPYRIGHT, + __AUTHORWEB, + UNICODE_AWARE, + // {4C4A27CF-5E64-4242-A332-B98B08243E89} + {0x4c4a27cf, 0x5e64, 0x4242, {0xa3, 0x32, 0xb9, 0x8b, 0x8, 0x24, 0x3e, 0x89}} +}; + +HINSTANCE hInstance; //!< Global reference to the application + +/** Called by Miranda to get the information associated to this plugin. +* It only returns the PLUGININFO structure, without any test on the version +* @param mirandaVersion The version of the application calling this function +*/ +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_PROTOCOL, MIID_LAST}; + +/** DLL entry point +* Required to store the instance handle +*/ +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + hInstance = hinstDLL; + return TRUE; +} + +/** Prepare the plugin to stop +* Called by Miranda when it will exit or when the plugin gets deselected +*/ +extern "C" __declspec(dllexport) int Unload(void) +{ + // see also meta_services.c, Meta_PreShutdown + Meta_CloseHandles(); + //MessageBox(0, "Unload complete", "MC", MB_OK); + return 0; +} + +/** Initializes the services provided and the link to those needed +* Called when the plugin is loaded into Miranda +*/ +extern "C" __declspec(dllexport) int Load(void) +{ + mir_getLP(&pluginInfo); + mir_getCLI(); + + db_set_resident(META_PROTO, "Status"); + db_set_resident(META_PROTO, "IdleTS"); + db_set_resident(META_PROTO, "ContactCountCheck"); + db_set_resident(META_PROTO, "Handle"); + db_set_resident(META_PROTO, "WindowOpen"); + + //set all contacts to 'offline', and initialize subcontact counter for db consistency check + for (MCONTACT hContact = db_find_first(META_PROTO); hContact; hContact = db_find_next(hContact, META_PROTO)) { + db_set_w(hContact, META_PROTO, "Status", ID_STATUS_OFFLINE); + db_set_dw(hContact, META_PROTO, "IdleTS", 0); + db_set_b(hContact, META_PROTO, "ContactCountCheck", 0); + + // restore any saved defaults that might have remained if miranda was closed or crashed while a convo was happening + if (db_get_dw(hContact, META_PROTO, "SavedDefault", (DWORD)-1) != (DWORD)-1) { + db_set_dw(hContact, META_PROTO, "Default", db_get_dw(hContact, META_PROTO, "SavedDefault", 0)); + db_set_dw(hContact, META_PROTO, "SavedDefault", (DWORD)-1); + } + } + + Meta_ReadOptions(&options); + + // sets subcontact handles to metacontacts, and metacontact handles to subcontacts + // (since these handles are not necessarily the same from run to run of miranda) + + // also verifies that subcontacts: have metacontacts, and that contact numbers are reasonable, + // that metacontacts: have the correct number of subcontacts, and have reasonable defaults + if (Meta_SetHandles()) { + // error - db corruption + if ( !db_get_b(0, META_PROTO, "DisabledMessageShown", 0)) { + MessageBox(0, TranslateT("Error - Database corruption.\nPlugin disabled."), TranslateT("MetaContacts"), MB_OK | MB_ICONERROR); + db_set_b(0, META_PROTO, "DisabledMessageShown", 1); + } + //Meta_HideMetaContacts(TRUE); + return 1; + } + + db_unset(0, META_PROTO, "DisabledMessageShown"); + + PROTOCOLDESCRIPTOR pd = { PROTOCOLDESCRIPTOR_V3_SIZE }; + pd.szName = META_FILTER; + pd.type = PROTOTYPE_FILTER; + CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd); + + pd.szName = META_PROTO; + pd.type = PROTOTYPE_VIRTUAL; + CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd); + + // further db setup done in modules loaded (nick [protocol string required] & clist display name) + + Meta_InitServices(); + + // moved to 'modules loaded' event handler (in meta_services.c) because we need to + // check protocol for jabber hack, and the proto modules must be loaded + //Meta_HideLinkedContactsAndSetHandles(); + + if ( ServiceExists(MS_MSG_GETWINDOWAPI)) + message_window_api_enabled = TRUE; + + // for clist_meta_mw - write hidden group name to DB + db_set_s(0, META_PROTO, "HiddenGroupName", META_HIDDEN_GROUP); + return 0; +} diff --git a/plugins/!Deprecated/MetaContacts/src/meta_menu.cpp b/plugins/!Deprecated/MetaContacts/src/meta_menu.cpp new file mode 100644 index 0000000000..0031b461ed --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/src/meta_menu.cpp @@ -0,0 +1,431 @@ +/* +MetaContacts Plugin for Miranda IM. + +Copyright © 2004 Universite Louis PASTEUR, STRASBOURG. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/** @file meta_menu.c +* +* Functions needed to handle MetaContacts. +* Centralizes functions called when the user chooses +* an option integrated in the context-menu of the \c CList. +*/ + +#include "metacontacts.h" + +/** Convert the contact chosen into a MetaContact. +* +* Create a new MetaContact, remove the selected contact from the \c CList +* and attach it to the MetaContact. +* +* @param wParam : \c HANDLE to the contact that has been chosen. +* @param lParam : Allways set to 0. +*/ + +INT_PTR Meta_Convert(WPARAM wParam, LPARAM lParam) +{ + DBVARIANT dbv; + char *group = 0; + + // Get some information about the selected contact. + if ( !db_get_utf(wParam, "CList", "Group", &dbv)) { + group = _strdup(dbv.pszVal); + db_free(&dbv); + } + + // Create a new metacontact + MCONTACT hMetaContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD,0,0); + if (hMetaContact) { + db_set_dw(hMetaContact, META_PROTO, META_ID,nextMetaID); + db_set_dw(hMetaContact, META_PROTO, "NumContacts",0); + db_set_dw(NULL, META_PROTO, "NextMetaID", ++nextMetaID); + + // Add the MetaContact protocol to the new meta contact + CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hMetaContact, (LPARAM)META_PROTO); + + if (group) + db_set_utf(hMetaContact, "CList", "Group", group); + + // Assign the contact to the MetaContact just created (and make default). + if ( !Meta_Assign(wParam, hMetaContact, TRUE)) { + MessageBox(0, TranslateT("There was a problem in assigning the contact to the MetaContact"), TranslateT("Error"), MB_ICONEXCLAMATION); + CallService(MS_DB_CONTACT_DELETE, (WPARAM)hMetaContact, 0); + return 0; + } + + // hide the contact if clist groups disabled (shouldn't create one anyway since menus disabled) + if ( !Meta_IsEnabled()) + db_set_b(hMetaContact, "CList", "Hidden", 1); + } + + free(group); + return (INT_PTR)hMetaContact; +} + +/** Display the 'Add to' Dialog +* +* Present a dialog in which the user can choose to which MetaContact this +* contact will be added +* +* @param wParam : \c HANDLE to the contact that has been chosen. +* @param lParam : Allways set to 0. +*/ + +INT_PTR Meta_AddTo(WPARAM wParam, LPARAM lParam) +{ + HWND clui = (HWND)CallService(MS_CLUI_GETHWND, 0, 0); + DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_METASELECT), clui, &Meta_SelectDialogProc, (LPARAM)wParam); + return 0; +} + +/** Display the 'Edit' Dialog +* +* Present a dialog in which the user can edit some properties of the MetaContact. +* +* @param wParam : \c HANDLE to the MetaContact to be edited. +* @param lParam : Allways set to 0. +*/ +INT_PTR Meta_Edit(WPARAM wParam,LPARAM lParam) +{ + HWND clui = (HWND)CallService(MS_CLUI_GETHWND, 0, 0); + DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_METAEDIT), clui, Meta_EditDialogProc, (LPARAM)wParam); + return 0; +} + +void Meta_RemoveContactNumber(MCONTACT hMeta, int number) +{ + int num_contacts = db_get_dw(hMeta, META_PROTO, "NumContacts", 0); + int default_contact = db_get_dw(hMeta, META_PROTO, "Default", -1); + if (number < 0 && number >= num_contacts) + return; + + // get the handle + MCONTACT hContact = Meta_GetContactHandle(hMeta, number); + + // make sure this contact thinks it's part of this metacontact + if ((MCONTACT)db_get_dw(hContact, META_PROTO, "Handle", 0) == hMeta) { + // remove link to meta contact + db_unset(hContact, META_PROTO, "IsSubcontact"); + db_unset(hContact, META_PROTO, META_LINK); + db_unset(hContact, META_PROTO, "Handle"); + db_unset(hContact, META_PROTO, "ContactNumber"); + // unhide - must be done after removing link (see meta_services.c:Meta_ChangeStatus) + Meta_RestoreGroup(hContact); + db_unset(hContact, META_PROTO, "OldCListGroup"); + + // stop ignoring, if we were + if (options.suppress_status) + CallService(MS_IGNORE_UNIGNORE, hContact, (WPARAM)IGNOREEVENT_USERONLINE); + } + + // each contact from 'number' upwards will be moved down one + // and the last one will be deleted + for (int i = number + 1; i < num_contacts; i++) + Meta_SwapContacts(hMeta, i, i-1); + + // remove the last one + char buffer[512], idStr[20]; + _itoa(num_contacts-1, idStr, 10); + strcpy(buffer, "Protocol"); strcat(buffer, idStr); + db_unset(hMeta, META_PROTO, buffer); + + strcpy(buffer, "Status"); strcat(buffer, idStr); + db_unset(hMeta, META_PROTO, buffer); + + strcpy(buffer, "Handle"); strcat(buffer, idStr); + db_unset(hMeta, META_PROTO, buffer); + + strcpy(buffer, "StatusString"); strcat(buffer, idStr); + db_unset(hMeta, META_PROTO, buffer); + + strcpy(buffer, "Login"); strcat(buffer, idStr); + db_unset(hMeta, META_PROTO, buffer); + + strcpy(buffer, "Nick"); strcat(buffer, idStr); + db_unset(hMeta, META_PROTO, buffer); + + strcpy(buffer, "CListName"); strcat(buffer, idStr); + db_unset(hMeta, META_PROTO, buffer); + + // if the default contact was equal to or greater than 'number', decrement it (and deal with ends) + if (default_contact >= number) { + default_contact--; + if (default_contact < 0) + default_contact = 0; + + db_set_dw(hMeta, META_PROTO, "Default", (DWORD)default_contact); + NotifyEventHooks(hEventDefaultChanged, (WPARAM)hMeta, (LPARAM)Meta_GetContactHandle(hMeta, default_contact)); + } + num_contacts--; + db_set_dw(hMeta, META_PROTO, "NumContacts", (DWORD)num_contacts); + + // fix nick + hContact = Meta_GetMostOnline(hMeta); + Meta_CopyContactNick(hMeta, hContact); + + // fix status + Meta_FixStatus(hMeta); + + // fix avatar + hContact = Meta_GetMostOnlineSupporting(hMeta, PFLAGNUM_4, PF4_AVATARS); + if (hContact) { + PROTO_AVATAR_INFORMATIONT AI = { sizeof(AI) }; + AI.hContact = hMeta; + AI.format = PA_FORMAT_UNKNOWN; + _tcscpy(AI.filename, _T("X")); + + if ((int)CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) + db_set_ts(hMeta, "ContactPhoto", "File",AI.filename); + } +} + +/** Delete a MetaContact from the database +* +* Delete a MetaContact and remove all the information +* concerning this MetaContact in the contact linked to it. +* +* @param wParam : \c HANDLE to the MetaContact to be deleted, or to the subcontact to be removed from the MetaContact +* @param lParam : \c BOOL flag indicating whether to ask 'are you sure' when deleting a MetaContact +*/ + +INT_PTR Meta_Delete(WPARAM wParam,LPARAM lParam) +{ + DWORD metaID; + + // The wParam is a metacontact + if ((metaID = db_get_dw(wParam, META_PROTO, META_ID, (DWORD)-1)) != (DWORD)-1) { + if ( !lParam) { // check from recursion - see second half of this function + if ( MessageBox((HWND)CallService(MS_CLUI_GETHWND,0,0), + TranslateT("This will remove the MetaContact permanently.\n\nProceed Anyway?"), + TranslateT("Are you sure?"),MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2) != IDYES) + return 0; + } + + for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { + // This contact is assigned to the MetaContact that will be deleted, clear the "MetaContacts" information + if ( db_get_dw(hContact, META_PROTO, META_LINK,(DWORD)-1) == metaID) { + db_unset(hContact, META_PROTO, "IsSubcontact"); + db_unset(hContact, META_PROTO, META_LINK); + db_unset(hContact, META_PROTO, "Handle"); + db_unset(hContact, META_PROTO, "ContactNumber"); + + // unhide - must be done after removing link (see meta_services.c:Meta_ChangeStatus) + Meta_RestoreGroup(hContact); + db_unset(hContact, META_PROTO, "OldCListGroup"); + + // stop ignoring, if we were + if (options.suppress_status) + CallService(MS_IGNORE_UNIGNORE, hContact, (WPARAM)IGNOREEVENT_USERONLINE); + } + } + + NotifyEventHooks(hSubcontactsChanged, (WPARAM)wParam, 0); + CallService(MS_DB_CONTACT_DELETE,wParam,0); + } + else { + MCONTACT hMeta = (MCONTACT)db_get_dw(wParam, META_PROTO, "Handle", 0); + DWORD num_contacts = db_get_dw(hMeta, META_PROTO, "NumContacts", -1); + + if (num_contacts == 1) { + if (IDYES == MessageBox(0, TranslateT(szDelMsg), TranslateT("Delete MetaContact?"), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON1)) + Meta_Delete((WPARAM)hMeta,(LPARAM)1); + + return 0; + } + + Meta_RemoveContactNumber(hMeta, db_get_dw(wParam, META_PROTO, "ContactNumber", -1)); + } + return 0; +} + +/** Set contact as MetaContact default +* +* Set the given contact to be the default one for the metacontact to which it is linked. +* +* @param wParam : \c HANDLE to the MetaContact to be set as default +* @param lParam : \c HWND to the clist window + (This means the function has been called via the contact menu). +*/ +INT_PTR Meta_Default(WPARAM wParam,LPARAM lParam) +{ + MCONTACT hMeta; + + // the wParam is a subcontact + if ((hMeta = (MCONTACT)db_get_dw(wParam, META_PROTO, "Handle",0)) != 0) { + db_set_dw(hMeta, META_PROTO, "Default", (DWORD)Meta_GetContactNumber(wParam)); + NotifyEventHooks(hEventDefaultChanged, (WPARAM)hMeta, (LPARAM)wParam); + } + return 0; +} + +/** Set/unset (i.e. toggle) contact to force use of default contact +* +* Set the given contact to be the default one for the metacontact to which it is linked. +* +* @param wParam : \c HANDLE to the MetaContact to be set as default +* @param lParam : \c HWND to the clist window + (This means the function has been called via the contact menu). +*/ + +INT_PTR Meta_ForceDefault(WPARAM wParam,LPARAM lParam) +{ + // the wParam is a MetaContact + if (db_get_dw(wParam, META_PROTO, META_ID, (DWORD)-1) != (DWORD)-1) { + BOOL current = db_get_b(wParam, META_PROTO, "ForceDefault", 0); + current = !current; + db_set_b(wParam, META_PROTO, "ForceDefault", (BYTE)current); + + db_set_dw(wParam, META_PROTO, "ForceSend", 0); + + if (current) + NotifyEventHooks(hEventForceSend, wParam, (LPARAM)Meta_GetContactHandle(wParam, db_get_dw(wParam, META_PROTO, "Default", -1))); + else + NotifyEventHooks(hEventUnforceSend, wParam, 0); + } + return 0; +} + +HGENMENU hMenuContact[MAX_CONTACTS]; + +/** Called when the context-menu of a contact is about to be displayed +* +* This will test which of the 4 menu item should be displayed, depending +* on which contact triggered the event +* +* @param wParam : \c HANDLE to the contact that triggered the event +* @param lParam : Always set to 0; +*/ + +int Meta_ModifyMenu(WPARAM wParam, LPARAM lParam) +{ + DBVARIANT dbv; + char buf[512], idStr[512]; + WORD status; + CLISTMENUITEM mi = { sizeof(mi) }; + + if (db_get_dw(wParam, META_PROTO, META_ID,-1) != (DWORD)-1) { + // save the mouse pos in case they open a subcontact menu + GetCursorPos(&menuMousePoint); + + // This is a MetaContact, show the edit, force default, and the delete menu, and hide the others + Menu_ShowItem(hMenuEdit, true); + Menu_ShowItem(hMenuAdd, false); + Menu_ShowItem(hMenuConvert, false); + Menu_ShowItem(hMenuDefault, false); + Menu_ShowItem(hMenuDelete, false); + + mi.flags = CMIM_NAME | CMIF_TCHAR; + mi.ptszName = (TCHAR*)TranslateT("Remove from MetaContact"); + Menu_ModifyItem(hMenuDelete, &mi); + + //show subcontact menu items + int num_contacts = db_get_dw(wParam, META_PROTO, "NumContacts", 0); + for (int i = 0; i < MAX_CONTACTS; i++) { + if (i >= num_contacts) { + Menu_ShowItem(hMenuContact[i], false); + continue; + } + + MCONTACT hContact = Meta_GetContactHandle(wParam, i); + char *szProto = GetContactProto(hContact); + if ( !szProto) + status = ID_STATUS_OFFLINE; + else + status = db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); + + if (options.menu_contact_label == DNT_UID) { + strcpy(buf, "Login"); + strcat(buf, _itoa(i, idStr, 10)); + + db_get(wParam, META_PROTO, buf, &dbv); + switch(dbv.type) { + case DBVT_ASCIIZ: + mir_snprintf(buf,512,"%s",dbv.pszVal); + break; + case DBVT_BYTE: + mir_snprintf(buf,512,"%d",dbv.bVal); + break; + case DBVT_WORD: + mir_snprintf(buf,512,"%d",dbv.wVal); + break; + case DBVT_DWORD: + mir_snprintf(buf,512,"%d",dbv.dVal); + break; + default: + buf[0] = 0; + } + db_free(&dbv); + mi.pszName = buf; + mi.flags = 0; + } + else { + mi.ptszName = pcli->pfnGetContactDisplayName(hContact, GCDNF_TCHAR); + mi.flags = CMIF_TCHAR; + } + + mi.flags |= CMIM_FLAGS | CMIM_NAME | CMIM_ICON; + + int iconIndex = CallService(MS_CLIST_GETCONTACTICON, hContact, 0); + mi.hIcon = ImageList_GetIcon((HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0), iconIndex, 0); + + Menu_ModifyItem(hMenuContact[i], &mi); + DestroyIcon(mi.hIcon); + } + + // show hide nudge menu item + #define MS_NUDGE_SHOWMENU "NudgeShowMenu" + // wParam = char *szProto + // lParam = BOOL show + char serviceFunc[256]; + mir_snprintf(serviceFunc, 256, "%s%s", GetContactProto( Meta_GetMostOnline(wParam)), PS_SEND_NUDGE); + CallService(MS_NUDGE_SHOWMENU, (WPARAM)META_PROTO, (LPARAM)ServiceExists(serviceFunc)); + } + else { // This is a simple contact + if ( !Meta_IsEnabled()) { + // groups disabled - all meta menu options hidden + Menu_ShowItem(hMenuDefault, false); + Menu_ShowItem(hMenuDelete, false); + Menu_ShowItem(hMenuAdd, false); + Menu_ShowItem(hMenuConvert, false); + Menu_ShowItem(hMenuEdit, false); + } + else if (db_get_dw(wParam, META_PROTO, META_LINK,(DWORD)-1)!=(DWORD)-1) { + // The contact is affected to a metacontact. + Menu_ShowItem(hMenuDefault, true); + + mi.flags = CMIM_NAME | CMIF_TCHAR; + mi.ptszName = (TCHAR*)TranslateT("Remove from MetaContact"); + Menu_ModifyItem(hMenuDelete, &mi); + + Menu_ShowItem(hMenuAdd, false); + Menu_ShowItem(hMenuConvert, false); + Menu_ShowItem(hMenuEdit, false); + } + else { + // The contact is neutral + Menu_ShowItem(hMenuAdd, true); + Menu_ShowItem(hMenuConvert, true); + Menu_ShowItem(hMenuEdit, false); + Menu_ShowItem(hMenuDelete, false); + Menu_ShowItem(hMenuDefault, false); + } + + for (int i = 0; i < MAX_CONTACTS; i++) + Menu_ShowItem(hMenuContact[i], false); + } + return 0; +} diff --git a/plugins/!Deprecated/MetaContacts/src/meta_options.cpp b/plugins/!Deprecated/MetaContacts/src/meta_options.cpp new file mode 100644 index 0000000000..a2e63ef375 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/src/meta_options.cpp @@ -0,0 +1,609 @@ +/* +MetaContacts Plugin for Miranda IM. + +Copyright © 2004 Universite Louis PASTEUR, STRASBOURG. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/** @file meta_menu.c +* +* Functions needed to handle MetaContacts. +* Centralizes functions called when the user chooses +* an option integrated in the context-menu of the \c CList. +*/ + +#include "metacontacts.h" + +MetaOptions options; +MetaOptions options_changes; + +INT_PTR CALLBACK DlgProcOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND hw; + TCHAR buff[40]; + + switch ( msg ) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + options_changes = options; + + CheckDlgButton(hwndDlg, IDC_CHK_SETDEFAULTRECV, options_changes.set_default_on_recv ? TRUE : FALSE); + hw = GetDlgItem(hwndDlg, IDC_CHK_TEMPDEFAULT); + EnableWindow(hw, options_changes.set_default_on_recv); + CheckDlgButton(hwndDlg, IDC_CHK_TEMPDEFAULT, options_changes.temp_default ? TRUE : FALSE); + + CheckDlgButton(hwndDlg, IDC_CHK_ALWAYSUSEDEFAULT, options_changes.always_use_default ? TRUE : FALSE); + CheckDlgButton(hwndDlg, IDC_CHK_SUPPRESSSTATUS, options_changes.suppress_status ? TRUE : FALSE); + + CheckDlgButton(hwndDlg, IDC_RAD_UID, options_changes.menu_contact_label == DNT_UID); + CheckDlgButton(hwndDlg, IDC_RAD_DID, options_changes.menu_contact_label == DNT_DID); + + CheckDlgButton(hwndDlg, IDC_RAD_MSG, options_changes.menu_function == FT_MSG); + CheckDlgButton(hwndDlg, IDC_RAD_MENU, options_changes.menu_function == FT_MENU); + CheckDlgButton(hwndDlg, IDC_RAD_INFO, options_changes.menu_function == FT_INFO); + + CheckDlgButton(hwndDlg, IDC_RAD_NICK, options_changes.clist_contact_name == CNNT_NICK); + CheckDlgButton(hwndDlg, IDC_RAD_NAME, options_changes.clist_contact_name == CNNT_DISPLAYNAME); + CheckDlgButton(hwndDlg, IDC_CHK_LOCKHANDLE, options_changes.lockHandle ? TRUE : FALSE); + CheckDlgButton(hwndDlg, IDC_CHK_SUBWINDOW, options_changes.subcontact_windows ? TRUE : FALSE); + + CheckDlgButton(hwndDlg, IDC_CHK_METAHISTORY, options_changes.metahistory ? TRUE : FALSE); + CheckDlgButton(hwndDlg, IDC_CHK_SUBHISTORY, options_changes.subhistory ? TRUE : FALSE); + CheckDlgButton(hwndDlg, IDC_CHK_COPYDATA, options_changes.copydata ? TRUE : FALSE); + + if ( !options_changes.subcontact_windows) { + hw = GetDlgItem(hwndDlg, IDC_CHK_METAHISTORY); + EnableWindow(hw, FALSE); + } else { + hw = GetDlgItem(hwndDlg, IDC_CHK_SUBHISTORY); + EnableWindow(hw, FALSE); + } + + CheckDlgButton(hwndDlg, IDC_CHK_COPYHISTORY, options_changes.copy_subcontact_history ? TRUE : FALSE); + hw = GetDlgItem(hwndDlg, IDC_ED_DAYS); + _itot(options_changes.days_history, buff, 10); + SetWindowText(hw, buff); + return TRUE; + + case WM_COMMAND: + if ( HIWORD( wParam ) == BN_CLICKED ) { + switch( LOWORD( wParam )) { + case IDC_CHK_SETDEFAULTRECV: + options_changes.set_default_on_recv = IsDlgButtonChecked(hwndDlg, IDC_CHK_SETDEFAULTRECV); + EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_TEMPDEFAULT), options_changes.set_default_on_recv); + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_CHK_TEMPDEFAULT: + options_changes.temp_default = IsDlgButtonChecked(hwndDlg, IDC_CHK_TEMPDEFAULT); + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_CHK_ALWAYSUSEDEFAULT: + options_changes.always_use_default = IsDlgButtonChecked(hwndDlg, IDC_CHK_ALWAYSUSEDEFAULT); + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_CHK_SUPPRESSSTATUS: + options_changes.suppress_status = IsDlgButtonChecked(hwndDlg, IDC_CHK_SUPPRESSSTATUS); + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_CHK_COPYHISTORY: + options_changes.copy_subcontact_history = IsDlgButtonChecked(hwndDlg, IDC_CHK_COPYHISTORY); + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_CHK_METAHISTORY: + options_changes.metahistory = IsDlgButtonChecked(hwndDlg, IDC_CHK_METAHISTORY); + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_CHK_SUBHISTORY: + options_changes.subhistory = IsDlgButtonChecked(hwndDlg, IDC_CHK_SUBHISTORY); + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_CHK_COPYDATA: + options_changes.copydata = IsDlgButtonChecked(hwndDlg, IDC_CHK_COPYDATA); + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_RAD_UID: + if (IsDlgButtonChecked(hwndDlg, IDC_RAD_UID)) { + options_changes.menu_contact_label = DNT_UID; + CheckDlgButton(hwndDlg, IDC_RAD_DID, FALSE); + } + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_RAD_DID: + if (IsDlgButtonChecked(hwndDlg, IDC_RAD_DID)) { + options_changes.menu_contact_label = DNT_DID; + CheckDlgButton(hwndDlg, IDC_RAD_UID, FALSE); + } + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_RAD_MSG: + if (IsDlgButtonChecked(hwndDlg, IDC_RAD_MSG)) { + options_changes.menu_function = FT_MSG; + CheckDlgButton(hwndDlg, IDC_RAD_MENU, FALSE); + CheckDlgButton(hwndDlg, IDC_RAD_INFO, FALSE); + } + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_RAD_MENU: + if (IsDlgButtonChecked(hwndDlg, IDC_RAD_MENU)) { + options_changes.menu_function = FT_MENU; + CheckDlgButton(hwndDlg, IDC_RAD_MSG, FALSE); + CheckDlgButton(hwndDlg, IDC_RAD_INFO, FALSE); + } + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_RAD_INFO: + if (IsDlgButtonChecked(hwndDlg, IDC_RAD_INFO)) { + options_changes.menu_function = FT_INFO; + CheckDlgButton(hwndDlg, IDC_RAD_MSG, FALSE); + CheckDlgButton(hwndDlg, IDC_RAD_MENU, FALSE); + } + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_RAD_NICK: + if (IsDlgButtonChecked(hwndDlg, IDC_RAD_NICK)) { + options_changes.clist_contact_name = CNNT_NICK; + CheckDlgButton(hwndDlg, IDC_RAD_NAME, FALSE); + } + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_RAD_NAME: + if (IsDlgButtonChecked(hwndDlg, IDC_RAD_NAME)) { + options_changes.clist_contact_name = CNNT_DISPLAYNAME; + CheckDlgButton(hwndDlg, IDC_RAD_NICK, FALSE); + } + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case IDC_CHK_SUBWINDOW: + options_changes.subcontact_windows = IsDlgButtonChecked(hwndDlg, IDC_CHK_SUBWINDOW); + + if (options_changes.subcontact_windows) { + EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_METAHISTORY), TRUE); + CheckDlgButton(hwndDlg, IDC_CHK_SUBHISTORY, TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_SUBHISTORY), FALSE); + options_changes.subhistory = TRUE; + } else { + EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_SUBHISTORY), TRUE); + CheckDlgButton(hwndDlg, IDC_CHK_METAHISTORY, TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_METAHISTORY), FALSE); + options_changes.metahistory = TRUE; + } + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + + case IDC_CHK_LOCKHANDLE: + options_changes.lockHandle = IsDlgButtonChecked(hwndDlg, IDC_CHK_LOCKHANDLE); + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + } + else if ( HIWORD( wParam ) == EN_CHANGE && ( HWND )lParam == GetFocus()) { + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->code == PSN_APPLY ) { + hw = GetDlgItem(hwndDlg, IDC_ED_DAYS); + GetWindowText(hw, buff, SIZEOF(buff)); + if (buff[0] != 0) + options_changes.days_history = _ttoi(buff); + + options = options_changes; + Meta_WriteOptions(&options); + + Meta_SuppressStatus(options.suppress_status); + Meta_SetAllNicks(); + return TRUE; + } + break; + } + + return FALSE; +} + +int Meta_WriteOptions(MetaOptions *opt) +{ + db_set_b(NULL, META_PROTO, "SetDefaultOnRecv", (BYTE)(opt->set_default_on_recv ? 1 : 0)); + db_set_b(NULL, META_PROTO, "TempDefault", (BYTE)(opt->temp_default ? 1 : 0)); + db_set_b(NULL, META_PROTO, "AlwaysUseDefault", (BYTE)(opt->always_use_default ? 1 : 0)); + db_set_b(NULL, META_PROTO, "SuppressStatus", (BYTE)(opt->suppress_status ? 1 : 0)); + db_set_w(NULL, META_PROTO, "MenuContactLabel", (WORD)opt->menu_contact_label); + db_set_w(NULL, META_PROTO, "MenuContactFunction", (WORD)opt->menu_function); + db_set_w(NULL, META_PROTO, "CListContactName", (WORD)opt->clist_contact_name); + db_set_b(NULL, META_PROTO, "CopyHistory", (BYTE)(opt->copy_subcontact_history ? 1 : 0)); + db_set_dw(NULL, META_PROTO, "DaysHistory", (DWORD)(opt->days_history)); + db_set_dw(NULL, META_PROTO, "SetStatusFromOfflineDelay", (DWORD)(opt->set_status_from_offline_delay)); + db_set_b(NULL, META_PROTO, "SubcontactWindows", (BYTE)(opt->subcontact_windows ? 1 : 0)); + db_set_b(NULL, META_PROTO, "CopyData", (BYTE)(opt->copydata ? 1 : 0)); + db_set_b(NULL, META_PROTO, "LockHandle", (BYTE)(opt->lockHandle ? 1 : 0)); + db_set_b(NULL, META_PROTO, "MetaMessageIcon", (BYTE)(opt->flash_meta_message_icon ? 1 : 0)); + db_set_b(NULL, META_PROTO, "CopyUserInfo", (BYTE)(opt->copy_userinfo ? 1 : 0)); + + if ( !opt->subcontact_windows) + db_set_b(NULL, META_PROTO, "MetaHistory", 1); + else + db_set_b(NULL, META_PROTO, "MetaHistory", (BYTE)(opt->metahistory ? 1 : 0)); + + if (opt->subcontact_windows) + db_set_b(NULL, META_PROTO, "SubcontactHistory", 1); + else + db_set_b(NULL, META_PROTO, "SubcontactHistory", (BYTE)(opt->subhistory ? 1 : 0)); + return 0; + + db_set_b(NULL, META_PROTO, "UseProtoRecv", (BYTE)(opt->use_proto_recv ? 1 : 0)); +} + +int Meta_ReadOptions(MetaOptions *opt) +{ + opt->set_default_on_recv = (db_get_b(NULL, META_PROTO, "SetDefaultOnRecv", 1) == 1 ? TRUE : FALSE); + opt->temp_default = (db_get_b(NULL, META_PROTO, "TempDefault", 1) == 1 ? TRUE : FALSE); + opt->always_use_default = (db_get_b(NULL, META_PROTO, "AlwaysUseDefault", 1) == 1 ? TRUE : FALSE); + opt->suppress_status = (db_get_b(NULL, META_PROTO, "SuppressStatus", 1) == 1 ? TRUE : FALSE); + opt->menu_contact_label = (int)db_get_w(NULL, META_PROTO, "MenuContactLabel", DNT_UID); + opt->menu_function = (int)db_get_w(NULL, META_PROTO, "MenuContactFunction", FT_MENU); + opt->clist_contact_name = (int)db_get_w(NULL, META_PROTO, "CListContactName", CNNT_NICK); + opt->copy_subcontact_history = (db_get_b(NULL, META_PROTO, "CopyHistory", 1) == 1 ? TRUE : FALSE); + opt->days_history = (int)db_get_dw(NULL, META_PROTO, "DaysHistory", 0); + opt->set_status_from_offline_delay = (int)db_get_dw(NULL, META_PROTO, "SetStatusFromOfflineDelay", DEFAULT_SET_STATUS_SLEEP_TIME); + opt->subcontact_windows = (db_get_b(NULL, META_PROTO, "SubcontactWindows", 0) == 1 ? TRUE : FALSE); + opt->copydata = (db_get_b(NULL, META_PROTO, "CopyData", 1) == 1 ? TRUE : FALSE); + opt->lockHandle = (db_get_b(NULL, META_PROTO, "LockHandle", 0) == 1 ? TRUE : FALSE); + opt->flash_meta_message_icon = (db_get_b(NULL, META_PROTO, "MetaMessageIcon", 1) == 1 ? TRUE : FALSE); + opt->copy_userinfo = (db_get_b(NULL, META_PROTO, "CopyUserInfo", 1) == 1 ? TRUE : FALSE); + + if ( !opt->subcontact_windows) + opt->metahistory = TRUE; + else + opt->metahistory = (db_get_b(NULL, META_PROTO, "MetaHistory", 1) == 1 ? TRUE : FALSE); + + if (opt->subcontact_windows) + opt->subhistory = TRUE; + else + opt->subhistory = (db_get_b(NULL, META_PROTO, "SubcontactHistory", 1) == 1 ? TRUE : FALSE); + + opt->use_proto_recv = (db_get_b(NULL, META_PROTO, "UseProtoRecv", 1) == 1 ? TRUE : FALSE); + return 0; +} + +/* +#define ID_STATUS_OFFLINE 40071 ->8 +#define ID_STATUS_ONLINE 40072 ->0 +#define ID_STATUS_AWAY 40073 ->4 +#define ID_STATUS_DND 40074 ->7 +#define ID_STATUS_NA 40075 ->6 +#define ID_STATUS_OCCUPIED 40076 ->5 +#define ID_STATUS_FREECHAT 40077 ->1 +#define ID_STATUS_INVISIBLE 40078 ->0 +#define ID_STATUS_ONTHEPHONE 40079 ->2 +#define ID_STATUS_OUTTOLUNCH 40080 ->3 +*/ + +int GetDefaultPrio(int status) +{ + switch( status ) { + case ID_STATUS_OFFLINE: return 8; + case ID_STATUS_AWAY: return 4; + case ID_STATUS_DND: return 7; + case ID_STATUS_NA: return 6; + case ID_STATUS_OCCUPIED: return 5; + case ID_STATUS_FREECHAT: return 1; + case ID_STATUS_ONTHEPHONE: return 2; + case ID_STATUS_OUTTOLUNCH: return 3; + } + + return 0; +} + +typedef struct { + int prio[10]; // priority for each status + BOOL def[10]; // use default for this one? +} ProtoStatusPrio; + +ProtoStatusPrio *priorities = 0; + +int GetRealPriority(char *proto, int status) +{ + char szSetting[256]; + if ( !proto) { + mir_snprintf(szSetting, 256, "DefaultPrio_%d", status); + return db_get_w(0, META_PROTO, szSetting, GetDefaultPrio(status)); + } + + mir_snprintf(szSetting, 256, "ProtoPrio_%s%d", proto, status); + int prio = db_get_w(0, META_PROTO, szSetting, 0xFFFF); + if (prio == 0xFFFF) { + mir_snprintf(szSetting, 256, "DefaultPrio_%d", status); + return db_get_w(0, META_PROTO, szSetting, GetDefaultPrio(status)); + } + return prio; +} + +void ReadPriorities() +{ + char szSetting[256]; + int num_protocols, i, j; + PROTOACCOUNT **pppDesc; + ProtoEnumAccounts(&num_protocols, &pppDesc); + + ProtoStatusPrio *current = priorities = (ProtoStatusPrio *)malloc((num_protocols + 1) * sizeof(ProtoStatusPrio)); + for (i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) { + mir_snprintf(szSetting, 256, "DefaultPrio_%d", i); + current->def[i - ID_STATUS_OFFLINE] = TRUE; + current->prio[i - ID_STATUS_OFFLINE] = db_get_w(0, META_PROTO, szSetting, GetDefaultPrio(i)); + } + + for (i = 0; i < num_protocols; i++) { + current = priorities + (i + 1); + for (j = ID_STATUS_OFFLINE; j <= ID_STATUS_OUTTOLUNCH; j++) { + mir_snprintf(szSetting, 256, "ProtoPrio_%s%d", pppDesc[i]->szModuleName, j); + current->prio[j - ID_STATUS_OFFLINE] = db_get_w(0, META_PROTO, szSetting, 0xFFFF); + current->def[j - ID_STATUS_OFFLINE] = (current->prio[j - ID_STATUS_OFFLINE] == 0xFFFF); + } + } +} + +void WritePriorities() +{ + char szSetting[256]; + ProtoStatusPrio *current = priorities; + int i, j; + + int num_protocols; + PROTOACCOUNT **pppDesc; + ProtoEnumAccounts(&num_protocols, &pppDesc); + + for (i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) { + mir_snprintf(szSetting, 256, "DefaultPrio_%d", i); + if (current->prio[i - ID_STATUS_OFFLINE] != GetDefaultPrio(i)) + db_set_w(0, META_PROTO, szSetting, (WORD)current->prio[i - ID_STATUS_OFFLINE]); + else + db_unset(0, META_PROTO, szSetting); + } + for (i = 0; i < num_protocols; i++) { + current = priorities + (i + 1); + for (j = ID_STATUS_OFFLINE; j <= ID_STATUS_OUTTOLUNCH; j++) { + mir_snprintf(szSetting, 256, "ProtoPrio_%s%d", pppDesc[i]->szModuleName, j); + if ( !current->def[j - ID_STATUS_OFFLINE]) + db_set_w(0, META_PROTO, szSetting, (WORD)current->prio[j - ID_STATUS_OFFLINE]); + else + db_unset(0, META_PROTO, szSetting); + } + } +} + +int GetIsDefault(int proto_index, int status) +{ + return (priorities + (proto_index + 1))->def[status - ID_STATUS_OFFLINE]; +} + +BOOL GetPriority(int proto_index, int status) +{ + if (proto_index == -1) + return priorities->prio[status - ID_STATUS_OFFLINE]; + + ProtoStatusPrio *current = priorities + (proto_index + 1); + if (current->def[status - ID_STATUS_OFFLINE]) + current = priorities; + + return current->prio[status - ID_STATUS_OFFLINE]; +} + +void SetPriority(int proto_index, int status, BOOL def, int prio) +{ + if (prio < 0) prio = 0; + if (prio > 500) prio = 500; + if (proto_index == -1) + priorities->prio[status - ID_STATUS_OFFLINE] = prio; + else { + ProtoStatusPrio *current = priorities + (proto_index + 1); + current->def[status - ID_STATUS_OFFLINE] = def; + if ( !def) + current->prio[status - ID_STATUS_OFFLINE] = prio; + } +} + +void ResetPriorities() +{ + int i, j, num_protocols; + PROTOACCOUNT **pppDesc; + ProtoEnumAccounts(&num_protocols, &pppDesc); + + ProtoStatusPrio *current = priorities; + for (i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) { + current->def[i - ID_STATUS_OFFLINE] = TRUE; + current->prio[i - ID_STATUS_OFFLINE] = GetDefaultPrio(i); + } + + for (i = 0; i < num_protocols; i++) { + current = priorities + (i + 1); + for (j = ID_STATUS_OFFLINE; j <= ID_STATUS_OUTTOLUNCH; j++) { + current->def[j - ID_STATUS_OFFLINE] = TRUE; + } + } +} + +#define WMU_FILLSTATUSCMB (WM_USER + 0x100) +#define WMU_FILLPRIODATA (WM_USER + 0x101) + +INT_PTR CALLBACK DlgProcOptsPriorities(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND hw; + int sel; + + switch ( msg ) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + SendMessage(GetDlgItem(hwndDlg, IDC_SP_PRIORITY), UDM_SETRANGE, 0, (LPARAM)MAKELONG(500, 0)); + ReadPriorities(); + { + int num_protocols; + PROTOACCOUNT **pppDesc; + ProtoEnumAccounts(&num_protocols, &pppDesc); + + hw = GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL); + int index = SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)TranslateT("")); + SendMessage(hw, CB_SETITEMDATA, (WPARAM)index, -1); + for (int i = 0; i < num_protocols; i++) { + if (strcmp(pppDesc[i]->szModuleName, META_PROTO) != 0) { + index = SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)pppDesc[i]->tszAccountName); + SendMessage(hw, CB_SETITEMDATA, (WPARAM)index, i); + } + } + + SendMessage(hw, CB_SETCURSEL, 0, 0); + SendMessage(hwndDlg, WMU_FILLSTATUSCMB, 0, 0); + SendMessage(hwndDlg, WMU_FILLPRIODATA, 0, 0); + } + return FALSE; + + case WMU_FILLPRIODATA: + sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETCURSEL, 0, 0); + if (sel != -1) { + int index = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETITEMDATA, (WPARAM)sel, 0); + sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETCURSEL, 0, 0); + if (sel != -1) { + int status = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETITEMDATA, (WPARAM)sel, 0); + SetDlgItemInt(hwndDlg, IDC_ED_PRIORITY, GetPriority(index, status), FALSE); + if (index == -1) { + EnableWindow(GetDlgItem(hwndDlg, IDC_ED_PRIORITY), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_SP_PRIORITY), TRUE); + CheckDlgButton(hwndDlg, IDC_CHK_DEFAULT, TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_DEFAULT), FALSE); + } + else { + if (GetIsDefault(index, status)) { + CheckDlgButton(hwndDlg, IDC_CHK_DEFAULT, TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ED_PRIORITY), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_SP_PRIORITY), FALSE); + } + else { + CheckDlgButton(hwndDlg, IDC_CHK_DEFAULT, FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ED_PRIORITY), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_SP_PRIORITY), TRUE); + } + + EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_DEFAULT), TRUE); + } + } + } + return TRUE; + + case WMU_FILLSTATUSCMB: + sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETCURSEL, 0, 0); + if (sel != -1) { + int index = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETITEMDATA, (WPARAM)sel, 0); + HWND hw = GetDlgItem(hwndDlg, IDC_CMB_STATUS); + SendMessage(hw, CB_RESETCONTENT, 0, 0); + if (index == -1) { + for (int i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) { + index = SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)pcli->pfnGetStatusModeDescription(i, 0)); + SendMessage(hw, CB_SETITEMDATA, (WPARAM)index, i); + } + } + else { + int num_protocols; + PROTOACCOUNT **pppDesc; + ProtoEnumAccounts(&num_protocols, &pppDesc); + + int caps = CallProtoService(pppDesc[index]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0); + + for (int i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) { + if (caps & Proto_Status2Flag(i)) { + index = SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)pcli->pfnGetStatusModeDescription(i, 0)); + SendMessage(hw, CB_SETITEMDATA, (WPARAM)index, i); + } + } + } + SendMessage(hw, CB_SETCURSEL, 0, 0); + SendMessage(hwndDlg, WMU_FILLPRIODATA, 0, 0); + } + return TRUE; + + case WM_COMMAND: + if ( HIWORD( wParam ) == BN_CLICKED ) { + switch( LOWORD( wParam )) { + case IDC_CHK_DEFAULT: + sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETCURSEL, 0, 0); + if (sel != -1) { + int index = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETITEMDATA, (WPARAM)sel, 0); + sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETCURSEL, 0, 0); + if (sel != -1) { + BOOL checked = IsDlgButtonChecked(hwndDlg, IDC_CHK_DEFAULT); + int status = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETITEMDATA, (WPARAM)sel, 0); + if (checked) { + SetPriority(index, status, TRUE, 0); + SetDlgItemInt(hwndDlg, IDC_ED_PRIORITY, GetPriority(index, status), FALSE); + } + else SetPriority(index, status, FALSE, GetDlgItemInt(hwndDlg, IDC_ED_PRIORITY, 0, FALSE)); + + EnableWindow(GetDlgItem(hwndDlg, IDC_ED_PRIORITY), !checked); + EnableWindow(GetDlgItem(hwndDlg, IDC_SP_PRIORITY), !checked); + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + break; + + case IDC_BTN_RESET: + ResetPriorities(); + SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_SETCURSEL, 0, 0); + SendMessage(hwndDlg, WMU_FILLSTATUSCMB, 0, 0); + SendMessage(hwndDlg, WMU_FILLPRIODATA, 0, 0); + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + } + + if ( HIWORD( wParam ) == EN_CHANGE && LOWORD(wParam) == IDC_ED_PRIORITY && ( HWND )lParam == GetFocus()) { + sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETCURSEL, 0, 0); + if (sel != -1) { + int index = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_PROTOCOL), CB_GETITEMDATA, (WPARAM)sel, 0); + sel = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETCURSEL, 0, 0); + if (sel != -1) { + int status = SendMessage(GetDlgItem(hwndDlg, IDC_CMB_STATUS), CB_GETITEMDATA, (WPARAM)sel, 0); + int prio = GetDlgItemInt(hwndDlg, IDC_ED_PRIORITY, 0, FALSE); + SetPriority(index, status, FALSE, prio); + if (prio != GetPriority(index, status)) + SetDlgItemInt(hwndDlg, IDC_ED_PRIORITY, GetPriority(index, status), FALSE); + SendMessage( GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + } + if ( HIWORD( wParam ) == CBN_SELCHANGE) { + switch( LOWORD( wParam )) { + case IDC_CMB_STATUS: + SendMessage(hwndDlg, WMU_FILLPRIODATA, 0, 0); + break; + case IDC_CMB_PROTOCOL: + SendMessage(hwndDlg, WMU_FILLSTATUSCMB, 0, 0); + break; + } + } + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->code == PSN_APPLY ) { + WritePriorities(); + return TRUE; + } + break; + case WM_DESTROY: + free(priorities); + priorities = 0; + break; + } + + return FALSE; +} diff --git a/plugins/!Deprecated/MetaContacts/src/meta_services.cpp b/plugins/!Deprecated/MetaContacts/src/meta_services.cpp new file mode 100644 index 0000000000..63578c17aa --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/src/meta_services.cpp @@ -0,0 +1,1453 @@ +/* +MetaContacts Plugin for Miranda IM. + +Copyright © 2004 Universite Louis PASTEUR, STRASBOURG. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/** @file meta_services.c +* +* Functions specific to the protocol part of the plugin. +* Centralizes all the functions called by Miranda to make +* the plugin work as a protocol. +*/ + +#include "metacontacts.h" + +#define PREF_METANODB 0x2000 //!< Flag to indicate message should not be added to db by filter when sending + +char *pendingACK = 0; //!< Name of the protocol in which an ACK is about to come. + +int previousMode, //!< Previous status of the MetaContacts Protocol + mcStatus; //!< Current status of the MetaContacts Protocol + +HGENMENU + hMenuConvert, //!< \c HANDLE to the convert menu item. + hMenuAdd, //!< \c HANDLE to the add to menu item. + hMenuEdit, //!< \c HANDLE to the edit menu item. + hMenuDelete, //!< \c HANDLE to the delete menu item. + hMenuDefault, //!< \c HANDLE to the delete menu item. + hMenuForceDefault, //!< \c HANDLE to the delete menu item. + hMenuOnOff; //!< \c HANDLE to the enable/disable menu item. + +HANDLE + hEventDefaultChanged, //!< \c HANDLE to the 'default changed' event + hEventForceSend, //!< \c HANDLE to the 'force send' event + hEventUnforceSend, //!< \c HANDLE to the 'unforce send' event + hSubcontactsChanged, //!< \c HANDLE to the 'contacts changed' event + hEventNudge; + + +DWORD nextMetaID; //!< Global variable specifying the ID value the next MetaContact will have. + +BOOL message_window_api_enabled = FALSE; //!< Global variable specifying whether the message window api ver 0.0.0.1+ is available + +// stuff for mw_clist extra icon +HANDLE hExtraImage[MAX_PROTOCOLS * 2]; // online and offline icons +char proto_names[MAX_PROTOCOLS * 128]; +HANDLE hProtoIcons[MAX_PROTOCOLS * 2]; // online and offline icons + +UINT_PTR setStatusTimerId = 0; +BOOL firstSetOnline = TRUE; // see Meta_SetStatus function + +/** Get the capabilities of the "MetaContacts" protocol. +* +* @param wParam : equals to one of the following values :\n + PFLAGNUM_1 | PFLAGNUM_2 | PFLAGNUM_3 | PFLAGNUM_4 | PFLAG_UNIQUEIDTEXT | PFLAG_MAXLENOFMESSAGE | PFLAG_UNIQUEIDSETTING . +* @param lParam : Allways set to 0. +* +* @return Depending on the \c WPARAM. +*/ +INT_PTR Meta_GetCaps(WPARAM wParam,LPARAM lParam) +{ + switch (wParam) { + case PFLAGNUM_1: + return PF1_IM | PF1_CHAT | PF1_FILESEND | PF1_MODEMSGRECV | PF1_NUMERICUSERID; + + case PFLAGNUM_2: + return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE; + + case PFLAGNUM_3: + return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE; + + case PFLAGNUM_4: + return PF4_SUPPORTTYPING | PF4_AVATARS | PF4_IMSENDUTF; + + case PFLAGNUM_5: + return PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE; + + case PFLAG_UNIQUEIDTEXT: + return (INT_PTR) Translate("Meta ID"); + + case PFLAG_MAXLENOFMESSAGE: + return 2000; + + case PFLAG_UNIQUEIDSETTING: + return (INT_PTR)META_ID; + } + return 0; +} + +/** Copy the name of the protocole into lParam +* @param wParam : max size of the name +* @param lParam : reference to a char *, which will hold the name +*/ + +INT_PTR Meta_GetName(WPARAM wParam,LPARAM lParam) +{ + char *name = (char *)Translate(META_PROTO); + size_t size = min(strlen(name),wParam-1); // copy only the first size bytes. + if (strncpy((char *)lParam,name,size)==NULL) + return 1; + ((char *)lParam)[size]='\0'; + return 0; +} + +/** Loads the icon corresponding to the status +* Called by the CList when the status changes. +* @param wParam : one of the following values : \n + PLI_PROTOCOL | PLI_ONLINE | PLI_OFFLINE +* @return an \c HICON in which the icon has been loaded. +*/ + +INT_PTR Meta_LoadIcon(WPARAM wParam,LPARAM lParam) +{ + UINT id; + switch (wParam & 0xFFFF) { + case PLI_PROTOCOL: + id = IDI_MCMENU; + break; + case PLI_ONLINE: + id = IDI_MCMENU; + break; + case PLI_OFFLINE: + id = IDI_MCMENU; + break; + default: + return 0; + } + + return (INT_PTR) LoadImage(hInstance, MAKEINTRESOURCE(id), IMAGE_ICON, + GetSystemMetrics(wParam & PLIF_SMALL ? SM_CXSMICON : SM_CXICON), + GetSystemMetrics(wParam & PLIF_SMALL ? SM_CYSMICON : SM_CYICON), 0); +} + +void CALLBACK SetStatusThread(HWND hWnd, UINT msg, UINT_PTR id, DWORD dw) +{ + previousMode = mcStatus; + + mcStatus = (int)ID_STATUS_ONLINE; + ProtoBroadcastAck(META_PROTO, NULL,ACKTYPE_STATUS,ACKRESULT_SUCCESS, (HANDLE)previousMode, mcStatus); + + KillTimer(0, setStatusTimerId); +} + +/** Changes the status and notifies everybody +* @param wParam : The new mode +* @param lParam : Allways set to 0. +*/ + +INT_PTR Meta_SetStatus(WPARAM wParam,LPARAM lParam) +{ + // firstSetOnline starts out true - used to delay metacontact's 'onlineness' to prevent double status notifications on startup + if (mcStatus == ID_STATUS_OFFLINE && firstSetOnline) { + // causes crash on exit if miranda is closed in under options.set_status_from_offline milliseconds! + //CloseHandle( CreateThread( NULL, 0, SetStatusThread, (void *)wParam, 0, 0 )); + setStatusTimerId = SetTimer(0, 0, options.set_status_from_offline_delay, SetStatusThread); + firstSetOnline = FALSE; + } + else { + previousMode = mcStatus; + mcStatus = (int)wParam; + ProtoBroadcastAck(META_PROTO, NULL,ACKTYPE_STATUS,ACKRESULT_SUCCESS, (HANDLE)previousMode, mcStatus); + } + return 0; +} + +/** Returns the current status +*/ +INT_PTR Meta_GetStatus(WPARAM wParam,LPARAM lParam) +{ + return mcStatus; +} + +////////////////////////////////////////////////////////// +/// Copied from MSN plugin - sent acks need to be from different thread :( +////////////////////////////////////////////////////////// + +struct TFakeAckParams +{ + HANDLE hEvent; + MCONTACT hContact; + LONG id; + char msg[512]; +}; + +static DWORD CALLBACK sttFakeAckFail( LPVOID param ) +{ + TFakeAckParams *tParam = ( TFakeAckParams* )param; + WaitForSingleObject( tParam->hEvent, INFINITE ); + + Sleep( 100 ); + ProtoBroadcastAck(META_PROTO, tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, (HANDLE)tParam->id, (WPARAM)tParam->msg ); + + CloseHandle( tParam->hEvent ); + mir_free(tParam); + return 0; +} + +/** Filter messages sent by subcontacts +* +* When groups are disabled, add an event to the DB for the metacontact to maintain history +* +* @param wParam : index of the protocol in the protocol chain. +* @param lParam : \c CCSDATA structure holding all the information about the message. +* +* @return 0 on success, 1 otherwise. +*/ + +INT_PTR MetaFilter_SendMessage(WPARAM wParam,LPARAM lParam) +{ + CCSDATA *ccs = (CCSDATA*)lParam; + MCONTACT hMeta; + + if ((hMeta = (MCONTACT)db_get_dw(ccs->hContact, META_PROTO, "Handle", 0)) == 0) + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); // Can't find the MetaID of the metacontact linked to + + // if subcontact sending, add db event to keep metacontact history correct + if (options.metahistory && !(ccs->wParam & PREF_METANODB)) { + + // reject "file As Message" messages + if (strlen((char *)ccs->lParam) > 5 && strncmp((char *)ccs->lParam, "<%fAM", 5) == 0) + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); // continue processing + + // reject "data As Message" messages + if (strlen((char *)ccs->lParam) > 5 && strncmp((char *)ccs->lParam, "<%dAM", 5) == 0) + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); // continue processing + + // reject "OTR" messages + if (strlen((char *)ccs->lParam) > 5 && strncmp((char *)ccs->lParam, "?OTR", 4) == 0) + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); // continue processing + + DBEVENTINFO dbei = { sizeof(dbei) }; + dbei.szModule = META_PROTO; + dbei.flags = DBEF_SENT; + dbei.timestamp = time(NULL); + dbei.eventType = EVENTTYPE_MESSAGE; + if (ccs->wParam & PREF_RTL) dbei.flags |= DBEF_RTL; + if (ccs->wParam & PREF_UTF) dbei.flags |= DBEF_UTF; + dbei.cbBlob = (DWORD)strlen((char *)ccs->lParam) + 1; + if ( ccs->wParam & PREF_UNICODE ) + dbei.cbBlob *= ( sizeof( wchar_t )+1 ); + dbei.pBlob = (PBYTE)ccs->lParam; + db_event_add(hMeta, &dbei); + } + + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); +} + +INT_PTR Meta_SendNudge(WPARAM wParam,LPARAM lParam) +{ + MCONTACT hSubContact = Meta_GetMostOnline(wParam); + return ProtoCallService(GetContactProto(hSubContact), PS_SEND_NUDGE, (WPARAM)hSubContact, lParam); +} + +///////////////////////////////////////////////////////////////// + +/** Send a message to the protocol specific network. +* +* Call the function specific to the protocol that belongs +* to the contact chosen to send the message. +* +* @param wParam : index of the protocol in the protocol chain. +* @param lParam : \c CCSDATA structure holding all the information abour rhe message. +* +* @return 0 on success, 1 otherwise. +*/ +INT_PTR Meta_SendMessage(WPARAM wParam,LPARAM lParam) +{ + CCSDATA *ccs = (CCSDATA*)lParam; + char *proto = 0; + DWORD default_contact_number; + + if ((default_contact_number = db_get_dw(ccs->hContact, META_PROTO, "Default",(DWORD)-1)) == (DWORD)-1) { + // This is a simple contact, let through the stack of protocols + // (this should normally not happen, since linked contacts do not appear on the list.) + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); + } + + MCONTACT most_online = Meta_GetMostOnline(ccs->hContact); + + if ( !most_online) { + DWORD dwThreadId; + HANDLE hEvent; + TFakeAckParams *tfap; + + // send failure to notify user of reason + hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + tfap = (TFakeAckParams *)mir_alloc(sizeof(TFakeAckParams)); + tfap->hContact = ccs->hContact; + tfap->hEvent = hEvent; + tfap->id = 10; + strcpy(tfap->msg, Translate("No online contacts found.")); + + CloseHandle( CreateThread( NULL, 0, sttFakeAckFail, tfap, 0, &dwThreadId )); + SetEvent( hEvent ); + + return 10; + } + + Meta_CopyContactNick(ccs->hContact, most_online); + + ccs->hContact = most_online; + proto = GetContactProto(most_online); + Meta_SetNick(proto); // (no matter what was there before) + + // don't bypass filters etc + if (options.subhistory && !(ccs->wParam & PREF_METANODB)) { + // add sent event to subcontact + DBEVENTINFO dbei = { sizeof(dbei) }; + dbei.szModule = GetContactProto(ccs->hContact); + if (dbei.szModule) { + dbei.flags = DBEF_SENT; + dbei.timestamp = time(NULL); + dbei.eventType = EVENTTYPE_MESSAGE; + if (ccs->wParam & PREF_RTL) dbei.flags |= DBEF_RTL; + if (ccs->wParam & PREF_UTF) dbei.flags |= DBEF_UTF; + dbei.cbBlob = (DWORD)strlen((char *)ccs->lParam) + 1; + if ( ccs->wParam & PREF_UNICODE ) + dbei.cbBlob *= ( sizeof( wchar_t )+1 ); + dbei.pBlob = (PBYTE)ccs->lParam; + db_event_add(ccs->hContact, &dbei); + } + } + + // prevent send filter from adding another copy of this send event to the db + ccs->wParam |= PREF_METANODB; + + return CallContactService(ccs->hContact, PSS_MESSAGE, ccs->wParam, ccs->lParam); +} + +/** Transmit a message received by a contact. +* +* Forward the message received by a contact linked to a MetaContact +* to that MetaContact and inhibit the further reception of this message +* by the standard protocol of the contact. +* +* @param wParam : index of the protocol in the protocol chain. +* @param lParam : \c CCSDATA structure holding all the information about the message. +* +* @return 0 on success, 1 otherwise. +*/ + +INT_PTR MetaFilter_RecvMessage(WPARAM wParam,LPARAM lParam) +{ + DBEVENTINFO dbei; + CCSDATA *ccs = (CCSDATA*)lParam; + PROTORECVEVENT *pre = (PROTORECVEVENT *) ccs->lParam; + MCONTACT hMeta; + + // Can't find the MetaID of the metacontact linked to this contact, let through the protocol chain + if ((hMeta = (MCONTACT)db_get_dw(ccs->hContact, META_PROTO, "Handle", 0)) == 0) + return CallService(MS_PROTO_CHAINRECV, wParam, (LPARAM)ccs); + + if (options.set_default_on_recv) { + if (options.temp_default && db_get_dw(hMeta, META_PROTO, "SavedDefault", (DWORD)-1) == (DWORD)-1) + db_set_dw(hMeta, META_PROTO, "SavedDefault", db_get_dw(hMeta, META_PROTO, "Default", 0)); + db_set_dw(hMeta, META_PROTO, "Default", db_get_dw(ccs->hContact, META_PROTO, "ContactNumber", 0)); + NotifyEventHooks(hEventDefaultChanged, (WPARAM)hMeta, (LPARAM)ccs->hContact); // nick set in event handler + } + + // if meta disabled (now message api) or window open (message api), or using subcontact windows, + // let through but add db event for metacontact history + if ( !Meta_IsEnabled() || db_get_b(ccs->hContact, META_PROTO, "WindowOpen", 0) == 1 || options.subcontact_windows) { + + // add a clist event, so that e.g. there is an icon flashing + // (only add it when message api available, 'cause then we can remove the event when the message window is opened) + if (message_window_api_enabled + && db_get_b(ccs->hContact, META_PROTO, "WindowOpen", 0) == 0 + && db_get_b(hMeta, META_PROTO, "WindowOpen", 0) == 0 + && options.flash_meta_message_icon) + { + TCHAR toolTip[256]; + + CLISTEVENT cle = { sizeof(cle) }; + cle.hContact = hMeta; + cle.flags = CLEF_TCHAR; + cle.hDbEvent = (HANDLE)ccs->hContact; // use subcontact handle as key - then we can remove all events if the subcontact window is opened + cle.hIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE); + cle.pszService = "MetaContacts/CListMessageEvent"; + mir_sntprintf(toolTip, SIZEOF(toolTip), TranslateT("Message from %s"), pcli->pfnGetContactDisplayName(hMeta, GCDNF_TCHAR)); + cle.ptszTooltip = toolTip; + CallService(MS_CLIST_ADDEVENT, 0, (LPARAM)&cle); + } + + if (options.metahistory) { + BOOL added = FALSE; + + // should be able to do this, but some protos mess with the memory + if (options.use_proto_recv) { + // use the subcontact's protocol 'recv' service to add the meta's history (AIMOSCAR removes HTML here!) if possible + char *proto = GetContactProto(ccs->hContact); + if (proto) { + MCONTACT hSub = ccs->hContact; + DWORD flags = pre->flags; + ccs->hContact = hMeta; + pre->flags |= (db_get_b(hMeta, META_PROTO, "WindowOpen", 0) ? 0 : PREF_CREATEREAD); + if (ProtoServiceExists(proto, PSR_MESSAGE) && !ProtoCallService(proto, PSR_MESSAGE, 0, (LPARAM)ccs)) + added = TRUE; + ccs->hContact = hSub; + pre->flags = flags; + } + } + + if ( !added) { + // otherwise add raw db event + ZeroMemory(&dbei, sizeof(dbei)); + dbei.cbSize = sizeof(dbei); + dbei.szModule = META_PROTO; + dbei.timestamp = pre->timestamp; + dbei.flags = (db_get_b(hMeta, META_PROTO, "WindowOpen", 0) ? 0 : DBEF_READ); + if (pre->flags & PREF_RTL) dbei.flags |= DBEF_RTL; + if (pre->flags & PREF_UTF) dbei.flags |= DBEF_UTF; + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.cbBlob = (DWORD)strlen(pre->szMessage) + 1; + if ( pre->flags & PREF_UNICODE ) { + dbei.cbBlob *= ( sizeof( wchar_t )+1 ); + } + dbei.pBlob = (PBYTE) pre->szMessage; + db_event_add(hMeta, &dbei); + } + } + + return CallService(MS_PROTO_CHAINRECV, wParam, (LPARAM)ccs); + } + + MCONTACT hSub = ccs->hContact; + ccs->hContact = hMeta; // Forward to the associated MetaContact. + CallService(MS_PROTO_CHAINRECV, 0, (LPARAM)ccs); + ccs->hContact = hSub; + + if (options.subhistory && !(ccs->wParam & PREF_METANODB)) { + // allow event pass through and thereby be added to subcontact history + pre->flags |= (db_get_b(ccs->hContact, META_PROTO, "WindowOpen", 0) ? 0 : PREF_CREATEREAD); + return CallService(MS_PROTO_CHAINRECV, wParam, (LPARAM)ccs); // pass through as normal + } + + return 1; // Stop further processing. +} + +/** Receive a message for a MetaContact +* +* @return 0 +*/ +INT_PTR Meta_RecvMessage(WPARAM wParam, LPARAM lParam) +{ + CCSDATA *ccs = (CCSDATA*)lParam; + PROTORECVEVENT *pre = (PROTORECVEVENT *) ccs->lParam; + + // contact is not a meta proto contact - just leave it + char *proto = GetContactProto(ccs->hContact); + if ( !proto || strcmp(proto, META_PROTO)) + return 0; + + if (options.use_proto_recv) { + // use the subcontact's protocol to add the db if possible (AIMOSCAR removes HTML here!) + MCONTACT most_online = Meta_GetMostOnline(ccs->hContact); + if (char *subProto = GetContactProto(most_online)) + if ( ProtoCallService(subProto, PSR_MESSAGE, wParam, lParam) != CALLSERVICE_NOTFOUND) + return 0; + } + + // otherwise, add event to db directly + DBEVENTINFO dbei = { sizeof(dbei) }; + dbei.szModule = META_PROTO; + dbei.timestamp = pre->timestamp; + dbei.flags = (pre->flags & PREF_CREATEREAD ? DBEF_READ : 0); + if (pre->flags & PREF_RTL) dbei.flags |= DBEF_RTL; + if (pre->flags & PREF_UTF) dbei.flags |= DBEF_UTF; + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.cbBlob = (DWORD)strlen(pre->szMessage) + 1; + if ( pre->flags & PREF_UNICODE ) + dbei.cbBlob *= ( sizeof( wchar_t )+1 ); + dbei.pBlob = (PBYTE) pre->szMessage; + db_event_add(ccs->hContact, &dbei); + return 0; +} + + +/** Called when an ACK is received. +* +* Retransmit the ACK sent by a simple contact so that it +* looks like it was the MetaContact that sends the ACK. +* +* @param wParam : Allways set to 0. +* @param lParam : Reference to a ACKDATA that contains +information about the ACK. +* @return 0 on success, 1 otherwise. +*/ +int Meta_HandleACK(WPARAM wParam, LPARAM lParam) +{ + ACKDATA *ack = (ACKDATA*) lParam; + MCONTACT hUser; + + if (ack->hContact == 0 || (hUser = (MCONTACT)db_get_dw(ack->hContact, META_PROTO, "Handle",0)) == 0) + return 0; // Can't find the MetaID, let through the protocol chain + + + if ( !strcmp(ack->szModule, META_PROTO)) { + return 0; // don't rebroadcast our own acks + } + + // if it's for something we don't support, ignore + if (ack->type != ACKTYPE_MESSAGE && ack->type != ACKTYPE_CHAT && ack->type != ACKTYPE_FILE && ack->type != ACKTYPE_AWAYMSG + && ack->type != ACKTYPE_AVATAR && ack->type != ACKTYPE_GETINFO) + + { + return 0; + } + + // change the hContact in the avatar info struct, if it's the avatar we're using - else drop it + if (ack->type == ACKTYPE_AVATAR) { + if (ack->result == ACKRESULT_SUCCESS || ack->result == ACKRESULT_FAILED || ack->result == ACKRESULT_STATUS) { + DBVARIANT dbv; + + // change avatar if the most online supporting avatars changes, or if we don't have one + MCONTACT most_online = Meta_GetMostOnlineSupporting(hUser, PFLAGNUM_4, PF4_AVATARS); + //if (AI.hContact == 0 || AI.hContact != most_online) { + if (ack->hContact == 0 || ack->hContact != most_online) { + return 0; + } + + //if ( !db_get(AI.hContact, "ContactPhoto", "File", &dbv)) { + if ( !db_get(ack->hContact, "ContactPhoto", "File", &dbv)) { + db_set_ts(hUser, "ContactPhoto", "File", dbv.ptszVal); + db_free(&dbv); + } + + if (ack->hProcess) { + PROTO_AVATAR_INFORMATIONT AI; + memcpy(&AI, (PROTO_AVATAR_INFORMATIONT *)ack->hProcess, sizeof(PROTO_AVATAR_INFORMATIONT)); + if (AI.hContact) + AI.hContact = hUser; + + return ProtoBroadcastAck(META_PROTO, hUser,ack->type,ack->result, (HANDLE)&AI, ack->lParam); + } else + return ProtoBroadcastAck(META_PROTO, hUser,ack->type,ack->result, 0, ack->lParam); + } + } + + return ProtoBroadcastAck(META_PROTO, hUser,ack->type,ack->result,ack->hProcess,ack->lParam); +} + +// hiding contacts on "CList/UseGroups" setting changed can cause a crash - do it in a seperate thread during idle time +static DWORD sttHideContacts( BOOL param ) +{ + Meta_HideMetaContacts((int)param); + return 0; +} + +/** Call whenever a contact changes one of its settings (for example, the status) +** +* @param wParam \c HANDLE to the contact that has change of its setting. +* @param lParam Reference to a structure that contains the setting that has changed (not used) +*/ +int Meta_SettingChanged(WPARAM wParam, LPARAM lParam) +{ + DBCONTACTWRITESETTING *dcws = (DBCONTACTWRITESETTING *)lParam; + char buffer[512], szId[40]; + int contact_number; + MCONTACT hMeta, most_online; + + // hide metacontacts when groups disabled + if (wParam == 0 + && ((strcmp(dcws->szModule, "CList") == 0 && strcmp(dcws->szSetting, "UseGroups") == 0) + || (strcmp(dcws->szModule, META_PROTO) == 0 && strcmp(dcws->szSetting, "Enabled") == 0))) + { + sttHideContacts(!Meta_IsEnabled()); + return 0; + } + + if (wParam == 0 + && strcmp(dcws->szModule, "Import") == 0 && strcmp(dcws->szSetting, "Completed") == 0) + { + // import process has just been run...call startup routines... + Meta_SetHandles(); + + for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { + int meta_id; + if ((meta_id = db_get_dw(hContact, META_PROTO, META_ID,(DWORD)-1)) != (DWORD)-1) + Meta_CopyData(hContact); + } + + Meta_HideLinkedContacts(); + Meta_SuppressStatus(options.suppress_status); + } + + // from here on, we're just interested in contact settings + if (wParam == 0) return 0; + + if ((hMeta=(MCONTACT)db_get_dw(wParam, META_PROTO, "Handle",0))!=0 && CallService(MS_DB_CONTACT_IS, (WPARAM)hMeta, 0)) // just to be safe + { + // This contact is attached to a MetaContact. + + contact_number = Meta_GetContactNumber(wParam); + if (contact_number == -1) return 0; // exit - db corruption + + if ( !meta_group_hack_disabled && !strcmp(dcws->szModule, "CList") && !strcmp(dcws->szSetting, "Group") && + Meta_IsEnabled() && db_get_b(wParam, META_PROTO, "Hidden", 0) == 0 && !Miranda_Terminated()) { + if ((dcws->value.type == DBVT_ASCIIZ || dcws->value.type == DBVT_UTF8) && !Meta_IsHiddenGroup(dcws->value.pszVal)) { + // subcontact group reassigned - copy to saved group + db_set(wParam, META_PROTO, "OldCListGroup", &dcws->value); + db_set_s(wParam, "CList", "Group", META_HIDDEN_GROUP); + } else if (dcws->value.type == DBVT_DELETED) { + db_unset(wParam, META_PROTO, "OldCListGroup"); + db_set_s(wParam, "CList", "Group", META_HIDDEN_GROUP); + } + } + else if ( !strcmp(dcws->szSetting, "IP")) { + if (dcws->value.type == DBVT_DWORD) + db_set_dw(hMeta, META_PROTO, "IP", dcws->value.dVal); + else + db_unset(hMeta, META_PROTO, "IP"); + } + else if ( !strcmp(dcws->szSetting, "RealIP")) { + if (dcws->value.type == DBVT_DWORD) + db_set_dw(hMeta, META_PROTO, "RealIP", dcws->value.dVal); + else + db_unset(hMeta, META_PROTO, "RealIP"); + + } + else if ( !strcmp(dcws->szSetting, "ListeningTo")) { + switch(dcws->value.type) { + case DBVT_ASCIIZ: + db_set_s(hMeta, META_PROTO, "ListeningTo", dcws->value.pszVal); + break; + case DBVT_UTF8: + db_set_utf(hMeta, META_PROTO, "ListeningTo", dcws->value.pszVal); + break; + case DBVT_WCHAR: + db_set_ws(hMeta, META_PROTO, "ListeningTo", dcws->value.pwszVal); + break; + case DBVT_DELETED: + db_unset(hMeta, META_PROTO, "ListeningTo"); + break; + } + } + else if ( !strcmp(dcws->szSetting, "Nick") && !dcws->value.type == DBVT_DELETED) { + // subcontact nick has changed - update metacontact + strcpy(buffer, "Nick"); + strcat(buffer, _itoa(contact_number, szId, 10)); + db_set(hMeta, META_PROTO, buffer, &dcws->value); + + DBVARIANT dbv; + if (Mydb_get(wParam, "CList", "MyHandle", &dbv)) { + strcpy(buffer, "CListName"); + strcat(buffer, _itoa(contact_number, szId, 10)); + db_set(hMeta, META_PROTO, buffer, &dcws->value); + } + else db_free(&dbv); + + // copy nick to metacontact, if it's the most online + MCONTACT most_online = Meta_GetMostOnline(hMeta); + Meta_CopyContactNick(hMeta, most_online); + + return 0; + } + else if ( !strcmp(dcws->szSetting, "IdleTS")) { + if (dcws->value.type == DBVT_DWORD) + db_set_dw(hMeta, META_PROTO, "IdleTS", dcws->value.dVal); + else if (dcws->value.type == DBVT_DELETED) + db_set_dw(hMeta, META_PROTO, "IdleTS", 0); + } + else if ( !strcmp(dcws->szSetting, "LogonTS")) { + if (dcws->value.type == DBVT_DWORD) + db_set_dw(hMeta, META_PROTO, "LogonTS", dcws->value.dVal); + else if (dcws->value.type == DBVT_DELETED) + db_set_dw(hMeta, META_PROTO, "LogonTS", 0); + } + else if ( !strcmp(dcws->szModule, "CList") && !strcmp(dcws->szSetting, "MyHandle")) { + if (dcws->value.type == DBVT_DELETED) { + char *proto = GetContactProto(wParam); + strcpy(buffer, "CListName"); + strcat(buffer, _itoa(contact_number, szId, 10)); + + DBVARIANT dbv; + if (proto && !Mydb_get(wParam, proto, "Nick", &dbv)) { + db_set(hMeta, META_PROTO, buffer, &dbv); + db_free(&dbv); + } else { + db_unset(hMeta, META_PROTO, buffer); + } + } else { + // subcontact clist displayname has changed - update metacontact + strcpy(buffer, "CListName"); + strcat(buffer, _itoa(contact_number, szId, 10)); + + db_set(hMeta, META_PROTO, buffer, &dcws->value); + } + + // copy nick to metacontact, if it's the most online + MCONTACT most_online = Meta_GetMostOnline(hMeta); + Meta_CopyContactNick(hMeta, most_online); + + return 0; + } + else if ( !strcmp(dcws->szSetting, "Status") && !dcws->value.type == DBVT_DELETED) { + // subcontact changing status + + // update subcontact status setting + strcpy(buffer, "Status"); + strcat(buffer, _itoa(contact_number, szId, 10)); + db_set_w(hMeta, META_PROTO, buffer, dcws->value.wVal); + + strcpy(buffer, "StatusString"); + strcat(buffer, _itoa(contact_number, szId, 10)); + db_set_ts(hMeta, META_PROTO, buffer, pcli->pfnGetStatusModeDescription(dcws->value.wVal, 0)); + + // if the contact was forced, unforce it (which updates status) + if ((HANDLE)db_get_dw(hMeta, META_PROTO, "ForceSend", 0) == (HANDLE)wParam) + MetaAPI_UnforceSendContact((WPARAM)hMeta, 0); + else { + // set status to that of most online contact + most_online = Meta_GetMostOnline(hMeta); + Meta_CopyContactNick(hMeta, most_online); + + Meta_FixStatus(hMeta); + Meta_CopyData(hMeta); + } + + // most online contact with avatar support might have changed - update avatar + most_online = Meta_GetMostOnlineSupporting(hMeta, PFLAGNUM_4, PF4_AVATARS); + if (most_online) { + PROTO_AVATAR_INFORMATIONT AI; + + AI.cbSize = sizeof(AI); + AI.hContact = hMeta; + AI.format = PA_FORMAT_UNKNOWN; + _tcscpy(AI.filename, _T("X")); + + if ((int)CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) + db_set_ts(hMeta, "ContactPhoto", "File",AI.filename); + } + } + else if (strcmp(dcws->szSetting, "XStatusId") == 0 || strcmp(dcws->szSetting, "XStatusMsg") == 0 || strcmp(dcws->szSetting, "XStatusName") == 0 || strcmp(dcws->szSetting, "StatusMsg") == 0) { + Meta_CopyData(hMeta); + } + else if (strcmp(dcws->szSetting, "MirVer") == 0) { + Meta_CopyData(hMeta); + } + else if ( !meta_group_hack_disabled && !strcmp(dcws->szModule, "CList") && !strcmp(dcws->szSetting, "Hidden")) { + if ((dcws->value.type == DBVT_DELETED || db_get_b(wParam, "CList", "Hidden", 0) == 0) + && db_get_b(wParam, META_PROTO, "Hidden", 0) == 1) + { + // a subcontact we hid (e.g. jabber) has been unhidden - hide it again :( + db_set_b(wParam, "CList", "Hidden", 1); + } + } + } + + return 0; +} + +int Meta_ContactDeleted(WPARAM wParam, LPARAM lParam) +{ + // is a subcontact - update meta contact + MCONTACT hMeta = (MCONTACT)db_get_dw(wParam, META_PROTO, "Handle", 0); + if (hMeta) { + Meta_RemoveContactNumber(hMeta, db_get_dw(wParam, META_PROTO, "ContactNumber", -1)); + NotifyEventHooks(hSubcontactsChanged, (WPARAM)hMeta, 0); + return 0; + } + + // not a subcontact - is it a metacontact? + int num_contacts = db_get_dw(wParam, META_PROTO, "NumContacts", 0); + if (num_contacts) + NotifyEventHooks(hSubcontactsChanged, (WPARAM)wParam, 0); + + // remove & restore all subcontacts + for (int i = 0; i < num_contacts; i++) { + MCONTACT hContact = Meta_GetContactHandle(wParam, i); + if (hContact && (HANDLE)db_get_dw(hContact, META_PROTO, "Handle", 0) == (HANDLE)wParam) { + if (db_get_b(hContact, META_PROTO, "IsSubcontact", 0) == 1) + db_unset(hContact, META_PROTO, "IsSubcontact"); + db_unset(hContact, META_PROTO, META_LINK); + db_unset(hContact, META_PROTO, "Handle"); + db_unset(hContact, META_PROTO, "ContactNumber"); + Meta_RestoreGroup(hContact); + db_unset(hContact, META_PROTO, "OldCListGroup"); + + // stop ignoring, if we were + if (options.suppress_status) + CallService(MS_IGNORE_UNIGNORE, hContact, (WPARAM)IGNOREEVENT_USERONLINE); + } + } + return 0; +} + +/** Call when we want to send a user is typing message +* +* @param wParam \c HANDLE to the contact that we are typing to +* @param lParam either PROTOTYPE_SELFTYPING_ON or PROTOTYPE_SELFTYPING_OFF +*/ +INT_PTR Meta_UserIsTyping(WPARAM wParam, LPARAM lParam) +{ + // This is a simple contact, let through the stack of protocols + if (db_get_dw(wParam, META_PROTO, META_ID,(DWORD)-1) == (DWORD)-1) + return 0; + + // forward to sending protocol, if supported + + MCONTACT most_online = Meta_GetMostOnline(wParam); + Meta_CopyContactNick(wParam, most_online); + if ( !most_online) + return 0; + + char *proto = GetContactProto(most_online); + if (proto) + if ( ProtoServiceExists(proto, PSS_USERISTYPING)) + ProtoCallService(proto, PSS_USERISTYPING, (WPARAM)most_online, (LPARAM)lParam); + + return 0; +} + +/** Call when we want to receive a user is typing message +* +* @param wParam \c HANDLE to the contact that is typing or not +* @param lParam either PROTOTYPE_SELFTYPING_ON or PROTOTYPE_SELFTYPING_OFF +*/ +int Meta_ContactIsTyping(WPARAM wParam, LPARAM lParam) +{ + MCONTACT hMeta; + if ((hMeta = (MCONTACT)db_get_dw(wParam, META_PROTO, "Handle",0)) != 0 && Meta_IsEnabled()) { + // This contact is attached to a MetaContact. + if ( !options.subcontact_windows) { // we don't want clicking on the clist notification icon to open the metacontact message window + // try to remove any clist events we added for subcontact + CallServiceSync(MS_CLIST_REMOVEEVENT, wParam, (LPARAM) 1); + CallService(MS_PROTO_CONTACTISTYPING, (WPARAM)hMeta, lParam); + // stop processing of event + return 1; + } + } + + return 0; +} + +/** Called when user info is about to be shown +* +* Returns 1 to stop event processing and opens page for metacontact default contact (returning 1 to stop it doesn't work!) +* +*/ + +int Meta_UserInfo(WPARAM wParam, LPARAM lParam) +{ + DWORD default_contact_number = db_get_dw(lParam, META_PROTO, "Default", (DWORD)-1); + + if (default_contact_number == -1) // not a meta contact + return 0; + + CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)Meta_GetContactHandle(lParam, default_contact_number), 0); + return 1; +} + +// handle message window api ver 0.0.0.1+ events - record window open/close status for subcontacts, so we know whether to +// let received messages through and add db history to metacontact, or vice versa +int Meta_MessageWindowEvent(WPARAM wParam, LPARAM lParam) { + MessageWindowEventData *mwed = (MessageWindowEventData *)lParam; + MCONTACT hMeta = 0; + + message_window_api_enabled = TRUE; + + if ((hMeta = (MCONTACT)db_get_dw(mwed->hContact, META_PROTO, "Handle", 0)) != 0 + || db_get_dw(mwed->hContact, META_PROTO, META_ID, (DWORD)-1) != (DWORD)-1) + { + // contact is subcontact of metacontact, or an actual metacontact - record whether window is open or closed + if (mwed->uType == MSG_WINDOW_EVT_OPEN || mwed->uType == MSG_WINDOW_EVT_OPENING) { + db_set_b(mwed->hContact, META_PROTO, "WindowOpen", 1); + + if (hMeta) { // subcontact window opened - remove clist events we added for metacontact + while(!CallService(MS_CLIST_REMOVEEVENT, (WPARAM)hMeta, (LPARAM)mwed->hContact)); + } + } else if (mwed->uType == MSG_WINDOW_EVT_CLOSE || mwed->uType == MSG_WINDOW_EVT_CLOSING) { + db_set_b(mwed->hContact, META_PROTO, "WindowOpen", 0); + if ( !hMeta) { // hMeta is 0 for metacontact (sorry) + DWORD saved_def; + + MetaAPI_UnforceSendContact((WPARAM)mwed->hContact, 0); + + // restore saved default contact + if (options.set_default_on_recv) { + saved_def = db_get_dw(mwed->hContact, META_PROTO, "SavedDefault", -1); + if (options.temp_default && saved_def != (DWORD)-1) { + db_set_dw(mwed->hContact, META_PROTO, "Default", saved_def); + db_set_dw(mwed->hContact, META_PROTO, "SavedDefault", (DWORD)-1); + NotifyEventHooks(hEventDefaultChanged, (WPARAM)mwed->hContact, (LPARAM)Meta_GetContactHandle(hMeta, saved_def)); // nick set in event handler + } + } + } + } + } + + return 0; +} + +int Meta_ClistDoubleClicked(WPARAM wParam, LPARAM lParam) +{ + if (db_get_dw(wParam, META_PROTO, "Default",(WORD)-1) == (WORD)-1) + return 0; + + // -1 indicates no specific capability but respect 'ForceDefault' + MCONTACT most_online = Meta_GetMostOnlineSupporting(wParam, PFLAGNUM_1, -1); + if ( !most_online) + return 0; + + if (options.subcontact_windows) { + if (lParam) // contact from incoming message in lParam via (at this point) clist message event + CallService(MS_CLIST_CONTACTDOUBLECLICKED, (WPARAM)lParam, 0); + else // simulate double click on most_online contact and stop event processing + CallService(MS_CLIST_CONTACTDOUBLECLICKED, (WPARAM)most_online, 0); + return 1; + } + + char *proto = GetContactProto(most_online); + if (proto == NULL) + return 0; + + char buffer[512]; + strcpy(buffer, proto); + strcat(buffer, PS_GETCAPS); + + // get the contacts messaging capabilities + int caps = CallService(buffer, (WPARAM)PFLAGNUM_1, 0); + if ((caps & PF1_IMSEND) || (caps & PF1_CHAT) || (proto && strcmp(proto, "IRC") == 0)) + // let event process normally + return 0; + + // simulate double click on most_online contact and stop event processing + CallService(MS_CLIST_CONTACTDOUBLECLICKED, (WPARAM)most_online, 0); + return 1; +} + +INT_PTR Meta_ClistMessageEventClicked(WPARAM wParam, LPARAM lParam) +{ + MCONTACT hContact = ((CLISTEVENT *)lParam)->hContact; + return Meta_ClistDoubleClicked(hContact, (LPARAM)((CLISTEVENT *)lParam)->hDbEvent); +} + +int NudgeRecieved(WPARAM wParam, LPARAM lParam) +{ + return 0; +} + +/** Called when all the plugin are loaded into Miranda. +* +* Initializes the 4 menus present in the context-menu +* and the initial value of nextMetaID +*/ +int Meta_ModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + char buffer[512], buffer2[512], buffer3[512]; + int i; + + if (ServiceExists(MS_MSG_GETWINDOWAPI)) + message_window_api_enabled = TRUE; + + // disable group hack for older nicer versions without the fix + if (ServiceExists(MS_CLUI_GETVERSION)) { + char *version = (char *)CallService(MS_CLUI_GETVERSION, 0, 0); + if (version && strlen(version) >= strlen("CList Nicer+") && strncmp(version, "CList Nicer+", strlen("CList Nicer+")) == 0) + meta_group_hack_disabled = TRUE; + } + + HookEvent(ME_CLIST_PREBUILDCONTACTMENU, Meta_ModifyMenu); + HookEvent(ME_CLIST_DOUBLECLICKED, Meta_ClistDoubleClicked ); + + InitIcons(); + + //////////////////////////////////////////////////////////////////////////// + CLISTMENUITEM mi = { sizeof(mi) }; + + // main menu item + mi.icolibItem = GetIconHandle(I_MENUOFF); + mi.pszName = LPGEN("Toggle MetaContacts Off"); + mi.pszService = "MetaContacts/OnOff"; + mi.position = 500010000; + hMenuOnOff = Menu_AddMainMenuItem(&mi); + + // contact menu items + mi.icolibItem = GetIconHandle(I_CONVERT); + mi.position = -200010; + mi.pszName = LPGEN("Convert to MetaContact"); + mi.pszService = "MetaContacts/Convert"; + hMenuConvert = Menu_AddContactMenuItem(&mi); + + mi.icolibItem = GetIconHandle(I_ADD); + mi.position = -200009; + mi.pszName = LPGEN("Add to existing MetaContact..."); + mi.pszService = "MetaContacts/AddTo"; + hMenuAdd = Menu_AddContactMenuItem(&mi); + + mi.icolibItem = GetIconHandle(I_EDIT); + mi.position = -200010; + mi.pszName = LPGEN("Edit MetaContact..."); + mi.pszService = "MetaContacts/Edit"; + hMenuEdit = Menu_AddContactMenuItem(&mi); + + mi.icolibItem = GetIconHandle(I_SETDEFAULT); + mi.position = -200009; + mi.pszName = LPGEN("Set as MetaContact default"); + mi.pszService = "MetaContacts/Default"; + hMenuDefault = Menu_AddContactMenuItem(&mi); + + mi.icolibItem = GetIconHandle(I_REMOVE); + mi.position = -200008; + mi.pszName = LPGEN("Delete MetaContact"); + mi.pszService = "MetaContacts/Delete"; + hMenuDelete = Menu_AddContactMenuItem(&mi); + + mi.flags |= CMIF_HIDDEN; + mi.pszContactOwner = META_PROTO; + + mi.position = -99000; + for (i = 0; i < MAX_CONTACTS; i++) { + mi.position--; + strcpy(buffer3, (char *)Translate("Context")); + strcat(buffer3, _itoa(i, buffer2, 10)); + mi.pszName = buffer3; + + strcpy(buffer, "MetaContacts/MenuFunc"); + strcat(buffer, _itoa(i, buffer2, 10)); + mi.pszService= buffer; + + hMenuContact[i] = Menu_AddContactMenuItem(&mi); + } + + nextMetaID = db_get_dw(NULL, META_PROTO, "NextMetaID",0); + + // loop and copy data from subcontacts + if (options.copydata) { + int meta_id; + for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) + if ((meta_id = db_get_dw(hContact, META_PROTO, META_ID,(DWORD)-1))!=(DWORD)-1) + Meta_CopyData(hContact); + } + + Meta_HideLinkedContacts(); + + if ( !Meta_IsEnabled()) { + // modify main menu item + mi.flags = CMIM_NAME | CMIM_ICON; + mi.icolibItem = GetIconHandle(I_MENU); + mi.pszName = LPGEN("Toggle MetaContacts On"); + Menu_ModifyItem(hMenuOnOff, &mi); + + Meta_HideMetaContacts(TRUE); + } + else Meta_SuppressStatus(options.suppress_status); + + // hook srmm window close/open events - message api ver 0.0.0.1+ + if (HookEvent(ME_MSG_WINDOWEVENT, Meta_MessageWindowEvent)) + message_window_api_enabled = TRUE; + + // hook protocol nudge events to forward to subcontacts + int numberOfProtocols; + PROTOACCOUNT ** ppProtocolDescriptors; + ProtoEnumAccounts(&numberOfProtocols, &ppProtocolDescriptors); + + for (int i = 0; i < numberOfProtocols ; i++) + if ( strcmp(ppProtocolDescriptors[i]->szModuleName, META_PROTO)) { + char str[MAXMODULELABELLENGTH + 10]; + mir_snprintf(str, SIZEOF(str), "%s/Nudge", ppProtocolDescriptors[i]->szModuleName); + HookEvent(str, NudgeRecieved); + } + + return 0; +} + +static VOID CALLBACK sttMenuThread( PVOID param ) +{ + HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)param, 0); + + TPMPARAMS tpmp = { 0 }; + tpmp.cbSize = sizeof(tpmp); + BOOL menuRet = TrackPopupMenuEx(hMenu, TPM_RETURNCMD, menuMousePoint.x, menuMousePoint.y, (HWND)CallService(MS_CLUI_GETHWND, 0, 0), &tpmp); + + CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(menuRet), MPCF_CONTACTMENU), (LPARAM)param); + + DestroyMenu(hMenu); +} + +INT_PTR Meta_ContactMenuFunc(WPARAM wParam, LPARAM lParam) +{ + MCONTACT hContact = Meta_GetContactHandle(wParam, (int)lParam); + + if (options.menu_function == FT_MSG) { + // open message window if protocol supports message sending or chat, else simulate double click + + int caps; + char *proto; + char buffer[512]; + + proto = GetContactProto(hContact); + + if (proto) { + strcpy(buffer, proto); + strcat(buffer, PS_GETCAPS); + + caps = CallService(buffer, (WPARAM)PFLAGNUM_1, 0); + + if ((caps & PF1_IMSEND) || (caps & PF1_CHAT) || (proto && strcmp(proto, "IRC") == 0)) { + // set default contact for sending/status and open message window + db_set_dw(wParam, META_PROTO, "Default", (DWORD)(int)lParam); + NotifyEventHooks(hEventDefaultChanged, wParam, (LPARAM)hContact); + CallService(MS_MSG_SENDMESSAGE, wParam, 0); + } else + // protocol does not support messaging - simulate double click + CallService(MS_CLIST_CONTACTDOUBLECLICKED, hContact, 0); + } else + // protocol does not support messaging - simulate double click + CallService(MS_CLIST_CONTACTDOUBLECLICKED, hContact, 0); + + } else if (options.menu_function == FT_MENU) { + // show contact's context menu + CallFunctionAsync(sttMenuThread, (void*)hContact); + } else if (options.menu_function == FT_INFO) { + // show user info for subcontact + CallService(MS_USERINFO_SHOWDIALOG, hContact, 0); + } + + return 0; +} + +//////////////////// +// file transfer support - mostly not required, since subcontacts do the receiving +//////////////////// + +INT_PTR Meta_FileSend(WPARAM wParam, LPARAM lParam) +{ + CCSDATA *ccs = (CCSDATA*)lParam; + char *proto = 0; + DWORD default_contact_number; + + if ((default_contact_number = db_get_dw(ccs->hContact, META_PROTO, "Default",(DWORD)-1)) == (DWORD)-1) + { + // This is a simple contact + // (this should normally not happen, since linked contacts do not appear on the list.) + //PUShowMessage("meta has no default", SM_NOTIFY); + return 0; + } + else + { + MCONTACT most_online = Meta_GetMostOnlineSupporting(ccs->hContact, PFLAGNUM_1, PF1_FILESEND); + if ( !most_online) { + //PUShowMessage("no most online for ft", SM_NOTIFY); + return 0; + } + + proto = GetContactProto(most_online); + if (proto) + return (int)(CallContactService(most_online, PSS_FILE, ccs->wParam, ccs->lParam)); + } + return 0; // fail +} + +INT_PTR Meta_GetAwayMsg(WPARAM wParam, LPARAM lParam) +{ + CCSDATA *ccs = (CCSDATA*)lParam; + char *proto = 0; + DWORD default_contact_number; + + if ((default_contact_number = db_get_dw(ccs->hContact, META_PROTO, "Default",(DWORD)-1)) == (DWORD)-1) + { + // This is a simple contact + // (this should normally not happen, since linked contacts do not appear on the list.) + return 0; + } + else + { + MCONTACT most_online = Meta_GetMostOnlineSupporting(ccs->hContact, PFLAGNUM_1, PF1_MODEMSGRECV); + if ( !most_online) + return 0; + + proto = GetContactProto(most_online); + if ( !proto) return 0; + + //Meta_CopyContactNick(ccs->hContact, most_online, proto); + + ccs->hContact = most_online; + //Meta_SetNick(proto); + + return (int)(CallContactService(ccs->hContact, PSS_GETAWAYMSG, ccs->wParam, ccs->lParam)); + } + return 0; // fail +} + +INT_PTR Meta_GetAvatarInfo(WPARAM wParam, LPARAM lParam) { + PROTO_AVATAR_INFORMATIONT *AI = (PROTO_AVATAR_INFORMATIONT *) lParam; + DWORD default_contact_number; + + if ((default_contact_number = db_get_dw(AI->hContact, META_PROTO, "Default",(DWORD)-1)) == (DWORD)-1) + { + // This is a simple contact + // (this should normally not happen, since linked contacts do not appear on the list.) + return 0; + } + else + { + MCONTACT hMeta = AI->hContact; + MCONTACT hSub = Meta_GetMostOnlineSupporting(AI->hContact, PFLAGNUM_4, PF4_AVATARS); + if ( !hSub) + return GAIR_NOAVATAR; + + char *proto = GetContactProto(hSub); + if ( !proto) return GAIR_NOAVATAR; + + AI->hContact = hSub; + + INT_PTR result = ProtoCallService(proto, PS_GETAVATARINFOT, wParam, lParam); + AI->hContact = hMeta; + if (result != CALLSERVICE_NOTFOUND) + return result; + } + return GAIR_NOAVATAR; // fail +} + +INT_PTR Meta_GetInfo(WPARAM wParam, LPARAM lParam) +{ + CCSDATA *ccs = (CCSDATA*)lParam; + DWORD default_contact_number; + + // This is a simple contact + // (this should normally not happen, since linked contacts do not appear on the list.) + if ((default_contact_number = db_get_dw(ccs->hContact, META_PROTO, "Default",(DWORD)-1)) == (DWORD)-1) + return 0; + + MCONTACT most_online = Meta_GetMostOnlineSupporting(ccs->hContact, PFLAGNUM_4, PF4_AVATARS); + if ( !most_online) + return 0; + + char *proto = GetContactProto(most_online); + if ( !proto) return 0; + + PROTO_AVATAR_INFORMATIONT AI; + AI.cbSize = sizeof(AI); + AI.hContact = ccs->hContact; + AI.format = PA_FORMAT_UNKNOWN; + _tcscpy(AI.filename, _T("X")); + if ((int)CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) + db_set_ts(ccs->hContact, "ContactPhoto", "File",AI.filename); + + most_online = Meta_GetMostOnline(ccs->hContact); + Meta_CopyContactNick(ccs->hContact, most_online); + + if ( !most_online) + return 0; + + ccs->hContact = most_online; + if ( !ProtoServiceExists(proto, PSS_GETINFO)) + return 0; // fail + + return CallContactService(ccs->hContact, PSS_GETINFO, ccs->wParam, ccs->lParam); +} + +int Meta_OptInit(WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp = { sizeof(odp) }; + odp.position = -790000000; + odp.hInstance = hInstance; + odp.flags = ODPF_BOLDGROUPS; + + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); + odp.pszTitle = LPGEN("MetaContacts"); + odp.pszGroup = LPGEN("Contacts"); + odp.pszTab = LPGEN("General"); + odp.pfnDlgProc = DlgProcOpts; + Options_AddPage(wParam, &odp); + + odp.pszTemplate = MAKEINTRESOURCEA(IDD_PRIORITIES); + odp.pszTab = LPGEN("Priorities"); + odp.pfnDlgProc = DlgProcOptsPriorities; + Options_AddPage(wParam, &odp); + + odp.pszTemplate = MAKEINTRESOURCEA(IDD_HISTORY); + odp.pszTab = LPGEN("History"); + odp.pfnDlgProc = DlgProcOpts; + Options_AddPage(wParam, &odp); + return 0; +} + +int Meta_CallMostOnline(WPARAM wParam, LPARAM lParam) +{ + MCONTACT most_online_im = Meta_GetMostOnline(wParam); + + // fix nick + Meta_CopyContactNick(wParam, most_online_im); + + // fix status + Meta_FixStatus(wParam); + + // copy all other data + Meta_CopyData((MCONTACT) wParam); + return 0; +} + +INT_PTR Meta_OnOff(WPARAM wParam, LPARAM lParam) +{ + CLISTMENUITEM mi = { sizeof(mi) }; + mi.flags = CMIM_NAME | CMIM_ICON; + // just write to db - the rest is handled in the Meta_SettingChanged function + if (db_get_b(0, META_PROTO, "Enabled", 1)) { + db_set_b(0, META_PROTO, "Enabled", 0); + // modify main mi item + mi.icolibItem = GetIconHandle(I_MENU); + mi.pszName = LPGEN("Toggle MetaContacts On"); + } else { + db_set_b(0, META_PROTO, "Enabled", 1); + // modify main mi item + mi.icolibItem = GetIconHandle(I_MENUOFF); + mi.pszName = LPGEN("Toggle MetaContacts Off"); + } + Menu_ModifyItem(hMenuOnOff, &mi); + return 0; +} + + +int Meta_PreShutdown(WPARAM wParam, LPARAM lParam) { + Meta_SetStatus((WPARAM)ID_STATUS_OFFLINE, 0); + Meta_UnhideLinkedContacts(); + Meta_SuppressStatus(FALSE); + //MessageBox(0, "Status is OFFLINE", "MC", MB_OK); + //MessageBox(0, "Preshutdown complete", "MC", MB_OK); + + if (setStatusTimerId) KillTimer(0, setStatusTimerId); + + return 0; +} + +INT_PTR MenuFunc(WPARAM wParam, LPARAM lParam, LPARAM param) +{ + return Meta_ContactMenuFunc(wParam, param); +} + +/** Initializes all services provided by the plugin +* +* Creates every function and hooks the event desired. +*/ + +void Meta_InitServices() +{ + previousMode = mcStatus = ID_STATUS_OFFLINE; + + CreateServiceFunction("MetaContacts/Convert", Meta_Convert); + CreateServiceFunction("MetaContacts/AddTo", Meta_AddTo); + CreateServiceFunction("MetaContacts/Edit", Meta_Edit); + CreateServiceFunction("MetaContacts/Delete", Meta_Delete); + CreateServiceFunction("MetaContacts/Default", Meta_Default); + CreateServiceFunction("MetaContacts/ForceDefault", Meta_ForceDefault); + + // hidden contact menu items...ho hum + for (int i=0; i < MAX_CONTACTS; i++) { + char szServiceName[100]; + mir_snprintf(szServiceName, SIZEOF(szServiceName), "MetaContacts/MenuFunc%d", i); + CreateServiceFunctionParam(szServiceName, MenuFunc, i); + } + + CreateProtoServiceFunction(META_PROTO, PS_GETCAPS, Meta_GetCaps); + CreateProtoServiceFunction(META_PROTO, PS_GETNAME, Meta_GetName); + CreateProtoServiceFunction(META_PROTO, PS_LOADICON, Meta_LoadIcon); + + CreateProtoServiceFunction(META_PROTO, PS_SETSTATUS, Meta_SetStatus); + + CreateProtoServiceFunction(META_PROTO, PS_GETSTATUS, Meta_GetStatus); + CreateProtoServiceFunction(META_PROTO, PSS_MESSAGE, Meta_SendMessage); + + CreateProtoServiceFunction(META_PROTO, PSS_USERISTYPING, Meta_UserIsTyping ); + + CreateProtoServiceFunction(META_PROTO, PSR_MESSAGE, Meta_RecvMessage); + + // file recv is done by subcontacts + CreateProtoServiceFunction(META_PROTO, PSS_FILE, Meta_FileSend); + + CreateProtoServiceFunction(META_PROTO, PSS_GETAWAYMSG, Meta_GetAwayMsg); + + CreateProtoServiceFunction(META_PROTO, PS_GETAVATARINFOT, Meta_GetAvatarInfo); + + CreateProtoServiceFunction(META_PROTO, PSS_GETINFO, Meta_GetInfo); + + CreateProtoServiceFunction(META_FILTER, PSR_MESSAGE, MetaFilter_RecvMessage); + CreateProtoServiceFunction(META_FILTER, PSS_MESSAGE, MetaFilter_SendMessage); + + // API services and events + CreateServiceFunction(MS_MC_GETMETACONTACT, MetaAPI_GetMeta); + CreateServiceFunction(MS_MC_GETDEFAULTCONTACT, MetaAPI_GetDefault); + CreateServiceFunction(MS_MC_GETDEFAULTCONTACTNUM, MetaAPI_GetDefaultNum); + CreateServiceFunction(MS_MC_GETMOSTONLINECONTACT, MetaAPI_GetMostOnline); + CreateServiceFunction(MS_MC_GETNUMCONTACTS, MetaAPI_GetNumContacts); + CreateServiceFunction(MS_MC_GETSUBCONTACT, MetaAPI_GetContact); + CreateServiceFunction(MS_MC_SETDEFAULTCONTACTNUM, MetaAPI_SetDefaultContactNum); + CreateServiceFunction(MS_MC_SETDEFAULTCONTACT, MetaAPI_SetDefaultContact); + CreateServiceFunction(MS_MC_FORCESENDCONTACTNUM, MetaAPI_ForceSendContactNum); + CreateServiceFunction(MS_MC_FORCESENDCONTACT, MetaAPI_ForceSendContact); + CreateServiceFunction(MS_MC_UNFORCESENDCONTACT, MetaAPI_UnforceSendContact); + CreateServiceFunction(MS_MC_GETPROTOCOLNAME, MetaAPI_GetProtoName); + CreateServiceFunction(MS_MC_GETFORCESTATE, MetaAPI_GetForceState); + + CreateServiceFunction(MS_MC_CONVERTTOMETA, MetaAPI_ConvertToMeta); + CreateServiceFunction(MS_MC_ADDTOMETA, MetaAPI_AddToMeta); + CreateServiceFunction(MS_MC_REMOVEFROMMETA, MetaAPI_RemoveFromMeta); + + CreateServiceFunction(MS_MC_DISABLEHIDDENGROUP, MetaAPI_DisableHiddenGroup); + + CreateServiceFunction("MetaContacts/OnOff", Meta_OnOff); + CreateServiceFunction("MetaContacts/CListMessageEvent", Meta_ClistMessageEventClicked); + + CreateProtoServiceFunction(META_PROTO, PS_SEND_NUDGE, Meta_SendNudge); + + // create our hookable events + hEventDefaultChanged = CreateHookableEvent(ME_MC_DEFAULTTCHANGED); + hEventForceSend = CreateHookableEvent(ME_MC_FORCESEND); + hEventUnforceSend = CreateHookableEvent(ME_MC_UNFORCESEND); + hSubcontactsChanged = CreateHookableEvent(ME_MC_SUBCONTACTSCHANGED); + + // hook other module events we need + HookEvent(ME_PROTO_ACK, Meta_HandleACK); + HookEvent(ME_PROTO_CONTACTISTYPING, Meta_ContactIsTyping); + HookEvent(ME_DB_CONTACT_DELETED, Meta_ContactDeleted); + HookEvent(ME_DB_CONTACT_SETTINGCHANGED, Meta_SettingChanged); + HookEvent(ME_OPT_INITIALISE, Meta_OptInit); + HookEvent(ME_SYSTEM_MODULESLOADED, Meta_ModulesLoaded); + HookEvent(ME_SYSTEM_PRESHUTDOWN, Meta_PreShutdown); + + // hook our own events, used to call Meta_GetMostOnline which sets nick for metacontact + HookEvent(ME_MC_DEFAULTTCHANGED, Meta_CallMostOnline); + HookEvent(ME_MC_FORCESEND, Meta_CallMostOnline); + HookEvent(ME_MC_UNFORCESEND, Meta_CallMostOnline); + + // redirect nudge events + hEventNudge = CreateHookableEvent(META_PROTO "/Nudge"); +} + +//! Unregister all hooks and services from Miranda +void Meta_CloseHandles() +{ + // destroy our hookable events + DestroyHookableEvent(hEventDefaultChanged); + DestroyHookableEvent(hEventForceSend); + DestroyHookableEvent(hEventUnforceSend); + DestroyHookableEvent(hSubcontactsChanged); + DestroyHookableEvent(hEventNudge); +} diff --git a/plugins/!Deprecated/MetaContacts/src/meta_utils.cpp b/plugins/!Deprecated/MetaContacts/src/meta_utils.cpp new file mode 100644 index 0000000000..6789e21352 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/src/meta_utils.cpp @@ -0,0 +1,1431 @@ +/* +MetaContacts Plugin for Miranda IM. + +Copyright © 2004 Universite Louis PASTEUR, STRASBOURG. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/** @file meta_utils.c +* +* Diverses functions useful in different places. +*/ + +#include "metacontacts.h" + +HANDLE invisiGroup; +POINT menuMousePoint; + +INT_PTR Mydb_get(MCONTACT hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv) +{ + memset(dbv, 0, sizeof(DBVARIANT)); + return db_get_s(hContact, szModule, szSetting, dbv, 0); +} + +int Meta_EqualDBV(DBVARIANT *dbv, DBVARIANT *id) { + DWORD res = 1; + int i; + if (dbv->type == id->type) + { // If the id parameter and the value returned by the db_get + // are the same, this is the correct HANDLE, return it. + switch(dbv->type) + { + case DBVT_DELETED: + return 1; + case DBVT_BYTE: + if (dbv->bVal == id->bVal) + return 1; + case DBVT_WORD: + if (dbv->wVal == id->wVal) + return 1; + case DBVT_DWORD: + if (dbv->dVal == id->dVal) + return 1; + break; + case DBVT_ASCIIZ: + case DBVT_UTF8: + if ( !strcmp(dbv->pszVal,id->pszVal)) + return 1; + case DBVT_WCHAR: + if ( !wcscmp(dbv->pwszVal,id->pwszVal)) + return 1; + case DBVT_BLOB: + if (dbv->cpbVal == id->cpbVal) + { + for (i=dbv->cpbVal;res && i<=0;i--) + res = (dbv->pbVal[i] == id->pbVal[i]); + if (res) + { + return 1; + } + } + break; + } // end switch + } // end if (dbv.type == id.type) + + return 0; +} + +/** Retrieve a \c HANDLE from a protocol and an identifier +* +* @param protocol : Name of the protocol +* @param id : Unique field identifiying the contact searched +* +* @return a \c HANDLE to the specified contact or \c NULL + if no contact has been found. +*/ +MCONTACT Meta_GetHandle(const char *protocol, DBVARIANT *id) +{ + char *field; + DBVARIANT dbv; + DWORD i,res = 1; + + // Get the field identifying the contact in the database. + if ( !ProtoServiceExists(protocol, PS_GETCAPS)) + return NULL; + + field = (char *)CallProtoService(protocol,PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0); + + for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { + // Scan the database and retrieve the field for each contact + if ( !db_get(hContact, protocol, field, &dbv)) { + if (dbv.type == id->type) { + // If the id parameter and the value returned by the db_get + // are the same, this is the correct HANDLE, return it. + switch(dbv.type) { + case DBVT_DELETED: + break; + case DBVT_BYTE: + if (dbv.bVal == id->bVal) + return hContact; + break; + case DBVT_WORD: + if (dbv.wVal == id->wVal) + return hContact; + break; + case DBVT_DWORD: + if (dbv.dVal == id->dVal) + return hContact; + break; + case DBVT_ASCIIZ: + case DBVT_UTF8: + if ( !strcmp(dbv.pszVal,id->pszVal)) { + db_free(&dbv); + return hContact; + } + db_free(&dbv); + break; + + case DBVT_WCHAR: + if ( !wcscmp(dbv.pwszVal,id->pwszVal)) { + db_free(&dbv); + return hContact; + } + db_free(&dbv); + break; + + case DBVT_BLOB: + if (dbv.cpbVal == id->cpbVal) { + for (i=dbv.cpbVal;res && i<=0;i--) + res = (dbv.pbVal[i] == id->pbVal[i]); + if (res) { + db_free(&dbv); + return hContact; + } + } + db_free(&dbv); + break; + } // end switch + } + else db_free(&dbv); + } + } + return NULL; +} + +/** Update the MetaContact login, depending on the protocol desired +* +* The login of the "MetaContacts" protocol will be copied from the login +* of the specified protocol. +* +* @param szProto : The name of the protocol used to get the login that will be +* affected to the "MetaContacts" protocol. +* +* @return O on success, 1 otherwise. +*/ +int Meta_SetNick(char *szProto) +{ + CONTACTINFO ci; + ci.cbSize = sizeof(CONTACTINFO); + ci.dwFlag = CNF_DISPLAY | CNF_TCHAR; + ci.hContact = NULL; + ci.szProto = szProto; + if (CallService(MS_CONTACT_GETCONTACTINFO,0,(LPARAM)&ci)) + return 1; + + switch(ci.type) { + case CNFT_BYTE: + if ( db_set_b(NULL, META_PROTO, "Nick", ci.bVal)) + return 1; + break; + case CNFT_WORD: + if ( db_set_w(NULL, META_PROTO, "Nick", ci.wVal)) + return 1; + break; + case CNFT_DWORD: + if ( db_set_dw(NULL, META_PROTO, "Nick", ci.dVal)) + return 1; + break; + case CNFT_ASCIIZ: + if ( db_set_ts(NULL, META_PROTO, "Nick", ci.pszVal)) + return 1; + mir_free(ci.pszVal); + break; + default: + if ( db_set_s(NULL, META_PROTO, "Nick",(char *)TranslateT("Sender"))) + return 1; + break; + } + return 0; +} + +/** Assign a contact (src) to a metacontact (dest) +* +* @param src \c HANDLE to a contact that should be assigned +* @param dest \c HANDLE to a metacontact that will host the contact +* @param set_as_default \c bool flag to indicate whether the new contact becomes the default +* +* @return TRUE on success, FALSE otherwise +*/ +BOOL Meta_Assign(MCONTACT src, MCONTACT dest, BOOL set_as_default) +{ + DWORD metaID, num_contacts; + char buffer[512], szId[40]; + WORD status; + MCONTACT most_online; + + if ((metaID = db_get_dw(dest, META_PROTO, META_ID,(DWORD)-1))==-1) { + MessageBox(0, TranslateT("Could not get MetaContact ID"), TranslateT("Assignment error"), MB_OK | MB_ICONWARNING); + return FALSE; + } + + if ((num_contacts = db_get_dw(dest, META_PROTO, "NumContacts",(DWORD)-1))==-1) { + MessageBox(0, TranslateT("Could not retreive MetaContact contact count"), TranslateT("Assignment error"), MB_OK | MB_ICONWARNING); + return FALSE; + } + + char *szProto = GetContactProto(src); + if (szProto == NULL) { + MessageBox(0, TranslateT("Could not retreive contact protocol"), TranslateT("Assignment error"), MB_OK | MB_ICONWARNING); + return FALSE; + } + + // Get the login of the subcontact + char *field = (char *)CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); + DBVARIANT dbv; + if ( db_get(src,szProto, field, &dbv)) { + MessageBox(0, TranslateT("Could not get unique ID of contact"), TranslateT("Assignment error"), MB_OK | MB_ICONWARNING); + return FALSE; + } + + // Check that is is 'on the list' + if ( db_get_b(src, "CList", "NotOnList", 0) == 1) { + MessageBox(0, TranslateT("Contact is 'Not on List' - please add the contact to your contact list before assigning."), TranslateT("Assignment error"), MB_OK | MB_ICONWARNING); + db_free(&dbv); + return FALSE; + } + + num_contacts++; + if (num_contacts >= MAX_CONTACTS) { + MessageBox(0, TranslateT("MetaContact is full"), TranslateT("Assignment error"), MB_OK | MB_ICONWARNING); + db_free(&dbv); + return FALSE; + } + + // write the contact's protocol + strcpy(buffer, "Protocol"); + strcat(buffer, _itoa(num_contacts-1, szId, 10)); + + if ( db_set_s(dest, META_PROTO, buffer, szProto)) { + MessageBox(0, TranslateT("Could not write contact protocol to MetaContact"), TranslateT("Assignment error"), MB_OK | MB_ICONWARNING); + db_free(&dbv); + return FALSE; + } + + // write the login + strcpy(buffer, "Login"); + strcat(buffer, szId); + + if ( db_set(dest, META_PROTO, buffer, &dbv)) { + MessageBox(0, TranslateT("Could not write unique ID of contact to MetaContact"), TranslateT("Assignment error"), MB_OK | MB_ICONWARNING); + db_free(&dbv); + return FALSE; + } + + db_free(&dbv); + + // If we can get the nickname of the subcontact... + if ( !db_get(src, szProto, "Nick", &dbv)) { + // write the nickname + strcpy(buffer, "Nick"); + strcat(buffer, szId); + if (db_set(dest, META_PROTO, buffer, &dbv)) { + MessageBox(0, TranslateT("Could not write nickname of contact to MetaContact"), TranslateT("Assignment error"), MB_OK | MB_ICONWARNING); + return FALSE; + } + + db_free(&dbv); + } + + // write the display name + strcpy(buffer, "CListName"); + strcat(buffer, szId); + db_set_ts(dest, META_PROTO, buffer, pcli->pfnGetContactDisplayName(src, GCDNF_TCHAR)); + + // Get the status + if ( !szProto) + status = ID_STATUS_OFFLINE; + else + status = db_get_w(src, szProto, "Status", ID_STATUS_OFFLINE); + + // write the status + strcpy(buffer, "Status"); + strcat(buffer, szId); + db_set_w(dest, META_PROTO, buffer, status); + + // write the handle + strcpy(buffer, "Handle"); + strcat(buffer, szId); + db_set_dw(dest, META_PROTO, buffer, (DWORD)src); + + // write status string + strcpy(buffer, "StatusString"); + strcat(buffer, szId); + + TCHAR *szStatus = pcli->pfnGetStatusModeDescription(status, 0); + db_set_ts(dest, META_PROTO, buffer, szStatus); + + // Write the link in the contact + db_set_dw(src, META_PROTO, META_LINK, metaID); + + // Write the contact number in the contact + db_set_dw(src, META_PROTO, "ContactNumber", num_contacts-1); + + // Write the handle in the contact + db_set_dw(src, META_PROTO, "Handle", (DWORD)dest); + + // update count of contacts + db_set_dw(dest, META_PROTO, "NumContacts", num_contacts); + + if (set_as_default) { + db_set_dw(dest, META_PROTO, "Default", (WORD)(num_contacts - 1)); + NotifyEventHooks(hEventDefaultChanged, (WPARAM)dest, (LPARAM)src); + } + + db_set_b(src, META_PROTO, "IsSubcontact", 1); + // set nick to most online contact that can message + most_online = Meta_GetMostOnline(dest); + Meta_CopyContactNick(dest, most_online); + + // set status to that of most online contact + Meta_FixStatus(dest); + + // if the new contact is the most online contact with avatar support, get avatar info + most_online = Meta_GetMostOnlineSupporting(dest, PFLAGNUM_4, PF4_AVATARS); + if (most_online == src) { + PROTO_AVATAR_INFORMATIONT AI; + AI.cbSize = sizeof(AI); + AI.hContact = dest; + AI.format = PA_FORMAT_UNKNOWN; + _tcscpy(AI.filename, _T("X")); + + if ( CallProtoService(META_PROTO, PS_GETAVATARINFOT, 0, (LPARAM)&AI) == GAIR_SUCCESS) + db_set_ts(dest, "ContactPhoto", "File",AI.filename); + } + + // Hide the contact + Meta_SetGroup(src); + + // copy history + if (options.copy_subcontact_history) + copyHistory(src, dest); + + // Ignore status if the option is on + if (options.suppress_status) + CallService(MS_IGNORE_IGNORE, (WPARAM)src, (WPARAM)IGNOREEVENT_USERONLINE); + + // copy other data + Meta_CopyData(dest); + + NotifyEventHooks(hSubcontactsChanged, (WPARAM)dest, 0); + return TRUE; +} + +/** +* Convenience method - get most online contact supporting messaging +* +*/ +MCONTACT Meta_GetMostOnline(MCONTACT hMeta) { + return Meta_GetMostOnlineSupporting(hMeta, PFLAGNUM_1, PF1_IM); +} +/** Get the 'most online' contact for a meta contact (according to above order) which supports the specified +* protocol service, and copies nick from that contact +* +* @param hMeta \c HANDLE to a metacontact +* +* @return \c HANDLE to a contact +*/ + +MCONTACT Meta_GetMostOnlineSupporting(MCONTACT hMeta, int pflagnum, unsigned long capability) { + int most_online_status = ID_STATUS_OFFLINE; + MCONTACT most_online_contact = NULL, hContact; + int i, status, default_contact_number, num_contacts; + unsigned long caps = 0; + char *szProto, *most_online_proto; + + // you can't get more online than having the default contact ONLINE - so check that first + if ((default_contact_number = db_get_dw(hMeta, META_PROTO, "Default",(DWORD)-1)) == (DWORD)-1) + { + // This is a simple contact - return NULL to signify error. + // (this should normally not happen, since all meta contacts have a default contact) + return NULL; + } + + // if the default is beyond the end of the list (eek!) return null + if (default_contact_number >= (num_contacts = db_get_dw(hMeta, META_PROTO, "NumContacts", 0))) + return NULL; + + most_online_contact = Meta_GetContactHandle(hMeta, default_contact_number); + szProto = GetContactProto(most_online_contact); + caps = szProto ? CallProtoService(szProto, PS_GETCAPS, (WPARAM)pflagnum, 0) : 0; + if (szProto && strcmp(szProto, "IRC") == 0) caps |= PF1_IM; + // we are forced to do use default for sending - '-1' capability indicates no specific capability, but respect 'Force Default' + if (szProto && db_get_b(hMeta, META_PROTO, "ForceDefault", 0) && capability != 0 && (capability == -1 || (caps & capability) == capability)) // capability is 0 when we're working out status + return most_online_contact; + + // a subcontact is being temporarily 'forced' to do sending + if ((most_online_contact = (MCONTACT)db_get_dw(hMeta, META_PROTO, "ForceSend", 0))) { + caps = szProto ? CallProtoService(szProto, PS_GETCAPS, (WPARAM)pflagnum, 0) : 0; + if (szProto && strcmp(szProto, "IRC") == 0) caps |= PF1_IM; + if (szProto && (caps & capability) == capability && capability != 0) // capability is 0 when we're working out status + return most_online_contact; + } + + most_online_contact = Meta_GetContactHandle(hMeta, default_contact_number); + szProto = GetContactProto(most_online_contact); + if (szProto && CallProtoService(szProto, PS_GETSTATUS, 0, 0) >= ID_STATUS_ONLINE) { + caps = szProto ? CallProtoService(szProto, PS_GETCAPS, (WPARAM)pflagnum, 0) : 0; + if (szProto && strcmp(szProto, "IRC") == 0) caps |= PF1_IM; + if (szProto && (capability == -1 || (caps & capability) == capability)) { + most_online_status = db_get_w(most_online_contact, szProto, "Status", ID_STATUS_OFFLINE); + + // if our default is not offline, and option to use default is set - return default + // and also if our default is online, return it + if (most_online_status == ID_STATUS_ONLINE || (most_online_status != ID_STATUS_OFFLINE && options.always_use_default)) { + return most_online_contact; + } + } else + most_online_status = ID_STATUS_OFFLINE; + } else + most_online_status = ID_STATUS_OFFLINE; + + most_online_proto = szProto; + // otherwise, check all the subcontacts for the one closest to the ONLINE state which supports the required capability + for (i = 0; i < num_contacts; i++) { + if (i == default_contact_number) // already checked that (i.e. initial value of most_online_contact and most_online_status are those of the default contact) + continue; + + hContact = Meta_GetContactHandle(hMeta, i); + szProto = GetContactProto(hContact); + + if ( !szProto || CallProtoService(szProto, PS_GETSTATUS, 0, 0) < ID_STATUS_ONLINE) // szProto offline or connecting + continue; + + caps = szProto ? CallProtoService(szProto, PS_GETCAPS, (WPARAM)pflagnum, 0) : 0; + if (szProto && strcmp(szProto, "IRC") == 0) caps |= PF1_IM; + if (szProto && (capability == -1 || (caps & capability) == capability)) { + + status = db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); + + if (status == ID_STATUS_ONLINE) { + most_online_contact = hContact; + most_online_proto = szProto; + return most_online_contact; + } else if (status <= ID_STATUS_OFFLINE) // status below ID_STATUS_OFFLINE is a connecting status + continue; + else { + if (GetRealPriority(szProto, status) < GetRealPriority(most_online_proto, most_online_status)) { + most_online_status = status; + most_online_contact = hContact; + most_online_proto = szProto; + } + } + } + } + + // no online contacts? if we're trying to message, use 'send offline' contact + if (most_online_status == ID_STATUS_OFFLINE && capability == PF1_IM) { + MCONTACT hOffline = Meta_GetContactHandle(hMeta, db_get_dw(hMeta, META_PROTO, "OfflineSend", (DWORD)-1)); + if (hOffline) + most_online_contact = hOffline; + } + + return most_online_contact; +} + +int Meta_GetContactNumber(MCONTACT hContact) { + return db_get_dw(hContact, META_PROTO, "ContactNumber", -1); +} + +BOOL dbv_same(DBVARIANT *dbv1, DBVARIANT *dbv2) { + if (dbv1->type != dbv2->type) return FALSE; + + switch(dbv1->type) { + case DBVT_BYTE: + return dbv1->bVal == dbv2->bVal; + case DBVT_WORD: + return dbv1->wVal == dbv2->wVal; + case DBVT_DWORD: + return dbv1->dVal == dbv2->dVal; + case DBVT_ASCIIZ: + return !strcmp(dbv1->pszVal, dbv2->pszVal); + case DBVT_BLOB: + return (dbv1->cpbVal == dbv2->cpbVal && !memcmp(dbv1->pbVal, dbv2->pbVal, dbv1->cpbVal)); + break; + default: + return FALSE; + } +} + + void copy_settings_array(MCONTACT hMeta, char *module, const char *settings[], int num_settings) { + int num_contacts = db_get_dw(hMeta, META_PROTO, "NumContacts", (DWORD)-1), + default_contact = db_get_dw(hMeta, META_PROTO, "Default", (DWORD)-1), + most_online = Meta_GetContactNumber(Meta_GetMostOnline(hMeta)); + + MCONTACT hContact; + int i, j; + char *used_mod; + + DBVARIANT dbv1, dbv2; + BOOL free, got_val, bDataWritten; + + BOOL use_default = FALSE; + int source_contact = (use_default ? default_contact : most_online); + + if (source_contact < 0 || source_contact >= num_contacts) return; + + for (i = 0; i < num_settings; i++) { + bDataWritten = FALSE; + for (j = 0; j < num_contacts && !bDataWritten; j++) { + // do source (most online) first + if (j == 0) + hContact = Meta_GetContactHandle(hMeta, source_contact); + else if (j <= source_contact) + hContact = Meta_GetContactHandle(hMeta, j - 1); + else + hContact = Meta_GetContactHandle(hMeta, j); + + if (hContact) { + if ( !module) { + used_mod = GetContactProto(hContact); + if ( !used_mod) + continue; // next contact + } + else used_mod = module; + + if (j == 0 && strcmp(settings[i], "MirVer") == 0) //Always reset MirVer + db_unset(hMeta, (module ? used_mod : META_PROTO), settings[i]); + + got_val = !Mydb_get(hContact, used_mod, settings[i], &dbv2); + if (got_val) { + free = !Mydb_get(hMeta, (module ? used_mod : META_PROTO), settings[i], &dbv1); + + if (strcmp(settings[i], "MirVer") == 0) { + if (db_get_w(hContact, used_mod, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE) { + if ( !free || (dbv1.pszVal == NULL || strcmp(dbv1.pszVal, "") == 0 || strlen(dbv1.pszVal) < 2)) { + db_set(hMeta, (module ? used_mod : META_PROTO), settings[i], &dbv2); + bDataWritten = TRUE; //only break if found something to copy + } + } + } + else { + if ( !free || !dbv_same(&dbv1, &dbv2)) { + db_set(hMeta, (module ? used_mod : META_PROTO), settings[i], &dbv2); + if (dbv2.type == DBVT_ASCIIZ || dbv2.type == DBVT_UTF8) { + if (dbv2.pszVal != NULL && strcmp(dbv2.pszVal, "") != 0) + bDataWritten = TRUE; //only break if found something to copy + } else if (dbv2.type == DBVT_WCHAR) { + if (dbv2.pwszVal != 0 && wcscmp(dbv2.pwszVal, L"") != 0) + bDataWritten = TRUE; //only break if found something to copy + } else + bDataWritten = TRUE; //only break if found something to copy + } + else + bDataWritten = TRUE; + + } + db_free(&dbv2); + if (free)db_free(&dbv1); + } + } + } + } +} + +const char *ProtoSettings[25] = + {"BirthDay", "BirthMonth", "BirthYear", "Age", "Cell", "Cellular", "Homepage", "email", "Email", "e-mail", + "FirstName", "MiddleName", "LastName", "Title", "Timezone", "Gender", "MirVer", "ApparentMode", "IdleTS", "LogonTS", "IP", "RealIP", + "Auth", "ListeningTo", "Country"}; +const char *UserInfoSettings[71] = + {"NickName", "FirstName", "MiddleName", "LastName", "Title", "Timezone", "Gender", "DOBd", "DOBm", "DOBy", + "Mye-mail0", "Mye-mail1", "MyPhone0", "MyPhone1", "MyNotes", "PersonalWWW", + "HomePhone", "HomeFax", "HomeMobile", "HomeStreet", "HomeCity", "HomeState", "HomeZip", "HomeCountry", + "WorkPhone", "WorkFax", "WorkMobile", "WorkStreet", "WorkCity", "WorkState", "WorkZip", "WorkCountry", "Company", "Department", "Position", + "Occupation", "Cellular", "Cell", "Phone", "Notes", + + "e-mail", "e-mail0", "e-mail1", "Homepage", "MaritalStatus", + "CompanyCellular", "CompanyCity", "CompanyState", "CompanyStreet", "CompanyCountry", "Companye-mail", + "CompanyHomepage", "CompanyDepartment", "CompanyOccupation", "CompanyPosition", "CompanyZip", + + "OriginCity", "OriginState", "OriginStreet", "OriginCountry", "OriginZip", + "City", "State", "Street", "Country", "Zip", + + "Language1", "Language2", "Language3", "Partner", "Gender"}; +const char *ContactPhotoSettings[5] = + {"File","Backup","Format","ImageHash","RFile"}; +const char *MBirthdaySettings[3] = + { "BirthDay", "BirthMonth", "BirthYear"}; + +// special handling for status message +// copy from first subcontact with any of these values that has the same status as the most online contact +// szProto: +// clist: "StatusMsg" + +void CopyStatusData(MCONTACT hMeta) +{ + int num_contacts = db_get_dw(hMeta, META_PROTO, "NumContacts", (DWORD)-1), + most_online = Meta_GetContactNumber(Meta_GetMostOnline(hMeta)); + WORD status = db_get_w(hMeta, META_PROTO, "Status", ID_STATUS_OFFLINE); + MCONTACT hContact; + BOOL bDoneStatus = FALSE, bDoneXStatus = FALSE; + + for (int i = 0; i < num_contacts; i++) { + if (i == 0) + hContact = Meta_GetContactHandle(hMeta, most_online); + else if (i <= most_online) + hContact = Meta_GetContactHandle(hMeta, i - 1); + else + hContact = Meta_GetContactHandle(hMeta, i); + + char *szProto = GetContactProto(hContact); + + if (szProto && db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE) == status) { + DBVARIANT dbv; + if ( !bDoneStatus && !Mydb_get(hContact, "CList", "StatusMsg", &dbv)) { + db_set(hMeta, "CList", "StatusMsg", &dbv); + db_free(&dbv); + bDoneStatus = TRUE; + } + if ((!bDoneXStatus) && (!Mydb_get(hContact, szProto, "XStatusId", &dbv)) && dbv.type != DBVT_DELETED) { + db_set_s(hMeta, META_PROTO, "XStatusProto", szProto); + db_set(hMeta, META_PROTO, "XStatusId", &dbv); + + db_free(&dbv); + if ( !Mydb_get(hContact, szProto, "XStatusMsg", &dbv)) { + db_set(hMeta, META_PROTO, "XStatusMsg", &dbv); + db_free(&dbv); + } + if ( !Mydb_get(hContact, szProto, "XStatusName", &dbv)) { + db_set(hMeta, META_PROTO, "XStatusName", &dbv); + db_free(&dbv); + } + bDoneXStatus = TRUE; + } + } + + if (bDoneStatus && bDoneXStatus) + break; + } + + if ( !bDoneStatus) db_unset(hMeta, "CList", "StatusMsg"); + if ( !bDoneXStatus) { + db_unset(hMeta, META_PROTO, "XStatusId"); + db_unset(hMeta, META_PROTO, "XStatusMsg"); + db_unset(hMeta, META_PROTO, "XStatusName"); + } +} + +void Meta_CopyData(MCONTACT hMeta) +{ + if (options.copydata) { + CopyStatusData(hMeta); + + copy_settings_array(hMeta, 0, ProtoSettings, 25); + copy_settings_array(hMeta, "mBirthday", UserInfoSettings, 3); + copy_settings_array(hMeta, "ContactPhoto", ContactPhotoSettings, 5); + + if (options.copy_userinfo) + copy_settings_array(hMeta, "UserInfo", UserInfoSettings, 71); + } +} + + +MCONTACT Meta_GetContactHandle(MCONTACT hMeta, int contact_number) +{ + char buffer[512], buffer2[512]; + int num_contacts = db_get_dw(hMeta, META_PROTO, "NumContacts", 0); + + if (contact_number >= num_contacts || contact_number < 0) return 0; + + strcpy(buffer, "Handle"); + strcat(buffer, _itoa(contact_number, buffer2, 10)); + return (MCONTACT)db_get_dw(hMeta, META_PROTO, buffer, 0); +} + +int Meta_SetHandles(void) +{ + DWORD meta_id, num_contacts, contact_number; + MCONTACT hContact2, hContact = db_find_first(), hNextContact; + char buffer[512]; + TCHAR nick_buffer[128], buffer2[40]; + BOOL found; + + while ( hContact != NULL ) { + if ((meta_id = db_get_dw(hContact, META_PROTO, META_LINK,(DWORD)-1))!=(DWORD)-1) { + // is a subcontact + + // get nick for debug messages + _tcscpy(nick_buffer, _T("meta_id: ")); + _tcscat(nick_buffer, _itot(meta_id, buffer2, 10)); + + contact_number = db_get_dw(hContact, META_PROTO, "ContactNumber", (DWORD)-1); + _tcscat(nick_buffer, _T(", contact num: ")); + _tcscat(nick_buffer, _itot(contact_number, buffer2, 10)); + + if (contact_number < 0) { + // problem! + MessageBox(0, TranslateT("Subcontact contact number < 0 - deleting MetaContact"), nick_buffer, MB_OK | MB_ICONERROR); + //CallService(MS_DB_CONTACT_DELETE, (WPARMA)hContact, 0); + hNextContact = db_find_next(hContact); + Meta_Delete(hContact, (LPARAM)1); + hContact = hNextContact; + continue; + //return 1; + } + + // ensure the window open flag is not present + db_unset(hContact, META_PROTO, "WindowOpen"); + + // find metacontact + found = FALSE; + hContact2 = db_find_first(); + + while ( hContact2 != NULL ) { + if (db_get_dw(hContact2, META_PROTO, META_ID,(DWORD)-1) == meta_id) { + found = TRUE; + + // set handle + db_set_dw(hContact, META_PROTO, "Handle", (DWORD)hContact2); + + // increment contact counter (cleared in Load function) + db_set_b(hContact2, META_PROTO, "ContactCountCheck", + (unsigned char)(db_get_b(hContact2, META_PROTO, "ContactCountCheck", 0) + 1)); + + num_contacts = db_get_dw(hContact2, META_PROTO, "NumContacts", (DWORD)-1); + if (contact_number >= 0 && contact_number < num_contacts) { + // set metacontact's handle to us + char szId[40]; + strcpy(buffer, "Handle"); + strcat(buffer, _itoa((int)contact_number, szId, 10)); + db_set_dw(hContact2, META_PROTO, buffer, (DWORD)hContact); + } + else { + TCHAR buff[256]; + // problem - contact number is greater than meta's number of contacts + mir_sntprintf(buff, SIZEOF(buff), TranslateT("Subcontact contact number (%d) > meta num contacts (%d) - deleting MetaContact"), contact_number, num_contacts); + MessageBox(0, buff, nick_buffer, MB_OK | MB_ICONERROR); + + hNextContact = db_find_next(hContact); + Meta_Delete(hContact, (LPARAM)1); + hContact = hNextContact; + continue; + } + } + + hContact2 = db_find_next(hContact2); + } + + if ( !found) { + // problem - subcontact's meta not found + MessageBox(0, TranslateT("Subcontact's MetaContact not found - deleting MetaContact data"), nick_buffer, MB_OK | MB_ICONERROR); + + // delete meta data + db_unset(hContact, META_PROTO, "IsSubcontact"); + db_unset(hContact, META_PROTO, META_LINK); + db_unset(hContact, META_PROTO, "Handle"); + db_unset(hContact, META_PROTO, "ContactNumber"); + Meta_RestoreGroup(hContact); + db_unset(hContact, META_PROTO, "OldCListGroup"); + + // stop ignoring, if we were + if (options.suppress_status) + CallService(MS_IGNORE_UNIGNORE, hContact, (WPARAM)IGNOREEVENT_USERONLINE); + + } + else { + if ( !db_get_b(hContact, META_PROTO, "IsSubcontact", 0)) + db_set_b(hContact, META_PROTO, "IsSubcontact", 1); + } + } + else db_unset(hContact, META_PROTO, "Handle"); + + if ((meta_id = db_get_dw(hContact, META_PROTO, META_ID,(DWORD)-1))!=(DWORD)-1) { + // is a metacontact + + // get nick for debug messages + _tcscpy(nick_buffer, _T("meta_id: ")); + _tcscat(nick_buffer, _itot(meta_id, buffer2, 10)); + + // ensure the window open flag is not present + db_unset(hContact, META_PROTO, "WindowOpen"); + + // ensure default is reasonable + contact_number = db_get_dw(hContact, META_PROTO, "Default", -1); + num_contacts = db_get_dw(hContact, META_PROTO, "NumContacts", (DWORD)-1); + + if (num_contacts < 0) { + // problem + MessageBox(0, TranslateT("MetaContact number of contacts < 0 - deleting MetaContact"), nick_buffer, MB_OK | MB_ICONERROR); + hNextContact = db_find_next(hContact); + Meta_Delete(hContact, (LPARAM)1); + hContact = hNextContact; + continue; + } + + if (contact_number < 0 || contact_number >= num_contacts) { + // problem + MessageBox(0, TranslateT("MetaContact default contact number out of range - deleting MetaContact"), nick_buffer, MB_OK | MB_ICONERROR); + hNextContact = db_find_next(hContact); + Meta_Delete(hContact, (LPARAM)1); + hContact = hNextContact; + continue; + } + } + + hContact = db_find_next(hContact); + } + + // loop through one more time - check contact counts match + hContact = db_find_first(); + while ( hContact != NULL ) { + if ((meta_id = db_get_dw(hContact, META_PROTO, META_ID,(DWORD)-1))!=(DWORD)-1) { + // get nick for debug messages + + num_contacts = db_get_b(hContact, META_PROTO, "ContactCountCheck", -2); + if (num_contacts != (DWORD)db_get_dw(hContact, META_PROTO, "NumContacts", (DWORD)-1)) { + hNextContact = db_find_next(hContact); + + _tcscpy(nick_buffer, TranslateT("Meta ID: ")); + _tcscat(nick_buffer, _itot(meta_id, buffer2, 10)); + MessageBox(0, TranslateT("MetaContact corrupted - the number of subcontacts is incorrect.\nDeleting MetaContact."), nick_buffer, MB_OK | MB_ICONERROR); + + Meta_Delete(hContact, (LPARAM)1); + hContact = hNextContact; + continue; + } + } + hContact = db_find_next(hContact); + } + + return 0; +} + +/** Hide all contacts linked to any meta contact, and set handle links +* +* Additionally, set all sub contacts and metacontacts to offline so that status notifications are always sent +* +* and ensure metafilter in place +*/ + +#define szMsg LPGEN("The 'MetaContacts Hidden Group' has been added to your contact list.\n\ +This is most likely due to server-side contact information. To fix this, so that\n\ +MetaContacts continues to function correctly, you should:\n\ + - disable MetaContacts using the 'Toggle MetaContacts Off' main menu item\n\ + - move all contacts out of this group\n\ + - synchronize your contacts with the server\n\ + - re-enable MetaContacts") + +int Meta_HideLinkedContacts(void) { + DBVARIANT dbv, dbv2; + DWORD meta_id, num_contacts, contact_number; + WORD status; + char buffer[512], buffer2[512]; + char *szProto, *group_name; + int hGroup = 1; + + MCONTACT hContact2, hContact = db_find_first(); + + // ensure the hidden group does not exist (how this occurs i wonder but there have been reports!) + // (sometimes protocol server side groups are to blame - msn and icq) + if ( !meta_group_hack_disabled) do { + group_name = (char *)CallService(MS_CLIST_GROUPGETNAME, (WPARAM)hGroup, 0); + if (group_name && !strcmp(group_name, META_HIDDEN_GROUP)) { + // disabled because it shows a message box + //CallService(MS_CLIST_GROUPDELETE, (WPARAM)hGroup, 0); + MessageBox(0, TranslateT(szMsg), TranslateT("MetaContacts Warning"), MB_ICONWARNING | MB_OK); + break; + } + hGroup++; + } while(group_name); + + while (hContact != NULL) { + if ((meta_id = db_get_dw(hContact, META_PROTO, META_LINK,(DWORD)-1))!=(DWORD)-1) { + // get contact number + contact_number = db_get_dw(hContact, META_PROTO, "ContactNumber", (DWORD)-1); + + // prepare to update metacontact record of subcontat status + szProto = GetContactProto(hContact); + + // save old group and move to invisible group (i.e. non-existent group) + Meta_SetGroup(hContact); + + // find metacontact + hContact2 = db_find_first(); + + while ( hContact2 != NULL ) { + if (db_get_dw(hContact2, META_PROTO, META_ID,(DWORD)-1) == meta_id) { + num_contacts = db_get_dw(hContact2, META_PROTO, "NumContacts", (DWORD)-1); + if (contact_number >= 0 && contact_number < num_contacts) { + + if ( !szProto) + status = ID_STATUS_OFFLINE; + else + status = db_get_w(hContact, szProto, "Status", ID_STATUS_OFFLINE); + + // update metacontact's record of status for this contact + strcpy(buffer, "Status"); + strcat(buffer, _itoa(contact_number, buffer2, 10)); + db_set_w(hContact2, META_PROTO, buffer, status); + + // update metacontact's record of nick for this contact + if (szProto && !db_get(hContact, szProto, "Nick", &dbv)) { + strcpy(buffer, "Nick"); + strcat(buffer, _itoa(contact_number, buffer2, 10)); + db_set(hContact2, META_PROTO, buffer, &dbv); + + strcpy(buffer, "CListName"); + strcat(buffer, _itoa(contact_number, buffer2, 10)); + if (db_get(hContact, "CList", "MyHandle", &dbv2)) { + db_set(hContact2, META_PROTO, buffer, &dbv); + } else { + db_set(hContact2, META_PROTO, buffer, &dbv2); + db_free(&dbv2); + } + + db_free(&dbv); + } else { + if ( !db_get(hContact, "CList", "MyHandle", &dbv)) { + strcpy(buffer, "CListName"); + strcat(buffer, _itoa(contact_number, buffer2, 10)); + db_set(hContact2, META_PROTO, buffer, &dbv); + db_free(&dbv); + } + } + } + } + + hContact2 = db_find_next(hContact2); + } + + if (options.suppress_status) + CallService(MS_IGNORE_IGNORE, hContact, (WPARAM)IGNOREEVENT_USERONLINE); + } + + hContact = db_find_next(hContact); + } + + // do metacontacts after handles set properly above + hContact = db_find_first(); + while ( hContact != NULL ) { + if (db_get_dw(hContact, META_PROTO, META_ID,(DWORD)-1)!=(DWORD)-1) { + // is a meta contact + MCONTACT hMostOnline = Meta_GetMostOnline(hContact); // set nick + Meta_CopyContactNick(hContact, hMostOnline); + + Meta_FixStatus(hContact); + + } + + hContact = db_find_next(hContact); + } + + return 0; +} + +/** Unhide all contacts linked to any meta contact +* +*/ +int Meta_UnhideLinkedContacts(void) +{ + for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { + if (db_get_dw(hContact, META_PROTO, META_LINK,(DWORD)-1)!=(DWORD)-1) { + // has a link - unhide it + // restore old group + Meta_RestoreGroup(hContact); + } + } + + return 0; +} + +int Meta_HideMetaContacts(int hide) +{ + // set status suppression + if (hide) Meta_SuppressStatus(FALSE); + else Meta_SuppressStatus(options.suppress_status); + + for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { + if (db_get_dw(hContact, META_PROTO, META_ID,(DWORD)-1)!=(DWORD)-1) { + // is a meta contact + if (hide) + db_set_b(hContact, "CList", "Hidden", 1); + else + db_unset(hContact, "CList", "Hidden"); + } + else if (db_get_dw(hContact, META_PROTO, META_LINK,(DWORD)-1)!=(DWORD)-1) { + // when metacontacts are hidden, show subcontacts, and vice versa + if (hide) + Meta_RestoreGroup(hContact); + else + Meta_SetGroup(hContact); + } + } + + return 0; +} + +void Meta_RestoreGroup(MCONTACT hContact) { + + if (meta_group_hack_disabled) return; // clist has called api function to disable group hack - yay! + + // the existence of this service means that clist_meta_mw is active and will do the hiding for us + if (ServiceExists(MS_CLUI_METASUPPORT)) return; + + // show it anyway - users are reporting contacts removed from meta remain 'hidden' + // possible suspect - server side groups cause hidden group hack to fail, users hide contacts via clist->delete->hide option + db_unset(hContact, META_PROTO, "Hidden"); + + if (db_get_b(hContact, META_PROTO, "Hidden", 0) == 1) + { + // if we hid it, unhide it + db_unset(hContact, META_PROTO, "Hidden"); + db_unset(hContact, "CList", "Hidden"); + } else { + DBCONTACTWRITESETTING cws; + + if ( !db_get(hContact, META_PROTO, "OldCListGroup", &cws.value)) { + + if ((cws.value.type == DBVT_ASCIIZ || cws.value.type == DBVT_UTF8) && !strcmp(cws.value.pszVal, META_HIDDEN_GROUP)) { + db_unset(hContact, "CList", "Group"); + } else { + int hGroup = 1; + char *name = 0; + BOOL found = FALSE; + do { + name = (char *)CallService(MS_CLIST_GROUPGETNAME, (WPARAM)hGroup, 0); + if (name && !strcmp(name, cws.value.pszVal)) { + found = TRUE; + break; + } + hGroup++; + } while(name); + + if (found) + db_set(hContact, "CList", "Group", &cws.value); + else { + // put back into metacontact's group + DBVARIANT dbv; + MCONTACT hMeta = (MCONTACT)db_get_dw(hContact, META_PROTO, "Handle", 0); + if (hMeta && !Mydb_get(hMeta, "CList", "Group", &dbv)) { + db_set(hContact, "CList", "Group", &dbv); + db_free(&dbv); + } + else db_unset(hContact, "CList", "Group"); + } + } + db_free(&cws.value); + } + db_unset(hContact, META_PROTO, "OldCListGroup"); + + if ( !db_get(hContact, "CList", "Group", &cws.value)) { + if ((cws.value.type == DBVT_ASCIIZ || cws.value.type == DBVT_UTF8) && !strcmp(cws.value.pszVal, META_HIDDEN_GROUP)) { + db_unset(hContact, "CList", "Group"); + } + db_free(&cws.value); + } + } + + // show it anyway - users are reporting contacts removed from meta remain 'hidden' + // possible suspect - server side groups cause hidden group hack to fail, users hide contacts via clist->delete->hide option + db_unset(hContact, "CList", "Hidden"); +} + +void Meta_SetGroup(MCONTACT hContact) { + char *szProto, *uid; + + if (meta_group_hack_disabled) return; // clist has called api function to disable group hack - yay! + + // the existence of this service means that clist_meta_mw is active and will do the hiding for us + if (ServiceExists(MS_CLUI_METASUPPORT)) return; + + szProto = GetContactProto(hContact); + if (szProto) + uid = (char *)CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); + + if (szProto && uid && (INT_PTR)uid != CALLSERVICE_NOTFOUND && !strcmp(JABBER_UNIQUE_ID_SETTING, uid)) { + // if it's a jabber contact, hide it, and record the fact that it was us who did + db_set_b(hContact, META_PROTO, "Hidden", 1); + db_set_b(hContact, "CList", "Hidden", 1); + } + else { + DBVARIANT dbv; + // save old group and move to invisible group (i.e. non-existent group) + if ( !Mydb_get(hContact, "CList", "Group", &dbv)) { + if ((dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_UTF8) && !strcmp(dbv.pszVal, META_HIDDEN_GROUP)) + ; // it's already in the group (shouldn't be - but maybe a crash) + else + db_set(hContact, META_PROTO, "OldCListGroup", &dbv); + + db_free(&dbv); + } + else db_unset(hContact, META_PROTO, "OldCListGroup"); + + db_set_s(hContact, "CList", "Group", META_HIDDEN_GROUP); + } +} + +int Meta_SuppressStatus(BOOL suppress) +{ + for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { + if (db_get_dw(hContact, META_PROTO, META_LINK,(DWORD)-1)!=(DWORD)-1) { + // is a subcontact + if (suppress) + CallService(MS_IGNORE_IGNORE, hContact, (WPARAM)IGNOREEVENT_USERONLINE); + else + CallService(MS_IGNORE_UNIGNORE, hContact, (WPARAM)IGNOREEVENT_USERONLINE); + } + } + + return 0; +} + +int Meta_CopyContactNick(MCONTACT hMeta, MCONTACT hContact) { + DBVARIANT dbv, dbv_proto; + char *szProto; + + if (options.lockHandle) { + hContact = Meta_GetContactHandle(hMeta, 0); + } + + if ( !hContact) return 1; + + //szProto = GetContactProto(hContact); + // read szProto direct from db, since we do this on load and other szProto plugins may not be loaded yet + if ( !db_get(hContact, "Protocol", "p", &dbv_proto)) { + + szProto = dbv_proto.pszVal; + if (options.clist_contact_name == CNNT_NICK && szProto) { + if ( !Mydb_get(hContact, szProto, "Nick", &dbv)) { + db_set(hMeta, META_PROTO, "Nick", &dbv); + db_free(&dbv); + //CallService(MS_CLIST_INVALIDATEDISPLAYNAME, (WPARAM)hMeta, 0); + //CallService(MS_CLUI_CONTACTRENAMED, (WPARAM)hMeta, 0); + db_free(&dbv_proto); + return 0; + } + } else if (options.clist_contact_name == CNNT_DISPLAYNAME) { + TCHAR *name = pcli->pfnGetContactDisplayName(hContact, GCDNF_TCHAR); + if (name && _tcscmp(name, TranslateT("(Unknown Contact)")) != 0) { + db_set_ts(hMeta, META_PROTO, "Nick", name); + db_free(&dbv_proto); + return 0; + } + } + db_free(&dbv_proto); + } + return 1; +} + +int Meta_SetAllNicks() +{ + for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { + if (db_get_dw(hContact, META_PROTO, META_ID,(DWORD)-1)!=(DWORD)-1) { + MCONTACT most_online = Meta_GetMostOnline(hContact); + Meta_CopyContactNick(hContact, most_online); + Meta_FixStatus(hContact); + Meta_CopyData(hContact); + } + + } + return 0; +} + +int Meta_IsHiddenGroup(const char *group_name) +{ + if (group_name && !strcmp(group_name, META_HIDDEN_GROUP)) + return 1; + + return 0; +} + +int Meta_SwapContacts(MCONTACT hMeta, DWORD contact_number1, DWORD contact_number2) { + DBVARIANT dbv1, dbv2; + + MCONTACT hContact1 = Meta_GetContactHandle(hMeta, contact_number1), + hContact2 = Meta_GetContactHandle(hMeta, contact_number2); + char buff1[512], buff12[512], buff2[512], buff22[512]; + BOOL ok1, ok2; + + // swap the protocol + strcpy(buff1, "Protocol"); + strcat(buff1, _itoa(contact_number1, buff12, 10)); + strcpy(buff2, "Protocol"); + strcat(buff2, _itoa(contact_number2, buff22, 10)); + ok1 = !Mydb_get(hMeta, META_PROTO, buff1, &dbv1); + ok2 = !Mydb_get(hMeta, META_PROTO, buff2, &dbv2); + if (ok1) { + db_set(hMeta, META_PROTO, buff2, &dbv1); + db_free(&dbv1); + } + if (ok2) { + db_set(hMeta, META_PROTO, buff1, &dbv2); + db_free(&dbv2); + } + + // swap the status + strcpy(buff1, "Status"); + strcat(buff1, _itoa(contact_number1, buff12, 10)); + strcpy(buff2, "Status"); + strcat(buff2, _itoa(contact_number2, buff22, 10)); + ok1 = !Mydb_get(hMeta, META_PROTO, buff1, &dbv1); + ok1 = !Mydb_get(hMeta, META_PROTO, buff2, &dbv2); + if (ok1) { + db_set(hMeta, META_PROTO, buff2, &dbv1); + db_free(&dbv1); + } + if (ok2) { + db_set(hMeta, META_PROTO, buff1, &dbv2); + db_free(&dbv2); + } + + // swap the status string + strcpy(buff1, "StatusString"); + strcat(buff1, _itoa(contact_number1, buff12, 10)); + strcpy(buff2, "StatusString"); + strcat(buff2, _itoa(contact_number2, buff22, 10)); + ok1 = !Mydb_get(hMeta, META_PROTO, buff1, &dbv1); + ok2 = !Mydb_get(hMeta, META_PROTO, buff2, &dbv2); + if (ok1) { + db_set(hMeta, META_PROTO, buff2, &dbv1); + db_free(&dbv1); + } + if (ok2) { + db_set(hMeta, META_PROTO, buff1, &dbv2); + db_free(&dbv2); + } + + // swap the login + strcpy(buff1, "Login"); + strcat(buff1, _itoa(contact_number1, buff12, 10)); + strcpy(buff2, "Login"); + strcat(buff2, _itoa(contact_number2, buff22, 10)); + ok1 = !Mydb_get(hMeta, META_PROTO, buff1, &dbv1); + ok2 = !Mydb_get(hMeta, META_PROTO, buff2, &dbv2); + if (ok1) { + db_unset(hMeta, META_PROTO, buff2); + db_set(hMeta, META_PROTO, buff2, &dbv1); + db_free(&dbv1); + } + if (ok2) { + db_unset(hMeta, META_PROTO, buff1); + db_set(hMeta, META_PROTO, buff1, &dbv2); + db_free(&dbv2); + } + + // swap the nick + strcpy(buff1, "Nick"); + strcat(buff1, _itoa(contact_number1, buff12, 10)); + strcpy(buff2, "Nick"); + strcat(buff2, _itoa(contact_number2, buff22, 10)); + ok1 = !Mydb_get(hMeta, META_PROTO, buff1, &dbv1); + ok2 = !Mydb_get(hMeta, META_PROTO, buff2, &dbv2); + if (ok1) { + db_set(hMeta, META_PROTO, buff2, &dbv1); + db_free(&dbv1); + } else { + db_unset(hMeta, META_PROTO, buff2); + } + if (ok2) { + db_set(hMeta, META_PROTO, buff1, &dbv2); + db_free(&dbv2); + } else { + db_unset(hMeta, META_PROTO, buff1); + } + + // swap the clist name + strcpy(buff1, "CListName"); + strcat(buff1, _itoa(contact_number1, buff12, 10)); + strcpy(buff2, "CListName"); + strcat(buff2, _itoa(contact_number2, buff22, 10)); + ok1 = !Mydb_get(hMeta, META_PROTO, buff1, &dbv1); + ok2 = !Mydb_get(hMeta, META_PROTO, buff2, &dbv2); + if (ok1) { + db_set(hMeta, META_PROTO, buff2, &dbv1); + db_free(&dbv1); + } else { + db_unset(hMeta, META_PROTO, buff2); + } + if (ok2) { + db_set(hMeta, META_PROTO, buff1, &dbv2); + db_free(&dbv2); + } else { + db_unset(hMeta, META_PROTO, buff1); + } + + // swap the handle + strcpy(buff1, "Handle"); + strcat(buff1, _itoa(contact_number1, buff12, 10)); + strcpy(buff2, "Handle"); + strcat(buff2, _itoa(contact_number2, buff22, 10)); + ok1 = !Mydb_get(hMeta, META_PROTO, buff1, &dbv1); + ok2 = !Mydb_get(hMeta, META_PROTO, buff2, &dbv2); + if (ok1) { + db_set(hMeta, META_PROTO, buff2, &dbv1); + db_free(&dbv1); + } else { + db_unset(hMeta, META_PROTO, buff2); + } + if (ok2) { + db_set(hMeta, META_PROTO, buff1, &dbv2); + db_free(&dbv2); + } else { + db_unset(hMeta, META_PROTO, buff1); + } + + // finally, inform the contacts of their change in position + db_set_dw(hContact1, META_PROTO, "ContactNumber", (DWORD)contact_number2); + db_set_dw(hContact2, META_PROTO, "ContactNumber", (DWORD)contact_number1); + + return 0; +} + +INT_PTR CALLBACK DlgProcNull(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) { + case WM_INITDIALOG: + { + HWND prog = GetDlgItem(hwndDlg, IDC_PROG); + + TranslateDialogDefault( hwndDlg ); + + SendMessage(prog, PBM_SETPOS, 0, 0); + return TRUE; + } + } + return FALSE; +} + +// function to copy history from one contact to another - courtesy JdGordon (thx) +void copyHistory(MCONTACT hContactFrom, MCONTACT hContactTo) +{ + HANDLE hDbEvent; + DBEVENTINFO dbei; + //char *id; + //DWORD id_length; + //DWORD oldBlobSize; + DWORD time_now = time(0); + DWORD earliest_time = time_now - options.days_history * 24 * 60 * 60; + BYTE *buffer = 0; + HWND progress_dialog, prog; + + if ( !hContactFrom || !hContactTo) return; + + //id = Meta_GetUniqueIdentifier(hContactFrom, &id_length); + //if ( !id) return; + + progress_dialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_COPYPROGRESS), 0, DlgProcNull); + ShowWindow(progress_dialog, SW_SHOW); + + prog = GetDlgItem(progress_dialog, IDC_PROG); + + //CallService(MS_DB_SETSAFETYMODE, (WPARAM)FALSE, 0); + for (hDbEvent = db_event_first(hContactFrom); hDbEvent; hDbEvent = db_event_next(hDbEvent)) + { + // get the event + ZeroMemory(&dbei, sizeof(dbei)); + dbei.cbSize = sizeof(dbei); + + if ((dbei.cbBlob = db_event_getBlobSize(hDbEvent)) == -1) + break; + + buffer = (BYTE *)mir_realloc(buffer, dbei.cbBlob);// + id_length); + dbei.pBlob = buffer; + if ( db_event_get(hDbEvent, &dbei)) + break; + + // i.e. optoins.days_history == 0; + if (time_now == earliest_time) earliest_time = dbei.timestamp; + + if (dbei.timestamp < earliest_time) + continue; + + if (dbei.eventType != EVENTTYPE_MESSAGE && dbei.eventType != EVENTTYPE_FILE && dbei.eventType != EVENTTYPE_URL) + continue; + + if (time_now > earliest_time) { // just in case! + SendMessage(prog, PBM_SETPOS, (WPARAM)(int)(100.0 * (dbei.timestamp - earliest_time) / (time_now - earliest_time)), 0); + UpdateWindow(progress_dialog); + } + + dbei.szModule = META_PROTO; + dbei.flags &= ~DBEF_FIRST; + db_event_add(hContactTo, &dbei); + } + + DestroyWindow(progress_dialog); + if (buffer) mir_free(buffer); + //mir_free(id); +} + +void Meta_FixStatus(MCONTACT hMeta) +{ + MCONTACT most_online = Meta_GetMostOnlineSupporting(hMeta, PFLAGNUM_1, 0); + if (most_online) { + char *szProto = GetContactProto(most_online); + if (szProto) { + WORD status = (WORD)db_get_w(most_online, szProto, "Status", (WORD)ID_STATUS_OFFLINE); + db_set_w(hMeta, META_PROTO, "Status", status); + } + else db_set_w(hMeta, META_PROTO, "Status", (WORD)ID_STATUS_OFFLINE); + } + else db_set_w(hMeta, META_PROTO, "Status", (WORD)ID_STATUS_OFFLINE); +} + +INT_PTR Meta_IsEnabled() { + return db_get_b(0, META_PROTO, "Enabled", 1) && (meta_group_hack_disabled || db_get_b(NULL, "CList", "UseGroups", 1)); +} + + + diff --git a/plugins/!Deprecated/MetaContacts/src/metacontacts.h b/plugins/!Deprecated/MetaContacts/src/metacontacts.h new file mode 100644 index 0000000000..369bdf696c --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/src/metacontacts.h @@ -0,0 +1,224 @@ +/* +MetaContacts Plugin for Miranda IM. + +Copyright © 2004 Universite Louis PASTEUR, STRASBOURG. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/** @file metacontacts.h +* +* Header declaring functions that are accessed in multiple files. +*/ + +#define _CRT_SECURE_NO_DEPRECATE + +#define _WIN32_WINNT 0x0400 +#define _WIN32_IE 0x0300 + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "resource.h" +#include "version.h" + +#define META_PROTO "MetaContacts" +#define META_FILTER "MetaContactsFilter" +#define META_ID "MetaID" +#define META_FILTER_ID "MetaFilterID" +#define META_LINK "MetaLink" + +#define META_HIDDEN_GROUP "MetaContacts Hidden Group" +#define MAX_CONTACTS 20 + +// I can't think of a way around this - mental block + +INT_PTR TranslateMenuFunc(MCONTACT hContact, int i); +extern HGENMENU hMenuContact[MAX_CONTACTS]; + +extern HINSTANCE hInstance; +extern PLUGININFOEX pluginInfo; + +// contact menu items +extern HGENMENU hMenuConvert, hMenuAdd, hMenuEdit, hMenuDelete, hMenuDefault, hMenuForceDefault, hMenuOnOff; + +extern DWORD nextMetaID; +extern int mcStatus; + +INT_PTR Meta_Convert(WPARAM wParam,LPARAM lParam); +INT_PTR Meta_AddTo(WPARAM wParam,LPARAM lParam); +INT_PTR Meta_Edit(WPARAM wParam,LPARAM lParam); +void Meta_RemoveContactNumber(MCONTACT hMeta, int number); +INT_PTR Meta_Delete(WPARAM wParam,LPARAM lParam); +INT_PTR Meta_Default(WPARAM wParam,LPARAM lParam); +INT_PTR Meta_ForceDefault(WPARAM wParam,LPARAM lParam); + +INT_PTR Meta_IsEnabled(); + +int Meta_EqualDBV(DBVARIANT *dbv, DBVARIANT *id); +int Meta_ModifyMenu(WPARAM wParam,LPARAM lParam); +BOOL Meta_Assign(MCONTACT src, MCONTACT dest, BOOL set_as_default); +MCONTACT Meta_GetHandle(const char *protocol, DBVARIANT *id); +int Meta_SetNick(char *proto); +MCONTACT Meta_GetMostOnline(MCONTACT hMeta); +MCONTACT Meta_GetMostOnlineSupporting(MCONTACT hMeta, int pflagnum, unsigned long capability); +int Meta_HideLinkedContacts(void); +int Meta_SetHandles(void); +int Meta_UnhideLinkedContacts(void); +int Meta_GetContactNumber(MCONTACT hContact); +MCONTACT Meta_GetContactHandle(MCONTACT hMeta, int contact_number); +void Meta_RestoreGroup(MCONTACT hContact); +void Meta_SetGroup(MCONTACT hContact); +int Meta_HideMetaContacts(int hide); +int Meta_SuppressStatus(int suppress); +int Meta_CopyContactNick(MCONTACT hMeta, MCONTACT hContact); +void Meta_CopyData(MCONTACT hMeta); +int Meta_SetAllNicks(); +int Meta_IsHiddenGroup(const char *group_name); +int Meta_SwapContacts(MCONTACT hMeta, DWORD contact_number1, DWORD contact_number2); +// function to copy history from one contact to another - courtesy JdGordon with mods (thx) +void copyHistory(MCONTACT hContactFrom, MCONTACT hContactTo); +// inverse +//void Meta_RemoveHistory(HANDLE hContactRemoveFrom, HANDLE hContactSource); +void Meta_FixStatus(MCONTACT hMeta); + +char *Meta_GetUniqueIdentifier(MCONTACT hContact, DWORD *pused); + +INT_PTR Meta_GetCaps(WPARAM wParam,LPARAM lParam); +INT_PTR Meta_GetName(WPARAM wParam,LPARAM lParam); +INT_PTR Meta_LoadIcon(WPARAM wParam,LPARAM lParam); +INT_PTR Meta_SetStatus(WPARAM wParam,LPARAM lParam); +INT_PTR Meta_GetStatus(WPARAM wParam,LPARAM lParam); +INT_PTR Meta_SendMessage(WPARAM wParam,LPARAM lParam); +INT_PTR Meta_RecvMessage(WPARAM wParam,LPARAM lParam); +INT_PTR Meta_ContactMenuFunc(WPARAM wParam, LPARAM lParam); + +INT_PTR CALLBACK Meta_SelectDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK Meta_EditDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +void Meta_InitServices(); +void Meta_CloseHandles(); + +enum MenuDisplayNameType {DNT_UID = 0, DNT_DID = 1}; +enum MenuFunctionType {FT_MSG = 0, FT_MENU = 1, FT_INFO = 2}; +enum CListDisplayNameType {CNNT_NICK = 0, CNNT_DISPLAYNAME = 1}; + +struct MetaOptions +{ + BYTE set_default_on_recv; + BYTE always_use_default; + BYTE suppress_status; + BYTE copy_subcontact_history; + BYTE subcontact_windows; + BYTE metahistory; + BYTE subhistory; + BYTE copydata; + BYTE lockHandle; + BYTE temp_default; + BYTE flash_meta_message_icon; + BYTE copy_userinfo; + BYTE use_proto_recv; + + int menu_contact_label; + int menu_function; + int clist_contact_name; + int days_history; + int set_status_from_offline_delay; +}; + +extern MetaOptions options; + +INT_PTR CALLBACK DlgProcOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK DlgProcOptsPriorities(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +int Meta_WriteOptions(MetaOptions *opt); +int Meta_ReadOptions(MetaOptions *opt); + +int GetDefaufaultPrio(int status); +int GetRealPriority(char *proto, int status); + +// API function headers +INT_PTR MetaAPI_GetMeta(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_GetDefault(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_GetDefaultNum(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_GetMostOnline(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_GetNumContacts(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_GetContact(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_SetDefaultContactNum(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_SetDefaultContact(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_ForceSendContactNum(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_ForceSendContact(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_UnforceSendContact(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_ForceDefault(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_GetForceState(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_GetProtoName(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_ConvertToMeta(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_AddToMeta(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_RemoveFromMeta(WPARAM wParam, LPARAM lParam); +INT_PTR MetaAPI_DisableHiddenGroup(WPARAM wParam, LPARAM lParam); + +// extended db get/write setting functions, that handle unicode +INT_PTR Mydb_get(MCONTACT hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv); + +// IcoLib support +void InitIcons(void); + +typedef enum {I_MENUOFF, I_MENU, I_CONVERT, I_ADD, I_EDIT, I_SETDEFAULT, I_REMOVE} IconIndex; +HICON LoadIconEx(IconIndex i); +HANDLE GetIconHandle(IconIndex i); + +extern HANDLE hEventDefaultChanged, hEventForceSend, hEventUnforceSend, hSubcontactsChanged; + +extern POINT menuMousePoint; + +extern BOOL message_window_api_enabled; + +#define MAX_PROTOCOLS 20 +extern char proto_names[MAX_PROTOCOLS * 128]; + +// used for the 'jabber' hack - i.e. hide contacts instead of moving them to the hidden group +#define JABBER_UNIQUE_ID_SETTING "jid" + +// delay setting status from offline - to help reduce innapropriate status notification popups +#define DEFAULT_SET_STATUS_SLEEP_TIME 15000 // milliseconds + +// service from clist_meta_mw, existence means we don't need to hide subcontacts (woohoo - thanks FYR) +#define MS_CLUI_METASUPPORT "CLUI/MetaContactSupport" + +extern BOOL meta_group_hack_disabled; + +#ifndef MS_CLUI_GETVERSION +#define MS_CLUI_GETVERSION "CLUI/GetVersion" + +#define szDelMsg LPGEN("You are going to remove all the contacts associated with this MetaContact.\nThis will delete the MetaContact.\n\nProceed Anyway?") + +#endif diff --git a/plugins/!Deprecated/MetaContacts/src/resource.h b/plugins/!Deprecated/MetaContacts/src/resource.h new file mode 100644 index 0000000000..87507e2f35 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/src/resource.h @@ -0,0 +1,75 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by MetaContacts.rc +// +#define IDC_BTN_REM 3 +#define IDD_METASELECT 101 +#define IDI_MCMENU 103 +#define IDD_METAEDIT 108 +#define IDD_OPTIONS 109 +#define IDD_COPYPROGRESS 110 +#define IDD_DELPROGRESS 111 +#define IDI_MCMENUOFF 116 +#define IDI_MCEDIT 118 +#define IDI_MCREMOVE 119 +#define IDI_MCCONVERT 120 +#define IDI_MCADD 121 +#define IDI_MCSETDEFAULT 122 +#define IDD_PRIORITIES 123 +#define IDD_HISTORY 124 +#define IDC_METALIST 1002 +#define IDC_ONLYAVAIL 1005 +#define IDC_DEFAULT 1008 +#define IDC_NAME 1009 +#define IDC_FRAME 1013 +#define IDC_VALIDATE 1014 +#define IDC_CHK_SETDEFAULTRECV 1016 +#define IDC_CHK_ALWAYSUSEDEFAULT 1017 +#define IDC_CHECK1 1018 +#define IDC_CHK_SUPPRESSSTATUS 1018 +#define IDC_CHK_FORCEDEFAULT 1018 +#define IDC_CHK_SRT 1018 +#define IDC_CHK_DEFAULT 1018 +#define IDC_RAD_UID 1019 +#define IDC_RAD_DID 1020 +#define IDC_RAD_MSG 1021 +#define IDC_RAD_MENU 1022 +#define IDC_RAD_INFO 1023 +#define IDC_RAD_NICK 1024 +#define IDC_RAD_NAME 1025 +#define IDC_LST_CONTACTS 1026 +#define IDC_BTN_SETDEFAULT 1027 +#define IDC_CHK_COPYHISTORY 1027 +#define IDC_BTN_UP 1028 +#define IDC_BTN_DOWN 1029 +#define IDC_ED_NAME 1030 +#define IDC_ED_DEFAULT 1031 +#define IDC_BTN_SETDEFAULT2 1031 +#define IDC_BTN_SETOFFLINE 1031 +#define IDC_ED_DAYS 1033 +#define IDC_PROG 1034 +#define IDC_CHK_SUBWINDOW 1035 +#define IDC_CHK_METAHISTORY 1036 +#define IDC_CHK_SUBHISTORY 1037 +#define IDC_CHK_COPYDATA 1038 +#define IDC_CHK_LOCKHANDLE 1039 +#define IDC_CHK_TEMPDEFAULT 1040 +#define IDC_ED_PRIORITY 1042 +#define IDC_SP_PRIORITY 1043 +#define IDC_CMB_STATUS 1044 +#define IDC_BUTTON2 1048 +#define IDC_BTN_RESET 1048 +#define IDC_CMB_PROTOCOL 1062 + +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 125 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1049 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/!Deprecated/MetaContacts/src/stdafx.cpp b/plugins/!Deprecated/MetaContacts/src/stdafx.cpp new file mode 100644 index 0000000000..eb479c620d --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/src/stdafx.cpp @@ -0,0 +1,18 @@ +/* +Copyright (C) 2012-14 Miranda NG project (http://miranda-ng.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "metacontacts.h" \ No newline at end of file diff --git a/plugins/!Deprecated/MetaContacts/src/version.h b/plugins/!Deprecated/MetaContacts/src/version.h new file mode 100644 index 0000000000..3e17b2a8e4 --- /dev/null +++ b/plugins/!Deprecated/MetaContacts/src/version.h @@ -0,0 +1,14 @@ +#define __MAJOR_VERSION 0 +#define __MINOR_VERSION 14 +#define __RELEASE_NUM 0 +#define __BUILD_NUM 13 + +#include + +#define __PLUGIN_NAME "MetaContacts" +#define __FILENAME "MetaContacts.dll" +#define __DESCRIPTION "Merges contacts from the same or different protocols into one." +#define __AUTHOR "J. Schaal & S. Ellis" +#define __AUTHOREMAIL "mail@scottellis.com.au" +#define __AUTHORWEB "http://miranda-ng.org/p/MetaContacts/" +#define __COPYRIGHT "© 2005,2006 Scott Ellis" -- cgit v1.2.3