summaryrefslogtreecommitdiff
path: root/plugins/SkypeStatusChange/src/options.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/SkypeStatusChange/src/options.cpp')
-rw-r--r--plugins/SkypeStatusChange/src/options.cpp317
1 files changed, 317 insertions, 0 deletions
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<LPARAM>(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<LPARAM>(&tvi))) {
+ CTreeItemData* pData = reinterpret_cast<CTreeItemData*>(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<LPARAM>(&tvi)))
+ {
+ UINT nState = (tvi.state >> 12);
+ return static_cast<ETreeCheckBoxState>(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<LPARAM>(&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<LPNMHDR>(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<HTREEITEM>(::SendMessage(hwndTree,TVM_HITTEST,0,reinterpret_cast<LPARAM>(&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;
+}