From c30391220326446fcdf5ff90a445401947b101a4 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Tue, 16 Apr 2013 20:30:13 +0000 Subject: SkypeStatusChange plugin added git-svn-id: http://svn.miranda-ng.org/main/trunk@4459 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- .../SkypeStatusChange/SkypeStatusChange_10.vcxproj | 208 +++++++++++++ .../SkypeStatusChange_10.vcxproj.filters | 47 +++ .../SkypeStatusChange/SkypeStatusChange_11.vcxproj | 213 +++++++++++++ .../SkypeStatusChange_11.vcxproj.filters | 47 +++ plugins/SkypeStatusChange/res/Chkboxs.bmp | Bin 0 -> 778 bytes plugins/SkypeStatusChange/res/SkypeStatusChange.rc | 125 ++++++++ plugins/SkypeStatusChange/res/Version.rc | 38 +++ plugins/SkypeStatusChange/src/Version.h | 14 + plugins/SkypeStatusChange/src/main.cpp | 329 +++++++++++++++++++++ plugins/SkypeStatusChange/src/options.cpp | 317 ++++++++++++++++++++ plugins/SkypeStatusChange/src/resource.h | 22 ++ plugins/SkypeStatusChange/src/stdafx.cpp | 18 ++ plugins/SkypeStatusChange/src/stdafx.h | 171 +++++++++++ 13 files changed, 1549 insertions(+) create mode 100644 plugins/SkypeStatusChange/SkypeStatusChange_10.vcxproj create mode 100644 plugins/SkypeStatusChange/SkypeStatusChange_10.vcxproj.filters create mode 100644 plugins/SkypeStatusChange/SkypeStatusChange_11.vcxproj create mode 100644 plugins/SkypeStatusChange/SkypeStatusChange_11.vcxproj.filters create mode 100644 plugins/SkypeStatusChange/res/Chkboxs.bmp create mode 100644 plugins/SkypeStatusChange/res/SkypeStatusChange.rc create mode 100644 plugins/SkypeStatusChange/res/Version.rc create mode 100644 plugins/SkypeStatusChange/src/Version.h create mode 100644 plugins/SkypeStatusChange/src/main.cpp create mode 100644 plugins/SkypeStatusChange/src/options.cpp create mode 100644 plugins/SkypeStatusChange/src/resource.h create mode 100644 plugins/SkypeStatusChange/src/stdafx.cpp create mode 100644 plugins/SkypeStatusChange/src/stdafx.h (limited to 'plugins/SkypeStatusChange') diff --git a/plugins/SkypeStatusChange/SkypeStatusChange_10.vcxproj b/plugins/SkypeStatusChange/SkypeStatusChange_10.vcxproj new file mode 100644 index 0000000000..9cd186e5fa --- /dev/null +++ b/plugins/SkypeStatusChange/SkypeStatusChange_10.vcxproj @@ -0,0 +1,208 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + SkypeStatusChange + {10F78F26-2B20-4158-869F-CB29533B4C2C} + + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.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 + + + + false + Full + Level3 + true + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + OnlyExplicitInline + false + Size + false + stdafx.h + Use + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + true + true + Windows + 0x30040000 + $(IntDir)$(TargetName).lib + true + true + false + $(ProfileDir)..\..\bin10\lib + /PDBALTPATH:%_PDB% + + + + + MultiThreadedDebugDLL + false + Disabled + Level3 + true + EditAndContinue + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + EnableFastChecks + false + stdafx.h + Use + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + true + true + Windows + 0x30040000 + $(IntDir)$(TargetName).lib + false + $(ProfileDir)..\..\bin10\lib + + + + + false + Full + Level3 + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + Default + OnlyExplicitInline + Size + false + stdafx.h + Use + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + true + true + Windows + 0x30040000 + $(IntDir)$(TargetName).lib + false + $(ProfileDir)..\..\bin10\lib + /PDBALTPATH:%_PDB% + + + + + MultiThreadedDebugDLL + false + Disabled + Level3 + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + EnableFastChecks + false + stdafx.h + Use + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + true + true + Windows + 0x30040000 + $(IntDir)$(TargetName).lib + false + $(ProfileDir)..\..\bin10\lib + + + + + + + + + + + + + + + + Create + + + + + + \ No newline at end of file diff --git a/plugins/SkypeStatusChange/SkypeStatusChange_10.vcxproj.filters b/plugins/SkypeStatusChange/SkypeStatusChange_10.vcxproj.filters new file mode 100644 index 0000000000..674c2e0d8e --- /dev/null +++ b/plugins/SkypeStatusChange/SkypeStatusChange_10.vcxproj.filters @@ -0,0 +1,47 @@ + + + + + {08a21636-368d-4feb-8d0d-0a27f237e1a2} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {9e6f20dc-3391-4299-9f74-e91d4f984ad3} + h;hpp;hxx;hm;inl + + + {18fd6180-ebb2-4558-b945-c4dac823f11b} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + Resource Files + + + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/plugins/SkypeStatusChange/SkypeStatusChange_11.vcxproj b/plugins/SkypeStatusChange/SkypeStatusChange_11.vcxproj new file mode 100644 index 0000000000..fca1a9bece --- /dev/null +++ b/plugins/SkypeStatusChange/SkypeStatusChange_11.vcxproj @@ -0,0 +1,213 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + SkypeStatusChange + {10F78F26-2B20-4158-869F-CB29533B4C2C} + + + + DynamicLibrary + Unicode + true + v110_xp + + + DynamicLibrary + Unicode + v110_xp + + + DynamicLibrary + Unicode + true + v110_xp + + + DynamicLibrary + Unicode + v110_xp + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.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 + + + + false + Full + Level3 + true + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + OnlyExplicitInline + false + Size + stdafx.h + Use + false + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + true + true + Windows + 0x30040000 + $(IntDir)$(TargetName).lib + true + true + false + $(ProfileDir)..\..\bin11\lib + /PDBALTPATH:%_PDB% + + + + + MultiThreadedDebugDLL + false + Disabled + Level3 + true + EditAndContinue + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + EnableFastChecks + stdafx.h + Use + false + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + true + true + Windows + 0x30040000 + $(IntDir)$(TargetName).lib + false + $(ProfileDir)..\..\bin11\lib + false + + + + + false + Full + Level3 + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN64;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + Default + OnlyExplicitInline + Size + stdafx.h + Use + false + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + true + true + Windows + 0x30040000 + $(IntDir)$(TargetName).lib + false + $(ProfileDir)..\..\bin11\lib + /PDBALTPATH:%_PDB% + + + + + MultiThreadedDebugDLL + false + Disabled + Level3 + ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) + WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + EnableFastChecks + stdafx.h + Use + false + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + true + true + Windows + 0x30040000 + $(IntDir)$(TargetName).lib + false + $(ProfileDir)..\..\bin11\lib + + + + + + + + + + + + + + + + Create + + + + + + \ No newline at end of file diff --git a/plugins/SkypeStatusChange/SkypeStatusChange_11.vcxproj.filters b/plugins/SkypeStatusChange/SkypeStatusChange_11.vcxproj.filters new file mode 100644 index 0000000000..674c2e0d8e --- /dev/null +++ b/plugins/SkypeStatusChange/SkypeStatusChange_11.vcxproj.filters @@ -0,0 +1,47 @@ + + + + + {08a21636-368d-4feb-8d0d-0a27f237e1a2} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {9e6f20dc-3391-4299-9f74-e91d4f984ad3} + h;hpp;hxx;hm;inl + + + {18fd6180-ebb2-4558-b945-c4dac823f11b} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + Resource Files + + + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/plugins/SkypeStatusChange/res/Chkboxs.bmp b/plugins/SkypeStatusChange/res/Chkboxs.bmp new file mode 100644 index 0000000000..b38f775223 Binary files /dev/null and b/plugins/SkypeStatusChange/res/Chkboxs.bmp differ diff --git a/plugins/SkypeStatusChange/res/SkypeStatusChange.rc b/plugins/SkypeStatusChange/res/SkypeStatusChange.rc new file mode 100644 index 0000000000..16f5cb194b --- /dev/null +++ b/plugins/SkypeStatusChange/res/SkypeStatusChange.rc @@ -0,0 +1,125 @@ +// 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 resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1251) + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_TREE_STATE BITMAP "res\\Chkboxs.bmp" +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Russian (Russia) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +#pragma code_page(1251) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Russian (Russia) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL +#pragma code_page(1252) + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG_SETTINGS DIALOGEX 0, 0, 312, 218 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "Synchronize status message",IDC_CHECK_SYNCK_STATUS_MSG, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,179,180,10 + LTEXT "&Check any protocol or any status to exclude it from synchronization:",IDC_STATIC,7,13,298,8 + CONTROL "",IDC_TREE_PROTOCOLS,"SysTreeView32",WS_BORDER | WS_HSCROLL | WS_TABSTOP,16,26,225,146 + CONTROL "Synchronize if current status differs from previous one",IDC_CHECK_STATUSES, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,194,194,10 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_DIALOG_SETTINGS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 305 + TOPMARGIN, 7 + BOTTOMMARGIN, 211 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/plugins/SkypeStatusChange/res/Version.rc b/plugins/SkypeStatusChange/res/Version.rc new file mode 100644 index 0000000000..5bfbab4754 --- /dev/null +++ b/plugins/SkypeStatusChange/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/SkypeStatusChange/src/Version.h b/plugins/SkypeStatusChange/src/Version.h new file mode 100644 index 0000000000..6af144d9ef --- /dev/null +++ b/plugins/SkypeStatusChange/src/Version.h @@ -0,0 +1,14 @@ +#define __MAJOR_VERSION 0 +#define __MINOR_VERSION 0 +#define __RELEASE_NUM 0 +#define __BUILD_NUM 18 + +#define __FILEVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM + +#define __PLUGIN_NAME "SkypeStatusChange" +#define __FILENAME "SkypeStatusChange.dll" +#define __DESCRIPTION "Skype Status Change according to miranda-Status" +#define __AUTHOR "Dioksin" +#define __AUTHOREMAIL "dioksin@ua.fm" +#define __AUTHORWEB "http://miranda-ng.org/" +#define __COPYRIGHT "© 2009-2010 Dioksin" diff --git a/plugins/SkypeStatusChange/src/main.cpp b/plugins/SkypeStatusChange/src/main.cpp new file mode 100644 index 0000000000..1157f4dd13 --- /dev/null +++ b/plugins/SkypeStatusChange/src/main.cpp @@ -0,0 +1,329 @@ +#include "stdafx.h" +#include "resource.h" +#include "Version.h" + +#pragma comment(lib, "Comctl32.lib") + +int hLangpack = 0; + +int SSC_OptInitialise(WPARAM wp, LPARAM lp); + +PLUGININFOEX g_pluginInfo = +{ + sizeof(PLUGININFOEX), + __PLUGIN_NAME, + PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), + __DESCRIPTION, + __AUTHOR, + __AUTHOREMAIL, + __COPYRIGHT, + __AUTHORWEB, + UNICODE_AWARE, //not transient + { 0x2925520b, 0x6677, 0x4658, { 0x8b, 0xad, 0x56, 0x61, 0xd1, 0x3e, 0x46, 0x92 } } +}; + +HINSTANCE g_hModule = NULL; + +UINT g_MsgIDSkypeControlAPIAttach = 0; +UINT g_MsgIDSkypeControlAPIDiscover = 0; +HWND g_wndMainWindow = NULL; + +HANDLE g_hThread = NULL; +HANDLE g_hEventShutdown = NULL; + +bool g_bMirandaIsShutdown = false; + +enum +{ + SKYPECONTROLAPI_ATTACH_SUCCESS = 0, // Client is successfully attached and API window handle can be found in wParam parameter + SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION = 1, // Skype has acknowledged connection request and is waiting for confirmation from the user. + // The client is not yet attached and should wait for SKYPECONTROLAPI_ATTACH_SUCCESS message + SKYPECONTROLAPI_ATTACH_REFUSED = 2, // User has explicitly denied access to client + SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE = 3, // API is not available at the moment. For example, this happens when no user is currently logged in. + // Client should wait for SKYPECONTROLAPI_ATTACH_API_AVAILABLE broadcast before making any further + // connection attempts. + SKYPECONTROLAPI_ATTACH_API_AVAILABLE = 0x8001 +}; + +LPCTSTR g_pszSkypeWndClassName = _T("SkypeHelperWindow{155198f0-8749-47b7-ac53-58f2ac70844c}"); + +const CMirandaStatus2SkypeStatus g_aStatusCode[10] = +{ + {ID_STATUS_AWAY, "AWAY",_T("Away")}, + {ID_STATUS_NA, "AWAY",_T("NA")}, // removed in Skype 5 + {ID_STATUS_DND, "DND",_T("DND")}, + {ID_STATUS_ONLINE, "ONLINE",_T("Online")}, + {ID_STATUS_FREECHAT, "ONLINE",_T("Free for chat")}, // SKYPEME status doesn't work in Skype 4! + {ID_STATUS_OFFLINE, "OFFLINE",_T("Offline")}, + {ID_STATUS_INVISIBLE, "INVISIBLE",_T("Invisible")}, + {ID_STATUS_OCCUPIED,"DND",_T("Occupied")}, + {ID_STATUS_ONTHEPHONE,"DND",_T("On the phone")}, + {ID_STATUS_OUTTOLUNCH,"DND",_T("Out to lunch")} +}; + +enum{INVALID_INDEX = 0xFFFFFFFF}; + +class CStatusInfo +{ +public: + CStatusInfo() : m_nStatusIndex(INVALID_INDEX){m_szModule[0] = '\0';} + + size_t StatusIndex()const{return m_nStatusIndex;} + void StatusIndex(size_t val){m_nStatusIndex = val;} + + const char* Module()const{return m_szModule;} + void Module(const char* val) + { + if (val) + strncpy_s(m_szModule,val,strlen(val)); + else + m_szModule[0] = '\0'; + } + +private: + char m_szModule[MAXMODULELABELLENGTH]; + size_t m_nStatusIndex; +}; + +COptions g_Options; +CStatusInfo g_CurrStatusInfo; +CRITICAL_SECTION g_csStatusInfo; + +int SSC_OnProtocolAck(WPARAM, LPARAM lParam) +{ + if (g_bMirandaIsShutdown) + return 0; + + ACKDATA* pAckData = reinterpret_cast(lParam); + if (pAckData->type != ACKTYPE_STATUS || pAckData->result != ACKRESULT_SUCCESS || !pAckData->szModule) + return 0; + + if (!g_Options.IsProtocolExcluded(pAckData->szModule)) { + int nStatus = CallProtoService(pAckData->szModule,PS_GETSTATUS,0,0); + for(size_t i = 0; i < SIZEOF(g_aStatusCode); ++i) { + const CMirandaStatus2SkypeStatus& ms = g_aStatusCode[i]; + if (ms.m_nMirandaStatus == nStatus) { + int nPrevStatus; + if ((false == g_Options.IsProtocolStatusExcluded(pAckData->szModule,nStatus)) + && ((false == g_Options.GetSyncStatusStateFlag()) + || (false == g_Options.GetPreviousStatus(pAckData->szModule,nPrevStatus)) + || (nPrevStatus != nStatus))) + { + { + mir_cslock guard(g_csStatusInfo); + g_CurrStatusInfo.StatusIndex(i); + g_CurrStatusInfo.Module(pAckData->szModule); + } + if (0 == ::PostMessage(HWND_BROADCAST,g_MsgIDSkypeControlAPIDiscover,(WPARAM)g_wndMainWindow,0)) { + mir_cslock guard(g_csStatusInfo); + g_CurrStatusInfo.StatusIndex(INVALID_INDEX); + g_CurrStatusInfo.Module(NULL); + } + else g_Options.SetPreviousStatus(pAckData->szModule,nStatus); + } + break; + } + } + } + + return 0; +} + +static void ThreadFunc(void*) +{ + while (true) { + MSG msg; + if (TRUE == ::PeekMessage(&msg,g_wndMainWindow,0,0,PM_NOREMOVE)) { + while(::GetMessage(&msg,g_wndMainWindow,0,0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + else { + DWORD dwResult = ::MsgWaitForMultipleObjects(1,&g_hEventShutdown,FALSE,INFINITE,QS_ALLEVENTS); + _ASSERT(WAIT_FAILED != dwResult); + if (WAIT_OBJECT_0 == dwResult) + break; + } + } +} + +bool ProtoServiceExists(const char *szModule,const char *szService) +{ + char str[MAXMODULELABELLENGTH * 2]; + strncpy_s(str,szModule,strlen(szModule)); + strncat_s(str,szService,strlen(szService)); + + return (ServiceExists(str) > 0); +} + + +LRESULT APIENTRY SkypeAPI_WindowProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) +{ + LRESULT lReturnCode = 0; + bool bIssueDefProc = false; + + switch(msg) { + case WM_DESTROY: + g_wndMainWindow = NULL; + break; + + case WM_COPYDATA: + break; + + default: + if (msg == g_MsgIDSkypeControlAPIAttach) { + switch(lp) { + case SKYPECONTROLAPI_ATTACH_SUCCESS: + { + CStatusInfo si; + { + mir_cslock guard(g_csStatusInfo); + si = g_CurrStatusInfo; + } + if (INVALID_INDEX != si.StatusIndex() && si.StatusIndex() < SIZEOF(g_aStatusCode)) { + const CMirandaStatus2SkypeStatus& ms = g_aStatusCode[si.StatusIndex()]; + HWND wndSkypeAPIWindow = reinterpret_cast(wp); + + enum{BUFFER_SIZE = 256}; + char szSkypeCmd[BUFFER_SIZE]; + const char szSkypeCmdSetStatus[] = "SET USERSTATUS "; + ::strncpy_s(szSkypeCmd,szSkypeCmdSetStatus,sizeof(szSkypeCmdSetStatus)/sizeof(szSkypeCmdSetStatus[0])); + ::strncat_s(szSkypeCmd,ms.m_pszSkypeStatus,strlen(ms.m_pszSkypeStatus)); + DWORD cLength = static_cast(strlen(szSkypeCmd)); + + COPYDATASTRUCT oCopyData; + oCopyData.dwData=0; + oCopyData.lpData = szSkypeCmd; + oCopyData.cbData = cLength+1; + SendMessage(wndSkypeAPIWindow,WM_COPYDATA,(WPARAM)hWnd,(LPARAM)&oCopyData); + if (g_Options.GetSyncStatusMsgFlag()) { + TCHAR* pszStatusMsg = NULL; + if (true == ProtoServiceExists(si.Module(), PS_GETMYAWAYMSG)) + pszStatusMsg = reinterpret_cast(CallProtoService(si.Module(),PS_GETMYAWAYMSG,(WPARAM)ms.m_nMirandaStatus,SGMA_TCHAR)); + + if ((NULL == pszStatusMsg) || (CALLSERVICE_NOTFOUND == reinterpret_cast(pszStatusMsg))) + pszStatusMsg = reinterpret_cast(CallService(MS_AWAYMSG_GETSTATUSMSGT,(WPARAM)ms.m_nMirandaStatus,0)); + + if (pszStatusMsg && reinterpret_cast(pszStatusMsg) != CALLSERVICE_NOTFOUND) { + char* pMsg = mir_utf8encodeT(pszStatusMsg); + mir_free(pszStatusMsg); + + const char szSkypeCmdSetStatusMsg[] = "SET PROFILE MOOD_TEXT "; + ::strncpy_s(szSkypeCmd,szSkypeCmdSetStatusMsg,sizeof(szSkypeCmdSetStatusMsg)/sizeof(szSkypeCmdSetStatusMsg[0])); + ::strncat_s(szSkypeCmd,pMsg,strlen(pMsg)); + mir_free(pMsg); + + DWORD cLength = static_cast(strlen(szSkypeCmd)); + + oCopyData.dwData=0; + oCopyData.lpData = szSkypeCmd; + oCopyData.cbData = cLength+1; + SendMessage(wndSkypeAPIWindow,WM_COPYDATA,(WPARAM)hWnd,(LPARAM)&oCopyData); + } + } + } + } + break; + + case SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION: + break; + + case SKYPECONTROLAPI_ATTACH_REFUSED: + break; + + case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE: + break; + + case SKYPECONTROLAPI_ATTACH_API_AVAILABLE: + break; + } + lReturnCode=1; + } + else bIssueDefProc = true; + break; + } + + if (true == bIssueDefProc) + lReturnCode = DefWindowProc(hWnd, msg, wp, lp); + + return lReturnCode; +} + +int SSC_OnPreShutdown(WPARAM/* wParam*/, LPARAM/* lParam*/) +{ + g_bMirandaIsShutdown = true; + BOOL b = SetEvent(g_hEventShutdown); + _ASSERT(b && "SetEvent failed"); + + DWORD dwResult = ::WaitForSingleObject(g_hThread,INFINITE); + _ASSERT(WAIT_FAILED != dwResult); + + b = ::CloseHandle(g_hEventShutdown); + _ASSERT(b && "CloseHandle event"); + + if (g_wndMainWindow) { + b = DestroyWindow(g_wndMainWindow); + _ASSERT(b && "DestoryWindow"); + g_wndMainWindow = NULL; + } + + UnregisterClass(g_pszSkypeWndClassName,g_hModule); + return 0; +} + +/******************************* INSTALLATION PROCEDURES *****************************/ + +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + if (fdwReason == DLL_PROCESS_ATTACH) + g_hModule = hinstDLL; + + return TRUE; +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &g_pluginInfo; +} + +extern "C" int __declspec(dllexport) Load() +{ + mir_getLP(&g_pluginInfo); + InitializeCriticalSection(&g_csStatusInfo); + + g_MsgIDSkypeControlAPIAttach = ::RegisterWindowMessage(_T("SkypeControlAPIAttach")); + g_MsgIDSkypeControlAPIDiscover = ::RegisterWindowMessage(_T("SkypeControlAPIDiscover")); + if ((0 == g_MsgIDSkypeControlAPIAttach)|| (0 == g_MsgIDSkypeControlAPIDiscover)) + return 1; + + WNDCLASS oWindowClass = { 0 }; + oWindowClass.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS; + oWindowClass.lpfnWndProc = (WNDPROC)&SkypeAPI_WindowProc; + oWindowClass.hInstance = g_hModule; + oWindowClass.lpszClassName = g_pszSkypeWndClassName; + if (!RegisterClass(&oWindowClass)) + return 1; + + g_wndMainWindow = CreateWindowEx( WS_EX_APPWINDOW|WS_EX_WINDOWEDGE, + g_pszSkypeWndClassName,_T(""), WS_BORDER|WS_SYSMENU|WS_MINIMIZEBOX, + CW_USEDEFAULT, CW_USEDEFAULT, 128, 128, NULL, 0, g_hModule, 0); + if (g_wndMainWindow == NULL) + return 1; + + g_bMirandaIsShutdown = false; + g_hEventShutdown = ::CreateEvent(NULL,TRUE,FALSE,NULL); + + g_hThread = mir_forkthread(ThreadFunc, NULL); + + HookEvent(ME_PROTO_ACK,SSC_OnProtocolAck); + HookEvent(ME_SYSTEM_PRESHUTDOWN,SSC_OnPreShutdown); + HookEvent(ME_OPT_INITIALISE,SSC_OptInitialise); + return 0; +} + +extern "C" __declspec(dllexport) int Unload(void) // Executed on DLL unload +{ + DeleteCriticalSection(&g_csStatusInfo); + return 0; +} diff --git a/plugins/SkypeStatusChange/src/options.cpp b/plugins/SkypeStatusChange/src/options.cpp new file mode 100644 index 0000000000..476feaae21 --- /dev/null +++ b/plugins/SkypeStatusChange/src/options.cpp @@ -0,0 +1,317 @@ +#include "stdafx.h" +#include "resource.h" + +///////////////////////////////////////////////////////////////////////////////////////////// + +struct CTreeItemData +{ + enum EType + { + Protocol, + Status + }; + + EType m_nType; + char* m_pszModule; + int m_nStatus; +}; + +enum ETreeCheckBoxState +{ + // tree check box state + TCBS_NOSTATEBOX = 0, + TCBS_UNCHECKED = 1, + TCBS_CHECKED = 2, + TCBS_DISABLE_UNCHECKED = 3, + TCBS_DISABLE_CHECKED = 4, +}; + +HTREEITEM tree_insert_item(HWND hDlg, HWND hwndTree, TCHAR *pName, HTREEITEM htiParent, ETreeCheckBoxState nState, CTreeItemData *pData) +{ + TVINSERTSTRUCT tvi = { 0 }; + tvi.hParent = htiParent; + tvi.hInsertAfter = TVI_LAST; + tvi.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_STATE; + tvi.item.pszText = pName; + tvi.item.lParam = reinterpret_cast(pData); + tvi.item.stateMask = TVIS_STATEIMAGEMASK; + tvi.item.state = INDEXTOSTATEIMAGEMASK(nState); + return TreeView_InsertItem(hwndTree,&tvi); +} + +void InitProtocolTree(HWND hDlg,HWND hwndTreeCtrl) +{ + int cAccounts = 0; + PROTOACCOUNT** ppAccount; + + enum{OFFLINE_STATUS_INDEX = 5}; + + ProtoEnumAccounts(&cAccounts, &ppAccount); + for(int i = 0; i < cAccounts;++i) + { + PROTOACCOUNT* pAccount = ppAccount[i]; + CTreeItemData* pItemData = new CTreeItemData; + pItemData->m_nType = CTreeItemData::Protocol; + pItemData->m_pszModule = pAccount->szModuleName; + + bool bProtocolExcluded = g_Options.IsProtocolExcluded(pAccount->szModuleName); + HTREEITEM hti = tree_insert_item(hDlg,hwndTreeCtrl,pAccount->tszAccountName,TVI_ROOT,((true == bProtocolExcluded) ? TCBS_CHECKED : TCBS_UNCHECKED),pItemData); + if (hti) + { + int nStatusBits = CallProtoService(pAccount->szModuleName,PS_GETCAPS,PFLAGNUM_2,0); + int nStatusExcluded = CallProtoService(pAccount->szModuleName,PS_GETCAPS,PFLAGNUM_5,0); + pItemData = new CTreeItemData; + pItemData->m_nType = CTreeItemData::Status; + pItemData->m_pszModule = pAccount->szModuleName; + pItemData->m_nStatus = ID_STATUS_OFFLINE; + bool bStatusExcluded = g_Options.IsProtocolStatusExcluded(pAccount->szModuleName,pItemData->m_nStatus); + ETreeCheckBoxState nState = TCBS_UNCHECKED; + if (bProtocolExcluded) { + if (bStatusExcluded) + nState = TCBS_DISABLE_CHECKED; + else + nState = TCBS_DISABLE_UNCHECKED; + } + else { + if (bStatusExcluded) + nState = TCBS_CHECKED; + else + nState = TCBS_UNCHECKED; + } + tree_insert_item(hDlg,hwndTreeCtrl,TranslateTS(g_aStatusCode[OFFLINE_STATUS_INDEX].m_ptszStatusName),hti,nState,pItemData); + for(size_t k = 0; k < SIZEOF(g_aStatusCode); ++k) { + const CMirandaStatus2SkypeStatus& m2s = g_aStatusCode[k]; + unsigned long statusFlags = Proto_Status2Flag(m2s.m_nMirandaStatus); + if ((m2s.m_nMirandaStatus != ID_STATUS_OFFLINE) && (nStatusBits & statusFlags) && !(nStatusExcluded & statusFlags)) { + pItemData = new CTreeItemData; + pItemData->m_nType = CTreeItemData::Status; + pItemData->m_pszModule = pAccount->szModuleName; + pItemData->m_nStatus = m2s.m_nMirandaStatus; + bool bStatusExcluded = g_Options.IsProtocolStatusExcluded(pAccount->szModuleName,pItemData->m_nStatus); + if (bProtocolExcluded) { + if (bStatusExcluded) + nState = TCBS_DISABLE_CHECKED; + else + nState = TCBS_DISABLE_UNCHECKED; + } + else { + if (bStatusExcluded) + nState = TCBS_CHECKED; + else + nState = TCBS_UNCHECKED; + } + + tree_insert_item(hDlg,hwndTreeCtrl,TranslateTS(m2s.m_ptszStatusName),hti,nState,pItemData); + } + } + + TreeView_Expand(hwndTreeCtrl,hti,TVE_EXPAND); + } + } +} + +inline HTREEITEM tree_get_child_item(HWND hwndTreeCtrl,HTREEITEM hti) +{ + return TreeView_GetChild(hwndTreeCtrl,hti); +} + +inline HTREEITEM tree_get_next_sibling_item(HWND hwndTreeCtrl,HTREEITEM hti) +{ + return TreeView_GetNextSibling(hwndTreeCtrl,hti); +} + +const CTreeItemData* get_item_data(HWND hwndTreeCtrl,HTREEITEM hti) +{ + TVITEM tvi = {0}; + tvi.hItem = hti; + tvi.mask = TVIF_PARAM|TVIF_HANDLE; + if (TRUE == ::SendMessage(hwndTreeCtrl,TVM_GETITEM,0,reinterpret_cast(&tvi))) { + CTreeItemData* pData = reinterpret_cast(tvi.lParam); + return pData; + } + return NULL; +} + + +inline ETreeCheckBoxState tree_get_state_image(HWND hwndTree,HTREEITEM hti) +{ + TVITEM tvi; + tvi.hItem = hti; + tvi.mask = TVIF_STATE|TVIF_HANDLE; + tvi.stateMask = TVIS_STATEIMAGEMASK; + if (TRUE == ::SendMessage(hwndTree,TVM_GETITEM,0,reinterpret_cast(&tvi))) + { + UINT nState = (tvi.state >> 12); + return static_cast(nState); + } + + _ASSERT(!"we should never get here!"); + return TCBS_UNCHECKED; +} + +void FreeMemory(HWND hwndTreeCtrl,HTREEITEM hti) +{ + for(HTREEITEM h = tree_get_child_item(hwndTreeCtrl,hti);h;h = tree_get_next_sibling_item(hwndTreeCtrl,h)) { + FreeMemory(hwndTreeCtrl,h); + const CTreeItemData* pData = get_item_data(hwndTreeCtrl,h); + if (pData) + delete pData; + } +} + +bool tree_set_item_state(HWND hwndTree,HTREEITEM hti,ETreeCheckBoxState nState) +{ + TVITEM tvi; + ZeroMemory(&tvi,sizeof(tvi)); + + tvi.mask = TVIF_STATE|TVIF_HANDLE; + tvi.hItem = hti; + + tvi.stateMask = TVIS_STATEIMAGEMASK; + tvi.state = INDEXTOSTATEIMAGEMASK(nState); + + return TRUE == ::SendMessage(hwndTree,TVM_SETITEM,0,reinterpret_cast(&tvi)); +} + +void disable_children(HWND hwndTree,HTREEITEM htiParent,bool bDisable) +{ + for(HTREEITEM hti = tree_get_child_item(hwndTree,htiParent);hti;hti = tree_get_next_sibling_item(hwndTree,hti)) { + ETreeCheckBoxState nState = tree_get_state_image(hwndTree,hti); + if (bDisable) { + if (TCBS_CHECKED == nState) + nState = TCBS_DISABLE_CHECKED; + else if (TCBS_UNCHECKED == nState) + nState = TCBS_DISABLE_UNCHECKED; + } + else { + if (TCBS_DISABLE_CHECKED == nState) + nState = TCBS_CHECKED; + else if (TCBS_DISABLE_UNCHECKED == nState) + nState = TCBS_UNCHECKED; + } + tree_set_item_state(hwndTree,hti,nState); + } +} + +void save_exclusion_list(HWND hwndTree,HTREEITEM htiParent) +{ + for(HTREEITEM hti = tree_get_child_item(hwndTree,htiParent);hti;hti = tree_get_next_sibling_item(hwndTree,hti)) { + const CTreeItemData* pData = get_item_data(hwndTree,hti); + ETreeCheckBoxState nState = tree_get_state_image(hwndTree,hti); + if (CTreeItemData::Protocol == pData->m_nType) { + g_Options.ExcludeProtocol(pData->m_pszModule,TCBS_CHECKED == nState); + save_exclusion_list(hwndTree,hti); + } + else g_Options.ExcludeProtocolStatus(pData->m_pszModule,pData->m_nStatus,((TCBS_CHECKED == nState) || (TCBS_DISABLE_CHECKED == nState))); + } +} + +class CImageListWrapper +{ +public: + CImageListWrapper() + : m_hImageList(ImageList_LoadImage(g_hModule,MAKEINTRESOURCE(IDB_TREE_STATE),16,0,RGB(255,255,255),IMAGE_BITMAP,LR_DEFAULTCOLOR)) + { + } + + ~CImageListWrapper() + { + if (m_hImageList) + ImageList_Destroy(m_hImageList); + } + + operator HIMAGELIST()const + { + return m_hImageList; + } + +private: + HIMAGELIST m_hImageList; +}; + +HIMAGELIST get_image_list() +{ + static CImageListWrapper wrapper; + return wrapper; +} + +static INT_PTR CALLBACK SettingsDlgProc(HWND hdlg,UINT msg,WPARAM wp,LPARAM lp) +{ + switch(msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hdlg); + { + HWND hwndTreeCtrl = GetDlgItem(hdlg,IDC_TREE_PROTOCOLS); + HIMAGELIST hImage = get_image_list(); + if (hImage) + TreeView_SetImageList(hwndTreeCtrl,hImage,TVSIL_STATE); + InitProtocolTree(hdlg,hwndTreeCtrl); + } + CheckDlgButton(hdlg,IDC_CHECK_SYNCK_STATUS_MSG,(true == g_Options.GetSyncStatusMsgFlag()) ? 1 : 0); + CheckDlgButton(hdlg,IDC_CHECK_STATUSES,(true == g_Options.GetSyncStatusStateFlag()) ? 1 : 0); + return TRUE; + + case WM_NOTIFY: + { + LPNMHDR pNMHDR = reinterpret_cast(lp); + switch(pNMHDR->code) { + case PSN_APPLY: + save_exclusion_list(GetDlgItem(hdlg,IDC_TREE_PROTOCOLS),TVI_ROOT); + g_Options.SetSyncStatusMsgFlag(1 == IsDlgButtonChecked(hdlg,IDC_CHECK_SYNCK_STATUS_MSG)); + g_Options.SetSyncStatusStateFlag(1 == IsDlgButtonChecked(hdlg,IDC_CHECK_STATUSES)); + break; + + case NM_CLICK: + if (IDC_TREE_PROTOCOLS == wp) { + DWORD pos = ::GetMessagePos(); + + HWND hwndTree = ::GetDlgItem(hdlg,IDC_TREE_PROTOCOLS); + + TVHITTESTINFO tvhti; + tvhti.pt.x = LOWORD(pos); + tvhti.pt.y = HIWORD(pos); + ::ScreenToClient(hwndTree,&(tvhti.pt)); + + HTREEITEM hti = reinterpret_cast(::SendMessage(hwndTree,TVM_HITTEST,0,reinterpret_cast(&tvhti))); + if (hti && (tvhti.flags&(TVHT_ONITEMSTATEICON|TVHT_ONITEMICON))) { + ETreeCheckBoxState nState = tree_get_state_image(hwndTree,hti); + if (TCBS_CHECKED == nState || TCBS_UNCHECKED == nState) { + if (TCBS_CHECKED == nState) + nState = TCBS_UNCHECKED; + else + nState = TCBS_CHECKED; + + tree_set_item_state(hwndTree,hti,nState); + disable_children(hwndTree,hti,TCBS_CHECKED == nState); + PropSheet_Changed(::GetParent(hdlg),hdlg); + } + } + } + } + } + break; + + case WM_COMMAND: + if (BN_CLICKED == HIWORD(wp) && ((IDC_CHECK_SYNCK_STATUS_MSG == LOWORD(wp)) || (IDC_CHECK_STATUSES == LOWORD(wp)))) + PropSheet_Changed(::GetParent(hdlg),hdlg); + break; + + case WM_DESTROY: + FreeMemory(GetDlgItem(hdlg,IDC_TREE_PROTOCOLS),TVI_ROOT); + break; + } + return FALSE; +} + +int SSC_OptInitialise(WPARAM wp, LPARAM lp) +{ + OPTIONSDIALOGPAGE odp = { sizeof(odp) }; + odp.position = 910000000; + odp.hInstance = g_hModule; + odp.pszTitle = LPGEN("Change Skype Status"); + odp.pszGroup = LPGEN("Plugins"); + odp.pszTemplate = MAKEINTRESOURCEA(IDD_DIALOG_SETTINGS); + odp.pfnDlgProc = SettingsDlgProc; + Options_AddPage(wp, &odp); + return 0; +} diff --git a/plugins/SkypeStatusChange/src/resource.h b/plugins/SkypeStatusChange/src/resource.h new file mode 100644 index 0000000000..ccead65830 --- /dev/null +++ b/plugins/SkypeStatusChange/src/resource.h @@ -0,0 +1,22 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by SkypeStatusChange.rc +// +#define IDD_DIALOG_SETTINGS 101 +#define IDB_BITMAP1 102 +#define IDB_TREE_STATE 102 +#define IDC_CHECK_SYNCK_STATUS_MSG 1001 +#define IDC_TREE_PROTOCOLS 1003 +#define IDC_CHECK1 1004 +#define IDC_CHECK_STATUSES 1004 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1005 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/SkypeStatusChange/src/stdafx.cpp b/plugins/SkypeStatusChange/src/stdafx.cpp new file mode 100644 index 0000000000..1ddfafbbbd --- /dev/null +++ b/plugins/SkypeStatusChange/src/stdafx.cpp @@ -0,0 +1,18 @@ +/* +Copyright (C) 2012-13 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 "stdafx.h" \ No newline at end of file diff --git a/plugins/SkypeStatusChange/src/stdafx.h b/plugins/SkypeStatusChange/src/stdafx.h new file mode 100644 index 0000000000..f6c0589707 --- /dev/null +++ b/plugins/SkypeStatusChange/src/stdafx.h @@ -0,0 +1,171 @@ +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MODULENAME "Change Skype Status" + +class COptions +{ + enum + { + cssOnline = 0x00000001, + cssOffline = 0x00000002, + cssInvisible = 0x00000004, + cssShortAway = 0x00000008, + cssLongAway = 0x00000010, + cssLightDND = 0x00000020, + cssHeavyDND = 0x00000040, + cssFreeChart = 0x00000080, + cssOutToLunch = 0x00000100, + cssOnThePhone = 0x00000200, + cssIdle = 0x00000400, + cssAll = 0x80000000 + }; + + static unsigned long Status2Flag(int status) + { + switch(status) + { + case ID_STATUS_ONLINE: return cssOnline; + case ID_STATUS_OFFLINE: return cssOffline; + case ID_STATUS_INVISIBLE: return cssInvisible; + case ID_STATUS_OUTTOLUNCH: return cssOutToLunch; + case ID_STATUS_ONTHEPHONE: return cssOnThePhone; + case ID_STATUS_AWAY: return cssShortAway; + case ID_STATUS_NA: return cssLongAway; + case ID_STATUS_OCCUPIED: return cssLightDND; + case ID_STATUS_DND: return cssHeavyDND; + case ID_STATUS_FREECHAT: return cssFreeChart; + case ID_STATUS_IDLE: return cssIdle; + } + return 0; + } + + struct PrevStatus + { + PrevStatus(const char *_proto, int _status) : + szProto(mir_strdup(_proto)), + iStatus(_status) + {} + + mir_ptr szProto; + int iStatus; + }; + + OBJLIST m_aProtocol2Status; + static int CompareStatuses(const PrevStatus *p1, const PrevStatus *p2) + { return strcmp(p1->szProto, p2->szProto); + } + +public: + COptions() : + m_aProtocol2Status(3, CompareStatuses) + {} + + bool IsProtocolExcluded(const char* pszProtocol)const + { + DWORD dwSettings = db_get_dw(NULL,pszProtocol,"ChangeSkypeStatus_Exclusions",0); + return ((dwSettings&cssAll) ? true : false); + } + + bool IsProtocolStatusExcluded(const char* pszProtocol,int nStatus)const + { + DWORD dwSettings = db_get_dw(NULL,pszProtocol,"ChangeSkypeStatus_Exclusions",0); + return ((dwSettings&Status2Flag(nStatus)) ? true : false); + } + + void ExcludeProtocol(const char* pszProtocol,bool bExclude) + { + DWORD dwSettings = db_get_dw(NULL,pszProtocol,"ChangeSkypeStatus_Exclusions",0); + if (bExclude) + dwSettings |=cssAll; + else + dwSettings &= ~cssAll; + + db_set_dw(NULL,pszProtocol,"ChangeSkypeStatus_Exclusions",dwSettings); + } + + void ExcludeProtocolStatus(const char* pszProtocol,int nStatus,bool bExclude) + { + DWORD dwSettings = db_get_dw(NULL,pszProtocol,"ChangeSkypeStatus_Exclusions",0); + if (bExclude) + dwSettings |=Status2Flag(nStatus); + else + dwSettings &= ~Status2Flag(nStatus); + + db_set_dw(NULL,pszProtocol,"ChangeSkypeStatus_Exclusions",dwSettings); + } + + bool GetSyncStatusMsgFlag()const + { + return db_get_b(NULL,MODULENAME,"SyncStatusMsg",false) > 0; + } + + bool GetSyncStatusStateFlag()const + { + return db_get_b(NULL,MODULENAME,"SyncStatusState",false) > 0; + } + + void SetSyncStatusMsgFlag(bool b) + { + db_set_b(NULL,MODULENAME,"SyncStatusMsg",b); + } + + void SetSyncStatusStateFlag(bool b) + { + db_set_b(NULL,MODULENAME,"SyncStatusState",b); + } + + bool GetPreviousStatus(const char* pszProtocol,int& nStatus)const + { + int i = m_aProtocol2Status.getIndex((PrevStatus*)&pszProtocol); + if (i != -1) { + nStatus = m_aProtocol2Status[i].iStatus; + return true; + } + + return false; + } + + void SetPreviousStatus(const char* pszProtocol,int nStatus) + { + int i = m_aProtocol2Status.getIndex((PrevStatus*)&pszProtocol); + if (i != -1) + m_aProtocol2Status[i].iStatus = nStatus; + else + m_aProtocol2Status.insert( new PrevStatus(pszProtocol, nStatus)); + } +}; + +extern COptions g_Options; + +///////////////////////////////////////////////////////////////////////////////////////// + +struct CMirandaStatus2SkypeStatus +{ + int m_nMirandaStatus; + LPCSTR m_pszSkypeStatus; + LPCTSTR m_ptszStatusName; +}; + +extern const CMirandaStatus2SkypeStatus g_aStatusCode[10]; + +///////////////////////////////////////////////////////////////////////////////////////// + +extern HINSTANCE g_hModule; \ No newline at end of file -- cgit v1.2.3