diff options
author | aunsane <aunsane@gmail.com> | 2017-01-06 16:19:32 +0300 |
---|---|---|
committer | aunsane <aunsane@gmail.com> | 2017-01-06 20:10:47 +0300 |
commit | b7336b2fc97092442ce643532f67466868a87812 (patch) | |
tree | 718b87c37090fe8bf7ae88b9d5da9b3b957c3e3c /plugins/StatusManager/src/AdvancedAutoAway | |
parent | ac1d88965de3022be2f484c2f58185ae75b4fe00 (diff) |
StatusManager: #662
- files splitted by folders
- main.cpp cleanup
- project cleanup
Diffstat (limited to 'plugins/StatusManager/src/AdvancedAutoAway')
4 files changed, 1394 insertions, 0 deletions
diff --git a/plugins/StatusManager/src/AdvancedAutoAway/aaa_msgoptions.cpp b/plugins/StatusManager/src/AdvancedAutoAway/aaa_msgoptions.cpp new file mode 100644 index 0000000000..2484440b2a --- /dev/null +++ b/plugins/StatusManager/src/AdvancedAutoAway/aaa_msgoptions.cpp @@ -0,0 +1,179 @@ +/* + AdvancedAutoAway Plugin for Miranda-IM (www.miranda-im.org) + Copyright 2003-2006 P. Boon + + 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 +*/ + +#include "..\stdafx.h" + +extern char *StatusModeToDbSetting(int status,const char *suffix); + +void DisableDialog(HWND hwndDlg) +{ + EnableWindow(GetDlgItem(hwndDlg, IDC_STATUS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_STATUSMSG), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARIABLESHELP), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_RADUSECUSTOM), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_RADUSEMIRANDA), FALSE); +} + +INT_PTR CALLBACK DlgProcAutoAwayMsgOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static AAMSGSETTING** settings; + static int last, count; + + switch( msg ) { + case WM_INITDIALOG: + TranslateDialogDefault( hwndDlg ); + { + ShowWindow(GetDlgItem(hwndDlg, IDC_VARIABLESHELP), ServiceExists(MS_VARS_SHOWHELP)?SW_SHOW:SW_HIDE); + count = 0; + last = -1; + + PROTOACCOUNT** proto; + int protoCount = 0; + Proto_EnumAccounts(&protoCount, &proto); + if (protoCount <= 0) + { + DisableDialog(hwndDlg); + break; + } + + DWORD protoModeMsgFlags = 0; + for (int i=0; i < protoCount; i++) + if (CallProtoService(proto[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND & ~PF1_INDIVMODEMSG) + protoModeMsgFlags |= CallProtoService( proto[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0 ); + + if (protoModeMsgFlags == 0) + { + DisableDialog(hwndDlg); + break; + } + + settings = ( AAMSGSETTING** )malloc(sizeof(AAMSGSETTING*)); + count = 0; + for (int i=0; i < _countof(statusModeList); i++ ) { + if ( !( protoModeMsgFlags & Proto_Status2Flag( statusModeList[i] ))) + continue; + + int j = SendDlgItemMessage(hwndDlg, IDC_STATUS, CB_ADDSTRING, 0, (LPARAM)pcli->pfnGetStatusModeDescription(statusModeList[i], 0)); + SendDlgItemMessage( hwndDlg, IDC_STATUS, CB_SETITEMDATA, j, statusModeList[i] ); + settings = ( AAMSGSETTING** )realloc(settings, (count+1)*sizeof(AAMSGSETTING*)); + settings[count] = ( AAMSGSETTING* )malloc(sizeof(AAMSGSETTING)); + settings[count]->status = statusModeList[i]; + + DBVARIANT dbv; + if ( !db_get(NULL, AAAMODULENAME, StatusModeToDbSetting(statusModeList[i],SETTING_STATUSMSG), &dbv)) { + settings[count]->msg = ( char* )malloc(mir_strlen(dbv.pszVal) + 1); + mir_strcpy(settings[count]->msg, dbv.pszVal); + db_free(&dbv); + } + else settings[count]->msg = NULL; + + settings[count]->useCustom = db_get_b(NULL, AAAMODULENAME, StatusModeToDbSetting(statusModeList[i], SETTING_MSGCUSTOM), FALSE); + count += 1; + } + SendDlgItemMessage(hwndDlg,IDC_STATUS,CB_SETCURSEL,0,0); + SendMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDC_STATUS,CBN_SELCHANGE),0); + } + break; + + case WM_COMMAND: + if ( ((HIWORD(wParam) == EN_CHANGE) || (HIWORD(wParam) == BN_CLICKED)) && ((HWND)lParam == GetFocus())) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + + switch(LOWORD(wParam)) { + case IDC_RADUSEMIRANDA: + CheckDlgButton(hwndDlg, IDC_RADUSECUSTOM, BST_UNCHECKED == IsDlgButtonChecked(hwndDlg, IDC_RADUSEMIRANDA) ? BST_CHECKED : BST_UNCHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_STATUSMSG), IsDlgButtonChecked(hwndDlg, IDC_RADUSECUSTOM)); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARIABLESHELP), IsDlgButtonChecked(hwndDlg, IDC_RADUSECUSTOM)); + settings[SendDlgItemMessage(hwndDlg,IDC_STATUS,CB_GETCURSEL,0,0)]->useCustom = IsDlgButtonChecked(hwndDlg, IDC_RADUSECUSTOM); + break; + + case IDC_RADUSECUSTOM: + CheckDlgButton(hwndDlg, IDC_RADUSEMIRANDA, BST_UNCHECKED == IsDlgButtonChecked(hwndDlg, IDC_RADUSECUSTOM) ? BST_CHECKED : BST_UNCHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_STATUSMSG), IsDlgButtonChecked(hwndDlg, IDC_RADUSECUSTOM)); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARIABLESHELP), IsDlgButtonChecked(hwndDlg, IDC_RADUSECUSTOM)); + settings[SendDlgItemMessage(hwndDlg,IDC_STATUS,CB_GETCURSEL,0,0)]->useCustom = IsDlgButtonChecked(hwndDlg, IDC_RADUSECUSTOM); + break; + + case IDC_STATUS: + if ( HIWORD( wParam ) == CBN_SELCHANGE ) { + int i = SendDlgItemMessage(hwndDlg,IDC_STATUS,CB_GETCURSEL,0,0); + int len = SendDlgItemMessage(hwndDlg, IDC_STATUSMSG, WM_GETTEXTLENGTH, 0, 0); + if ( last != -1 ) { + if (settings[last]->msg == NULL) + settings[last]->msg = ( char* )malloc(len+1); + else + settings[last]->msg = (char*)realloc(settings[last]->msg, len+1); + GetDlgItemTextA(hwndDlg, IDC_STATUSMSG, settings[last]->msg, (len+1)); + } + + if (i != -1) { + if (settings[i]->msg != NULL) + SetDlgItemTextA(hwndDlg, IDC_STATUSMSG, settings[i]->msg); + else { + ptrW msgw((wchar_t*)CallService(MS_AWAYMSG_GETSTATUSMSGW, settings[i]->status, 0)); + SetDlgItemText(hwndDlg, IDC_STATUSMSG, (msgw != NULL) ? msgw : L""); + } + + if (settings[i]->useCustom) { + EnableWindow(GetDlgItem(hwndDlg, IDC_STATUSMSG), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARIABLESHELP), TRUE); + CheckDlgButton(hwndDlg, IDC_RADUSECUSTOM, BST_CHECKED); + CheckDlgButton(hwndDlg, IDC_RADUSEMIRANDA, BST_UNCHECKED); + } + else { + EnableWindow(GetDlgItem(hwndDlg, IDC_STATUSMSG), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARIABLESHELP), FALSE); + CheckDlgButton(hwndDlg, IDC_RADUSEMIRANDA, BST_CHECKED); + CheckDlgButton(hwndDlg, IDC_RADUSECUSTOM, BST_UNCHECKED); + } + } + last = i; + } + break; + + case IDC_VARIABLESHELP: + CallService(MS_VARS_SHOWHELP, (WPARAM)GetDlgItem(hwndDlg, IDC_STATUSMSG), 0); + break; + } + break; + + case WM_NOTIFY: + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: + SendMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDC_STATUS,CBN_SELCHANGE),0); + for (int i=0; i < count; i++ ) { + db_set_b(NULL, AAAMODULENAME, StatusModeToDbSetting(settings[i]->status,SETTING_MSGCUSTOM), (BYTE)settings[i]->useCustom); + if ( (settings[i]->useCustom) && (settings[i]->msg != NULL) && (settings[i]->msg[0] != '\0')) + db_set_s(NULL, AAAMODULENAME, StatusModeToDbSetting(settings[i]->status,SETTING_STATUSMSG), settings[i]->msg); + } + break; + } + break; + + case WM_DESTROY: + for (int i=0; i < count; i++ ) { + free(settings[i]->msg); + free(settings[i]); + } + free(settings); + break; + } + + return FALSE; +} diff --git a/plugins/StatusManager/src/AdvancedAutoAway/aaa_options.cpp b/plugins/StatusManager/src/AdvancedAutoAway/aaa_options.cpp new file mode 100644 index 0000000000..93204a033d --- /dev/null +++ b/plugins/StatusManager/src/AdvancedAutoAway/aaa_options.cpp @@ -0,0 +1,523 @@ +/* +AdvancedAutoAway Plugin for Miranda-IM (www.miranda-im.org) +Copyright 2003-2006 P. Boon + +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 +*/ + +#include "..\stdafx.h" + +int LoadAutoAwaySetting(TAAAProtoSetting &autoAwaySetting, char* protoName); + +INT_PTR CALLBACK DlgProcAutoAwayMsgOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +static BOOL bSettingSame = FALSE; + +///////////////////////////////////////////////////////////////////////////////////////// +// Dialog service functions + +static int WriteAutoAwaySetting(TAAAProtoSetting &autoAwaySetting, char *protoName) +{ + char setting[128]; + mir_snprintf(setting, "%s_OptionFlags", protoName); + db_set_w(NULL, AAAMODULENAME, setting, (WORD)autoAwaySetting.optionFlags); + mir_snprintf(setting, "%s_AwayTime", protoName); + db_set_w(NULL, AAAMODULENAME, setting, (WORD)autoAwaySetting.awayTime); + mir_snprintf(setting, "%s_NATime", protoName); + db_set_w(NULL, AAAMODULENAME, setting, (WORD)autoAwaySetting.naTime); + mir_snprintf(setting, "%s_StatusFlags", protoName); + db_set_w(NULL, AAAMODULENAME, setting, (WORD)autoAwaySetting.statusFlags); + mir_snprintf(setting, "%s_Lv1Status", protoName); + db_set_w(NULL, AAAMODULENAME, setting, (WORD)autoAwaySetting.lv1Status); + mir_snprintf(setting, "%s_Lv2Status", protoName); + db_set_w(NULL, AAAMODULENAME, setting, (WORD)autoAwaySetting.lv2Status); + + return 0; +} + +static void SetDialogItems(HWND hwndDlg, TAAAProtoSetting *setting) +{ + bool bIsTimed = (setting->optionFlags & FLAG_ONMOUSE) != 0; + bool bSetNA = (setting->optionFlags & FLAG_SETNA) != 0; + bool bSaver = (setting->optionFlags & FLAG_ONSAVER) != 0; + bool bFullScr = (setting->optionFlags & FLAG_FULLSCREEN) != 0; + + CheckDlgButton(hwndDlg, IDC_FULLSCREEN, bFullScr ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SCREENSAVE, bSaver ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_ONLOCK, (setting->optionFlags & FLAG_ONLOCK) != 0 ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_TIMED, bIsTimed ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SETNA, bSetNA ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CONFIRM, (setting->optionFlags & FLAG_CONFIRM) != 0 ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_RESETSTATUS, (setting->optionFlags & FLAG_RESET) != 0 ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_MONITORMIRANDA, (setting->optionFlags & FLAG_MONITORMIRANDA) != 0 ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_LV2ONINACTIVE, (setting->optionFlags & FLAG_LV2ONINACTIVE) != 0 ? BST_CHECKED : BST_UNCHECKED); + + SetDlgItemInt(hwndDlg, IDC_AWAYTIME, setting->awayTime, FALSE); + SetDlgItemInt(hwndDlg, IDC_NATIME, setting->naTime, FALSE); + + EnableWindow(GetDlgItem(hwndDlg, IDC_SETNA), bIsTimed); + EnableWindow(GetDlgItem(hwndDlg, IDC_LV2ONINACTIVE), bIsTimed && bSetNA); + EnableWindow(GetDlgItem(hwndDlg, IDC_MONITORMIRANDA), bIsTimed); + EnableWindow(GetDlgItem(hwndDlg, IDC_AWAYTIME), bIsTimed); + EnableWindow(GetDlgItem(hwndDlg, IDC_LV1AFTERSTR), bIsTimed); + EnableWindow(GetDlgItem(hwndDlg, IDC_LV1STATUS), bIsTimed || bSaver || bFullScr); + EnableWindow(GetDlgItem(hwndDlg, IDC_STATUSLIST), bIsTimed || bSaver || bFullScr); + EnableWindow(GetDlgItem(hwndDlg, IDC_RESETSTATUS), (bIsTimed || bSaver || bFullScr) && IsDlgButtonChecked(hwndDlg, IDC_LV2ONINACTIVE)); + EnableWindow(GetDlgItem(hwndDlg, IDC_CONFIRM), (bIsTimed || bSaver || bFullScr) && IsDlgButtonChecked(hwndDlg, IDC_LV2ONINACTIVE) && IsDlgButtonChecked(hwndDlg, IDC_RESETSTATUS)); + EnableWindow(GetDlgItem(hwndDlg, IDC_NATIME), bSetNA && bIsTimed); + EnableWindow(GetDlgItem(hwndDlg, IDC_SETNASTR), bSetNA && bIsTimed); + EnableWindow(GetDlgItem(hwndDlg, IDC_SETNASTR), bSetNA && bIsTimed); + EnableWindow(GetDlgItem(hwndDlg, IDC_LV2STATUS), bSetNA && bIsTimed); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROTOCOL), !bSettingSame); +} + +static TAAAProtoSetting* GetSetting(HWND hwndDlg, TAAAProtoSetting *sameSetting) +{ + if (bSettingSame) + return sameSetting; + + int iItem = SendDlgItemMessage(hwndDlg, IDC_PROTOCOL, CB_GETCURSEL, 0, 0); + if (iItem == -1) + return NULL; + + INT_PTR iData = (INT_PTR)SendDlgItemMessage(hwndDlg, IDC_PROTOCOL, CB_GETITEMDATA, iItem, 0); + return (iData == -1) ? NULL : (TAAAProtoSetting*)iData; +} + +static void SetDialogStatus(HWND hwndDlg, TAAAProtoSetting *sameSetting) +{ + TAAAProtoSetting *setting = GetSetting(hwndDlg, sameSetting); + if (setting == NULL) + return; + + // create columns + HWND hList = GetDlgItem(hwndDlg, IDC_STATUSLIST); + ListView_SetExtendedListViewStyleEx(hList, LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES, LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES); + + LVCOLUMN lvCol = { 0 }; + lvCol.mask = LVCF_WIDTH | LVCF_TEXT; + lvCol.pszText = TranslateT("Status"); + lvCol.cx = 118; + ListView_InsertColumn(hList, 0, &lvCol); + + // get pointer to settings + SetDialogItems(hwndDlg, setting); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Rules dialog window procedure + +static TAAAProtoSettingList optionSettings(10, AAACompareSettings); + +static INT_PTR CALLBACK DlgProcAutoAwayRulesOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static TAAAProtoSetting* sameSetting; + TAAAProtoSetting *setting; + static int init; + + switch (msg) { + case WM_INITDIALOG: + init = TRUE; + TranslateDialogDefault(hwndDlg); + + // copy the settings + optionSettings = autoAwaySettings; + + sameSetting = (TAAAProtoSetting*)malloc(sizeof(TAAAProtoSetting)); + LoadAutoAwaySetting(*sameSetting, SETTING_ALL); + + // fill list from currentProtoSettings + { + for (int i = 0; i < optionSettings.getCount(); i++) { + TAAAProtoSetting &p = optionSettings[i]; + int item = SendDlgItemMessage(hwndDlg, IDC_PROTOCOL, CB_ADDSTRING, 0, (LPARAM)p.tszAccName); + SendDlgItemMessage(hwndDlg, IDC_PROTOCOL, CB_SETITEMDATA, item, (LPARAM)&p); + } + } + // set cursor to first protocol + SendDlgItemMessage(hwndDlg, IDC_PROTOCOL, CB_SETCURSEL, 0, 0); + + // status list + SetDialogStatus(hwndDlg, sameSetting); + + SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_PROTOCOL, (LPARAM)0x11111111); + init = FALSE; + break; + + case WM_COMMAND: + if ((HIWORD(wParam) == EN_CHANGE || HIWORD(wParam) == BN_CLICKED) && (HWND)lParam == GetFocus()) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + + setting = GetSetting(hwndDlg, sameSetting); + if (!setting) + break; + + switch (LOWORD(wParam)) { + case IDC_PROTOCOL: + // status listview + init = TRUE; + { + HWND hList = GetDlgItem(hwndDlg, IDC_STATUSLIST); + ListView_DeleteAllItems(hList); + + int flags = 0; + if (!bSettingSame) + flags = CallProtoService(setting->szName, PS_GETCAPS, PFLAGNUM_2, 0)&~CallProtoService(setting->szName, PS_GETCAPS, (WPARAM)PFLAGNUM_5, 0); + + LVITEM lvItem = { 0 }; + lvItem.mask = LVIF_TEXT | LVIF_PARAM; + lvItem.iItem = 0; + lvItem.iSubItem = 0; + for (int i = 0; i < _countof(statusModeList); i++) { + if ((flags & statusModePf2List[i]) || (statusModePf2List[i] == PF2_OFFLINE) || (bSettingSame)) { + lvItem.pszText = pcli->pfnGetStatusModeDescription(statusModeList[i], 0); + lvItem.lParam = (LPARAM)statusModePf2List[i]; + ListView_InsertItem(hList, &lvItem); + ListView_SetCheckState(hList, lvItem.iItem, setting->statusFlags & statusModePf2List[i] ? TRUE : FALSE); + lvItem.iItem++; + } + } + } + init = FALSE; + // status dropdown boxes + { + int flags = 0; + if (!bSettingSame) + flags = CallProtoService(setting->szName, PS_GETCAPS, PFLAGNUM_2, 0)&~CallProtoService(setting->szName, PS_GETCAPS, (WPARAM)PFLAGNUM_5, 0); + + // clear box and add new status, loop status and check if compatible with proto + SendDlgItemMessage(hwndDlg, IDC_LV1STATUS, CB_RESETCONTENT, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_LV2STATUS, CB_RESETCONTENT, 0, 0); + for (int i = 0; i < _countof(statusModeList); i++) { + if ((flags & statusModePf2List[i]) || statusModePf2List[i] == PF2_OFFLINE || bSettingSame) { + wchar_t *statusMode = pcli->pfnGetStatusModeDescription(statusModeList[i], 0); + int item = SendDlgItemMessage(hwndDlg, IDC_LV1STATUS, CB_ADDSTRING, 0, (LPARAM)statusMode); + SendDlgItemMessage(hwndDlg, IDC_LV1STATUS, CB_SETITEMDATA, item, (LPARAM)statusModeList[i]); + item = SendDlgItemMessage(hwndDlg, IDC_LV2STATUS, CB_ADDSTRING, 0, (LPARAM)statusMode); + SendDlgItemMessage(hwndDlg, IDC_LV2STATUS, CB_SETITEMDATA, item, (LPARAM)statusModeList[i]); + if (statusModeList[i] == setting->lv1Status) { + SendDlgItemMessage(hwndDlg, IDC_LV1STATUS, CB_SETCURSEL, (WPARAM)item, 0); + SetDlgItemText(hwndDlg, IDC_SETNASTR, CMStringW(FORMAT, TranslateT("minutes of %s mode"), statusMode)); + } + if (statusModeList[i] == setting->lv2Status) + SendDlgItemMessage(hwndDlg, IDC_LV2STATUS, CB_SETCURSEL, (WPARAM)item, 0); + } + } + } + SetDialogItems(hwndDlg, setting); + break; + + case IDC_LV1STATUS: + if (HIWORD(wParam) == CBN_SELCHANGE) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + + setting->lv1Status = (int)SendDlgItemMessage(hwndDlg, IDC_LV1STATUS, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_LV1STATUS, CB_GETCURSEL, 0, 0), 0); + SetDlgItemText(hwndDlg, IDC_SETNASTR, CMStringW(FORMAT, TranslateT("minutes of %s mode"), pcli->pfnGetStatusModeDescription(setting->lv1Status, 0))); + break; + + case IDC_LV2STATUS: + if (HIWORD(wParam) == CBN_SELCHANGE) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + + setting->lv2Status = (int)SendDlgItemMessage(hwndDlg, IDC_LV2STATUS, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, IDC_LV2STATUS, CB_GETCURSEL, 0, 0), 0); + break; + + case IDC_FULLSCREEN: + setting->optionFlags ^= FLAG_FULLSCREEN; + SetDialogItems(hwndDlg, setting); + break; + + case IDC_SCREENSAVE: + setting->optionFlags ^= FLAG_ONSAVER; + SetDialogItems(hwndDlg, setting); + break; + + case IDC_ONLOCK: + setting->optionFlags ^= FLAG_ONLOCK; + SetDialogItems(hwndDlg, setting); + break; + + case IDC_TIMED: + setting->optionFlags ^= FLAG_ONMOUSE; + SetDialogItems(hwndDlg, setting); + break; + + case IDC_SETNA: + setting->optionFlags ^= FLAG_SETNA; + SetDialogItems(hwndDlg, setting); + break; + + case IDC_AWAYTIME: + setting->awayTime = GetDlgItemInt(hwndDlg, IDC_AWAYTIME, NULL, FALSE); + break; + + case IDC_NATIME: + setting->naTime = GetDlgItemInt(hwndDlg, IDC_NATIME, NULL, FALSE); + break; + + case IDC_LV2ONINACTIVE: + setting->optionFlags ^= FLAG_LV2ONINACTIVE; + SetDialogItems(hwndDlg, setting); + break; + + case IDC_CONFIRM: + setting->optionFlags ^= FLAG_CONFIRM; + SetDialogItems(hwndDlg, setting); + break; + + case IDC_RESETSTATUS: + setting->optionFlags ^= FLAG_RESET; + SetDialogItems(hwndDlg, setting); + break; + + case IDC_MONITORMIRANDA: + setting->optionFlags ^= FLAG_MONITORMIRANDA; + SetDialogItems(hwndDlg, setting); + break; + } + break; + + case WM_SHOWWINDOW: + init = TRUE; + + if (setting = GetSetting(hwndDlg, sameSetting)) + SetDialogItems(hwndDlg, setting); + + SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_PROTOCOL, (LPARAM)0x11111111); + init = FALSE; + break; + + case WM_NOTIFY: + switch (((NMHDR*)lParam)->idFrom) { + case IDC_STATUSLIST: + if (init) + break; + + switch (((NMHDR*)lParam)->code) { + case LVN_ITEMCHANGED: + NMLISTVIEW *nmlv = (NMLISTVIEW*)lParam; + if (IsWindowVisible(GetDlgItem(hwndDlg, IDC_STATUSLIST)) && ((nmlv->uNewState ^ nmlv->uOldState) & LVIS_STATEIMAGEMASK)) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + + if (setting = GetSetting(hwndDlg, sameSetting)) { + HWND hList = GetDlgItem(hwndDlg, IDC_STATUSLIST); + LVITEM lvItem = { 0 }; + lvItem.mask = LVIF_PARAM; + lvItem.iItem = nmlv->iItem; + ListView_GetItem(hList, &lvItem); + int pf2Status = lvItem.lParam; + if (ListView_GetCheckState(hList, lvItem.iItem)) + setting->statusFlags |= pf2Status; + else + setting->statusFlags &= ~pf2Status; + } + } + break; + } + break; + } + + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: + if (bSettingSame) + WriteAutoAwaySetting(*sameSetting, SETTING_ALL); + else { + for (int i = 0; i < optionSettings.getCount(); i++) + WriteAutoAwaySetting(optionSettings[i], optionSettings[i].szName); + } + AAALoadOptions(autoAwaySettings, FALSE); + } + break; + + case WM_DESTROY: + optionSettings.destroy(); + free(sameSetting); + break; + } + return FALSE; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// General options window procedure + +static INT_PTR CALLBACK DlgProcAutoAwayGeneralOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + CheckDlgButton(hwndDlg, IDC_IGNLOCK, db_get_b(NULL, AAAMODULENAME, SETTING_IGNLOCK, FALSE) != 0 ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_IGNSYSKEYS, db_get_b(NULL, AAAMODULENAME, SETTING_IGNSYSKEYS, FALSE) != 0 ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_IGNALTCOMBO, db_get_b(NULL, AAAMODULENAME, SETTING_IGNALTCOMBO, FALSE) != 0 ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_MONITORMOUSE, db_get_b(NULL, AAAMODULENAME, SETTING_MONITORMOUSE, BST_CHECKED) != 0 ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_MONITORKEYBOARD, db_get_b(NULL, AAAMODULENAME, SETTING_MONITORKEYBOARD, BST_CHECKED) != 0 ? BST_CHECKED : BST_UNCHECKED); + SetDlgItemInt(hwndDlg, IDC_AWAYCHECKTIMEINSECS, db_get_w(NULL, AAAMODULENAME, SETTING_AWAYCHECKTIMEINSECS, 5), FALSE); + SetDlgItemInt(hwndDlg, IDC_CONFIRMDELAY, db_get_w(NULL, AAAMODULENAME, SETTING_CONFIRMDELAY, 5), FALSE); + CheckDlgButton(hwndDlg, bSettingSame ? IDC_SAMESETTINGS : IDC_PERPROTOCOLSETTINGS, BST_CHECKED); + ShowWindow(GetDlgItem(hwndDlg, IDC_IDLEWARNING), db_get_b(NULL, "Idle", "AAEnable", 0)); + break; + + case WM_SHOWWINDOW: + ShowWindow(GetDlgItem(hwndDlg, IDC_IDLEWARNING), (db_get_b(NULL, "Idle", "AAEnable", 0))); + break; + + case WM_COMMAND: + if ((HIWORD(wParam) == EN_CHANGE || HIWORD(wParam) == BN_CLICKED) && (HWND)lParam == GetFocus()) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + + switch (LOWORD(wParam)) { + case IDC_MONITORMOUSE: + CheckDlgButton(hwndDlg, IDC_MONITORMOUSE, (((BST_UNCHECKED == IsDlgButtonChecked(hwndDlg, IDC_MONITORMOUSE)) && (BST_UNCHECKED == IsDlgButtonChecked(hwndDlg, IDC_MONITORKEYBOARD))) || (IsDlgButtonChecked(hwndDlg, IDC_MONITORMOUSE)) ? BST_CHECKED : BST_UNCHECKED)); + break; + + case IDC_MONITORKEYBOARD: + CheckDlgButton(hwndDlg, IDC_MONITORKEYBOARD, (((BST_UNCHECKED == IsDlgButtonChecked(hwndDlg, IDC_MONITORMOUSE)) && (BST_UNCHECKED == IsDlgButtonChecked(hwndDlg, IDC_MONITORKEYBOARD))) || (IsDlgButtonChecked(hwndDlg, IDC_MONITORKEYBOARD)) ? BST_CHECKED : BST_UNCHECKED)); + break; + + case IDC_SAMESETTINGS: + case IDC_PERPROTOCOLSETTINGS: + bSettingSame = IsDlgButtonChecked(hwndDlg, IDC_SAMESETTINGS); + break; + } + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->code == PSN_APPLY) { + db_set_b(NULL, AAAMODULENAME, SETTING_IGNLOCK, (BYTE)IsDlgButtonChecked(hwndDlg, IDC_IGNLOCK)); + db_set_b(NULL, AAAMODULENAME, SETTING_IGNSYSKEYS, (BYTE)IsDlgButtonChecked(hwndDlg, IDC_IGNSYSKEYS)); + db_set_b(NULL, AAAMODULENAME, SETTING_IGNALTCOMBO, (BYTE)IsDlgButtonChecked(hwndDlg, IDC_IGNALTCOMBO)); + db_set_b(NULL, AAAMODULENAME, SETTING_SAMESETTINGS, (BYTE)bSettingSame); + db_set_w(NULL, AAAMODULENAME, SETTING_AWAYCHECKTIMEINSECS, (WORD)GetDlgItemInt(hwndDlg, IDC_AWAYCHECKTIMEINSECS, NULL, FALSE)); + db_set_w(NULL, AAAMODULENAME, SETTING_CONFIRMDELAY, (WORD)GetDlgItemInt(hwndDlg, IDC_CONFIRMDELAY, NULL, FALSE)); + db_set_b(NULL, AAAMODULENAME, SETTING_MONITORMOUSE, (BYTE)IsDlgButtonChecked(hwndDlg, IDC_MONITORMOUSE)); + db_set_b(NULL, AAAMODULENAME, SETTING_MONITORKEYBOARD, (BYTE)IsDlgButtonChecked(hwndDlg, IDC_MONITORKEYBOARD)); + AAALoadOptions(autoAwaySettings, FALSE); + } + break; + } + return FALSE; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Tab window procedure + +static INT_PTR CALLBACK DlgProcAutoAwayTabs(HWND hwndDlg, UINT msg, WPARAM, LPARAM lParam) +{ + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + { + RECT rcTabs, rcOptions, rcPage; + bSettingSame = db_get_b(NULL, AAAMODULENAME, SETTING_SAMESETTINGS, FALSE); + + // set tabs + int tabCount = 0; + HWND hTab = GetDlgItem(hwndDlg, IDC_TABS); + GetWindowRect(hTab, &rcTabs); + GetWindowRect(hwndDlg, &rcOptions); + + // general tab + TCITEM tci = { 0 }; + tci.mask = TCIF_TEXT | TCIF_PARAM; + tci.pszText = TranslateT("General"); + HWND hPage = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_OPT_GENAUTOAWAY), hwndDlg, DlgProcAutoAwayGeneralOpts, (LPARAM)GetParent(hwndDlg)); + EnableThemeDialogTexture(hPage, ETDT_ENABLETAB); + + tci.lParam = (LPARAM)hPage; + GetClientRect(hPage, &rcPage); + MoveWindow(hPage, (rcTabs.left - rcOptions.left) + ((rcTabs.right - rcTabs.left) - (rcPage.right - rcPage.left)) / 2, 10 + (rcTabs.top - rcOptions.top) + ((rcTabs.bottom - rcTabs.top) - (rcPage.bottom - rcPage.top)) / 2, rcPage.right - rcPage.left, rcPage.bottom - rcPage.top, TRUE); + ShowWindow(hPage, SW_HIDE); + TabCtrl_InsertItem(hTab, tabCount++, &tci); + HWND hShow = hPage; + + // rules tab + tci.mask = TCIF_TEXT | TCIF_PARAM; + tci.pszText = TranslateT("Rules"); + hPage = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_OPT_AUTOAWAY), hwndDlg, DlgProcAutoAwayRulesOpts, (LPARAM)GetParent(hwndDlg)); + EnableThemeDialogTexture(hPage, ETDT_ENABLETAB); + + tci.lParam = (LPARAM)hPage; + GetClientRect(hPage, &rcPage); + MoveWindow(hPage, (rcTabs.left - rcOptions.left) + ((rcTabs.right - rcTabs.left) - (rcPage.right - rcPage.left)) / 2, 10 + (rcTabs.top - rcOptions.top) + ((rcTabs.bottom - rcTabs.top) - (rcPage.bottom - rcPage.top)) / 2, rcPage.right - rcPage.left, rcPage.bottom - rcPage.top, TRUE); + ShowWindow(hPage, SW_HIDE); + TabCtrl_InsertItem(hTab, tabCount++, &tci); + + // messages tab + tci.mask = TCIF_TEXT | TCIF_PARAM; + tci.pszText = TranslateT("Status messages"); + hPage = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_OPT_AUTOAWAYMSG), hwndDlg, DlgProcAutoAwayMsgOpts, (LPARAM)GetParent(hwndDlg)); + EnableThemeDialogTexture(hPage, ETDT_ENABLETAB); + + tci.lParam = (LPARAM)hPage; + GetClientRect(hPage, &rcPage); + MoveWindow(hPage, (rcTabs.left - rcOptions.left) + ((rcTabs.right - rcTabs.left) - (rcPage.right - rcPage.left)) / 2, 10 + (rcTabs.top - rcOptions.top) + ((rcTabs.bottom - rcTabs.top) - (rcPage.bottom - rcPage.top)) / 2, rcPage.right - rcPage.left, rcPage.bottom - rcPage.top, TRUE); + ShowWindow(hPage, SW_HIDE); + TabCtrl_InsertItem(hTab, tabCount++, &tci); + + ShowWindow(hShow, SW_SHOW); + } + break; + + case PSM_CHANGED: + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + + case WM_NOTIFY: + if ((((NMHDR*)lParam)->idFrom == IDC_TABS)) { + if (((NMHDR*)lParam)->code == TCN_SELCHANGING) { + TCITEM tci; + + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(GetDlgItem(hwndDlg, IDC_TABS), TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_TABS)), &tci); + ShowWindow((HWND)tci.lParam, SW_HIDE); + } + else if (((NMHDR*)lParam)->code == TCN_SELCHANGE) { + TCITEM tci; + + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(GetDlgItem(hwndDlg, IDC_TABS), TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_TABS)), &tci); + ShowWindow((HWND)tci.lParam, SW_SHOW); + } + } + if (((LPNMHDR)lParam)->code == PSN_APPLY) { + TCITEM tci; + tci.mask = TCIF_PARAM; + int count = TabCtrl_GetItemCount(GetDlgItem(hwndDlg, IDC_TABS)); + for (int i = 0; i < count; i++) { + TabCtrl_GetItem(GetDlgItem(hwndDlg, IDC_TABS), i, &tci); + SendMessage((HWND)tci.lParam, WM_NOTIFY, 0, lParam); + } + } + break; + } + + return FALSE; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Options initialization procedure + +int AutoAwayOptInitialise(WPARAM wParam, LPARAM) +{ + OPTIONSDIALOGPAGE odp = { 0 }; + odp.position = 1000000000; + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_TABS); + odp.szTitle.a = LPGEN("Auto away"); + odp.szGroup.a = LPGEN("Status"); + odp.pfnDlgProc = DlgProcAutoAwayTabs; + odp.flags = ODPF_BOLDGROUPS; + Options_AddPage(wParam, &odp); + return 0; +} diff --git a/plugins/StatusManager/src/AdvancedAutoAway/advancedautoaway.cpp b/plugins/StatusManager/src/AdvancedAutoAway/advancedautoaway.cpp new file mode 100644 index 0000000000..d0eb48801c --- /dev/null +++ b/plugins/StatusManager/src/AdvancedAutoAway/advancedautoaway.cpp @@ -0,0 +1,598 @@ +/* + AdvancedAutoAway Plugin for Miranda-IM (www.miranda-im.org) + Copyright 2003-2006 P. Boon + + 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 + + + Some code is copied from Miranda's AutoAway module +*/ + +#include "..\stdafx.h" + +#ifdef _DEBUG + #define SECS_PER_MINUTE 20 /* speedup */ +#else + #define SECS_PER_MINUTE 60 /* default I believe */ +#endif + +///////////////////////////////////////////////////////////////////////////////////////// + +TAAAProtoSettingList autoAwaySettings(10, AAACompareSettings); + +TAAAProtoSetting::TAAAProtoSetting(PROTOACCOUNT *pa) +{ + cbSize = sizeof(PROTOCOLSETTINGEX); + szName = pa->szModuleName; + tszAccName = pa->tszAccountName; + lastStatus = status = originalStatusMode = ID_STATUS_CURRENT; + szMsg = NULL; + curState = ACTIVE; + mStatus = FALSE; +} + +TAAAProtoSetting::~TAAAProtoSetting() +{ + free(szMsg); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +HANDLE hAAAModuleLoadedHook = NULL, + hStateChangedEvent = NULL; + +static BOOL ignoreLockKeys = FALSE; +static BOOL ignoreSysKeys = FALSE; +static BOOL ignoreAltCombo = FALSE; +static BOOL monitorMouse = TRUE; +static BOOL monitorKeyboard = TRUE; +static HWND confirmDialog; +static int mouseStationaryTimer; +HHOOK hMirandaMouseHook = NULL; +HHOOK hMirandaKeyBoardHook = NULL; +#pragma data_seg("Shared") +DWORD lastInput = 0; +POINT lastMousePos = {0}; +HHOOK hMouseHook = NULL; +HHOOK hKeyBoardHook = NULL; +#pragma data_seg() +#pragma comment(linker, "/section:Shared,rws") +DWORD lastMirandaInput = 0; +static UINT_PTR hAutoAwayTimer; +// prototypes +extern DWORD StatusModeToProtoFlag(int status); +static int HookWindowsHooks(int hookMiranda, int hookAll); +static int UnhookWindowsHooks(); +static LRESULT CALLBACK MouseHookFunction(int code, WPARAM wParam, LPARAM lParam); +static LRESULT CALLBACK KeyBoardHookFunction(int code, WPARAM wParam, LPARAM lParam); +static LRESULT CALLBACK MirandaMouseHookFunction(int code, WPARAM wParam, LPARAM lParam); +static LRESULT CALLBACK MirandaKeyBoardHookFunction(int code, WPARAM wParam, LPARAM lParam); +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved); + +static VOID CALLBACK AutoAwayTimer(HWND hwnd,UINT message,UINT_PTR idEvent,DWORD dwTime); +extern int AutoAwayOptInitialise(WPARAM wParam,LPARAM lParam); +extern int AutoAwayMsgOptInitialise(WPARAM wParam,LPARAM lParam); +extern int SetStatus(WPARAM wParam, LPARAM lParam); +extern int ShowConfirmDialog(WPARAM wParam, LPARAM lParam); +extern char *StatusModeToDbSetting(int status,const char *suffix); + +///////////////////////////////////////////////////////////////////////////////////////// +// Load from DB + +void AAALoadOptions(TAAAProtoSettingList &loadSettings, BOOL override) +{ + // if override is enabled, samesettings will be ignored (for options loading) + int monitorMiranda = FALSE; // use windows hooks? + int monitorAll = FALSE; // use windows hooks? + + if (!override) + UnhookWindowsHooks(); + if (hAutoAwayTimer != 0) + KillTimer(NULL, hAutoAwayTimer); + + ignoreLockKeys = db_get_b(NULL, AAAMODULENAME, SETTING_IGNLOCK, FALSE); + ignoreSysKeys = db_get_b(NULL, AAAMODULENAME, SETTING_IGNSYSKEYS, FALSE); + ignoreAltCombo = db_get_b(NULL, AAAMODULENAME, SETTING_IGNALTCOMBO, FALSE); + monitorMouse = db_get_b(NULL, AAAMODULENAME, SETTING_MONITORMOUSE, TRUE); + monitorKeyboard = db_get_b(NULL, AAAMODULENAME, SETTING_MONITORKEYBOARD, TRUE); + lastInput = lastMirandaInput = GetTickCount(); + + for (int i = 0; i < loadSettings.getCount(); i++) { + char* protoName; + if ((db_get_b(NULL, AAAMODULENAME, SETTING_SAMESETTINGS, 0)) && !override) + protoName = SETTING_ALL; + else + protoName = loadSettings[i].szName; + LoadAutoAwaySetting(loadSettings[i], protoName); + if (!override) { + if (loadSettings[i].optionFlags & FLAG_MONITORMIRANDA) + monitorMiranda = TRUE; + else if (ignoreLockKeys || ignoreSysKeys || ignoreAltCombo || (monitorMouse != monitorKeyboard)) + monitorAll = TRUE; + } + } + + if (db_get_b(NULL, "Idle", "AAEnable", 0)) + return; + + HookWindowsHooks(monitorMiranda, monitorAll); + hAutoAwayTimer = SetTimer(NULL, 0, db_get_w(NULL, AAAMODULENAME, SETTING_AWAYCHECKTIMEINSECS, 5) * 1000, AutoAwayTimer); +} + +int LoadAutoAwaySetting(TAAAProtoSetting &autoAwaySetting, char* protoName) +{ + char setting[128]; + mir_snprintf(setting, "%s_OptionFlags", protoName); + autoAwaySetting.optionFlags = db_get_w(NULL, AAAMODULENAME, setting, FLAG_LV2ONINACTIVE | FLAG_RESET); + mir_snprintf(setting, "%s_AwayTime", protoName); + autoAwaySetting.awayTime = db_get_w(NULL, AAAMODULENAME, setting, SETTING_AWAYTIME_DEFAULT); + mir_snprintf(setting, "%s_NATime", protoName); + autoAwaySetting.naTime = db_get_w(NULL, AAAMODULENAME, setting, SETTING_NATIME_DEFAULT); + mir_snprintf(setting, "%s_StatusFlags", protoName); + autoAwaySetting.statusFlags = db_get_w(NULL, AAAMODULENAME, setting, StatusModeToProtoFlag(ID_STATUS_ONLINE) | StatusModeToProtoFlag(ID_STATUS_FREECHAT)); + + int flags; + if (db_get_b(NULL, AAAMODULENAME, SETTING_SAMESETTINGS, 0)) + flags = 0xFFFFFF; + else + flags = CallProtoService(protoName, PS_GETCAPS, PFLAGNUM_2, 0)&~CallProtoService(protoName, PS_GETCAPS, (WPARAM)PFLAGNUM_5, 0); + mir_snprintf(setting, "%s_Lv1Status", protoName); + autoAwaySetting.lv1Status = db_get_w(NULL, AAAMODULENAME, setting, (flags&StatusModeToProtoFlag(ID_STATUS_AWAY)) ? ID_STATUS_AWAY : ID_STATUS_OFFLINE); + mir_snprintf(setting, "%s_Lv2Status", protoName); + autoAwaySetting.lv2Status = db_get_w(NULL, AAAMODULENAME, setting, (flags&StatusModeToProtoFlag(ID_STATUS_NA)) ? ID_STATUS_NA : ID_STATUS_OFFLINE); + + return 0; +} + +static int ProcessProtoAck(WPARAM, LPARAM lParam) +{ + ACKDATA *ack = (ACKDATA*)lParam; + if (ack->type != ACKTYPE_STATUS || ack->result != ACKRESULT_SUCCESS) + return 0; + + log_debugA("ProcessProtoAck: ack->szModule: %s", ack->szModule); + for (int i = 0; i < autoAwaySettings.getCount(); i++) { + TAAAProtoSetting &p = autoAwaySettings[i]; + log_debugA("chk: %s", p.szName); + if (!mir_strcmp(p.szName, ack->szModule)) { + log_debugA("ack->szModule: %s p.statusChanged: %d", ack->szModule, p.statusChanged); + if (!p.statusChanged) + p.mStatus = TRUE; + + p.statusChanged = FALSE; + } + } + + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Account control event + +int OnAAAAccChanged(WPARAM wParam, LPARAM lParam) +{ + PROTOACCOUNT *pa = (PROTOACCOUNT*)lParam; + switch (wParam) { + case PRAC_ADDED: + autoAwaySettings.insert(new TAAAProtoSetting(pa)); + break; + + case PRAC_REMOVED: + for (int i = 0; i < autoAwaySettings.getCount(); i++) { + if (!mir_strcmp(autoAwaySettings[i].szName, pa->szModuleName)) { + autoAwaySettings.remove(i); + break; + } + } + break; + } + + return 0; +} + +static char* status2descr(int status) +{ + switch (status) { + case ACTIVE: return "ACTIVE"; + case STATUS1_SET: return "STATUS1_SET"; + case STATUS2_SET: return "STATUS2_SET"; + case SET_ORGSTATUS: return "SET_ORGSTATUS"; + case HIDDEN_ACTIVE: return "HIDDEN_ACTIVE"; + } + return "ERROR"; +} + +static int changeState(TAAAProtoSetting &setting, STATES newState) +{ + if (setting.curState == newState) + return 0; + + setting.oldState = setting.curState; + setting.curState = newState; + + log_debugA("%s state change: %s -> %s", setting.szName, status2descr(setting.oldState), status2descr(setting.curState)); + + NotifyEventHooks(hStateChangedEvent, 0, (LPARAM)&setting); + if (setting.curState != SET_ORGSTATUS && setting.curState != ACTIVE && setting.statusChanged) { + /* change the awaymessage */ + if (setting.szMsg != NULL) { + free(setting.szMsg); + setting.szMsg = NULL; + } + + if (db_get_b(NULL, AAAMODULENAME, StatusModeToDbSetting(setting.status, SETTING_MSGCUSTOM), FALSE)) { + DBVARIANT dbv; + if (!db_get_ws(NULL, AAAMODULENAME, StatusModeToDbSetting(setting.status, SETTING_STATUSMSG), &dbv)) { + setting.szMsg = wcsdup(dbv.ptszVal); + db_free(&dbv); + } + } + } + else if (setting.szMsg != NULL) { + free(setting.szMsg); + setting.szMsg = NULL; + } + + return 0; +} + +static VOID CALLBACK AutoAwayTimer(HWND, UINT, UINT_PTR, DWORD) +{ + int statusChanged = FALSE; + int confirm = FALSE; + + for (int i = 0; i < autoAwaySettings.getCount(); i++) { + TAAAProtoSetting& aas = autoAwaySettings[i]; + aas.status = ID_STATUS_DISABLED; + + BOOL bTrigger = false; + + if (aas.optionFlags & FLAG_MONITORMIRANDA) + mouseStationaryTimer = (GetTickCount() - lastMirandaInput) / 1000; + else { + LASTINPUTINFO ii = { sizeof(ii) }; + GetLastInputInfo(&ii); + mouseStationaryTimer = (GetTickCount() - ii.dwTime) / 1000; + } + + int sts1Time = aas.awayTime * SECS_PER_MINUTE; + int sts2Time = aas.naTime * SECS_PER_MINUTE; + int sts1setTime = aas.sts1setTimer == 0 ? 0 : (GetTickCount() - aas.sts1setTimer) / 1000; + int currentMode = CallProtoService(aas.szName, PS_GETSTATUS, 0, 0); + + if (aas.optionFlags & FLAG_ONSAVER) + bTrigger |= IsScreenSaverRunning(); + if (aas.optionFlags & FLAG_ONLOCK) + bTrigger |= IsWorkstationLocked(); + if (aas.optionFlags & FLAG_FULLSCREEN) + bTrigger |= IsFullScreen(); + + /* check states */ + if (aas.curState == ACTIVE) { + if (((mouseStationaryTimer >= sts1Time && (aas.optionFlags & FLAG_ONMOUSE)) || bTrigger) && currentMode != aas.lv1Status && aas.statusFlags&StatusModeToProtoFlag(currentMode)) { + /* from ACTIVE to STATUS1_SET */ + aas.lastStatus = aas.originalStatusMode = CallProtoService(aas.szName, PS_GETSTATUS, 0, 0); + aas.status = aas.lv1Status; + aas.sts1setTimer = GetTickCount(); + sts1setTime = 0; + aas.statusChanged = statusChanged = TRUE; + changeState(aas, STATUS1_SET); + } + else if (mouseStationaryTimer >= sts2Time && currentMode == aas.lv1Status && currentMode != aas.lv2Status && (aas.optionFlags & FLAG_SETNA) && (aas.statusFlags & StatusModeToProtoFlag(currentMode))) { + /* from ACTIVE to STATUS2_SET */ + aas.lastStatus = aas.originalStatusMode = CallProtoService(aas.szName, PS_GETSTATUS, 0, 0); + aas.status = aas.lv2Status; + aas.statusChanged = statusChanged = TRUE; + changeState(aas, STATUS2_SET); + } + } + + if (aas.curState == STATUS1_SET) { + if ((mouseStationaryTimer < sts1Time && !bTrigger) && !(aas.optionFlags & FLAG_RESET)) { + /* from STATUS1_SET to HIDDEN_ACTIVE */ + changeState(aas, HIDDEN_ACTIVE); + aas.lastStatus = CallProtoService(aas.szName, PS_GETSTATUS, 0, 0); + } + else if (((mouseStationaryTimer < sts1Time) && !bTrigger) && + ((aas.optionFlags & FLAG_LV2ONINACTIVE) || (!(aas.optionFlags&FLAG_SETNA))) && + (aas.optionFlags & FLAG_RESET)) { + /* from STATUS1_SET to SET_ORGSTATUS */ + changeState(aas, SET_ORGSTATUS); + } + else if ((aas.optionFlags & FLAG_SETNA) && sts1setTime >= sts2Time) { + /* when set STATUS2, currentMode doesn't have to be in the selected status list (statusFlags) */ + /* from STATUS1_SET to STATUS2_SET */ + aas.lastStatus = CallProtoService(aas.szName, PS_GETSTATUS, 0, 0); + aas.status = aas.lv2Status; + aas.statusChanged = statusChanged = TRUE; + changeState(aas, STATUS2_SET); + } + } + + if (aas.curState == STATUS2_SET) { + if (mouseStationaryTimer < sts2Time && !bTrigger && (aas.optionFlags & FLAG_RESET)) { + /* from STATUS2_SET to SET_ORGSTATUS */ + changeState(aas, SET_ORGSTATUS); + } + else if (mouseStationaryTimer < sts2Time && !bTrigger && !(aas.optionFlags & FLAG_RESET)) { + /* from STATUS2_SET to HIDDEN_ACTIVE */ + /* Remember: after status1 is set, and "only on inactive" is NOT set, it implies !reset. */ + changeState(aas, HIDDEN_ACTIVE); + aas.lastStatus = CallProtoService(aas.szName, PS_GETSTATUS, 0, 0); + } + } + + if (aas.curState == HIDDEN_ACTIVE) { + if (aas.mStatus) { + /* HIDDEN_ACTIVE to ACTIVE */ + //aas.statusChanged = FALSE; + changeState(aas, ACTIVE); + aas.sts1setTimer = 0; + aas.mStatus = FALSE; + } + else if ((aas.optionFlags & FLAG_SETNA) && currentMode == aas.lv1Status && + currentMode != aas.lv2Status && (aas.statusFlags & StatusModeToProtoFlag(currentMode)) && + (mouseStationaryTimer >= sts2Time || (sts1setTime >= sts2Time && !(aas.optionFlags & FLAG_LV2ONINACTIVE)))) { + /* HIDDEN_ACTIVE to STATUS2_SET */ + aas.lastStatus = aas.originalStatusMode = CallProtoService(aas.szName, PS_GETSTATUS, 0, 0); + aas.status = aas.lv2Status; + aas.statusChanged = statusChanged = TRUE; + changeState(aas, STATUS2_SET); + } + } + if (aas.curState == SET_ORGSTATUS) { + /* SET_ORGSTATUS to ACTIVE */ + aas.lastStatus = CallProtoService(aas.szName, PS_GETSTATUS, 0, 0); + aas.status = aas.originalStatusMode; + confirm = (aas.optionFlags&FLAG_CONFIRM) ? TRUE : confirm; + aas.statusChanged = statusChanged = TRUE; + changeState(aas, ACTIVE); + aas.sts1setTimer = 0; + } + autoAwaySettings[i].mStatus = FALSE; + } + + if (confirm || statusChanged) { + TAAAProtoSettingList ps = autoAwaySettings; + for (int i = 0; i < ps.getCount(); i++) { + if (ps[i].szMsg) + ps[i].szMsg = wcsdup(ps[i].szMsg); + + if (ps[i].status == ID_STATUS_DISABLED) + ps[i].szName = ""; + } + + if (confirm) + confirmDialog = (HWND)CallService(MS_CS_SHOWCONFIRMDLGEX, (WPARAM)&ps, db_get_w(NULL, AAAMODULENAME, SETTING_CONFIRMDELAY, 5)); + else if (statusChanged) + CallService(MS_CS_SETSTATUSEX, (WPARAM)&ps, 0); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Windows hooks + +static int HookWindowsHooks(int hookMiranda, int hookAll) +{ + if (hookMiranda) { + if (monitorKeyboard && hMirandaKeyBoardHook == NULL) + hMirandaKeyBoardHook = SetWindowsHookEx(WH_KEYBOARD, MirandaKeyBoardHookFunction, NULL, GetCurrentThreadId()); + if (monitorMouse && hMirandaMouseHook == NULL) + hMirandaMouseHook = SetWindowsHookEx(WH_MOUSE, MirandaMouseHookFunction, NULL, GetCurrentThreadId()); + } + if (hookAll) { + if (monitorKeyboard && hKeyBoardHook == NULL) + hKeyBoardHook = SetWindowsHookEx(WH_KEYBOARD, KeyBoardHookFunction, 0, GetCurrentThreadId()); + if (monitorMouse && hMouseHook == NULL) + hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseHookFunction, 0, GetCurrentThreadId()); + } + + return 0; +} + +static int UnhookWindowsHooks() +{ + UnhookWindowsHookEx(hMouseHook); + UnhookWindowsHookEx(hKeyBoardHook); + UnhookWindowsHookEx(hMirandaMouseHook); + UnhookWindowsHookEx(hMirandaKeyBoardHook); + + hMouseHook = hKeyBoardHook = hMirandaMouseHook = hMirandaKeyBoardHook = NULL; + return 0; +} + +static LRESULT CALLBACK MirandaMouseHookFunction(int code, WPARAM wParam, LPARAM lParam) +{ + if (code >= 0) { + PMOUSEHOOKSTRUCT mouseInfo = (PMOUSEHOOKSTRUCT)lParam; + POINT pt = mouseInfo->pt; + + /* TioDuke's KeyBoardNotifyExt: only update if a Miranda window is focused */ + DWORD pid; + GetWindowThreadProcessId(GetForegroundWindow(), &pid); + if (pid != GetCurrentProcessId()) + return CallNextHookEx(hMirandaMouseHook, code, wParam, lParam); + + if (pt.x != lastMousePos.x || pt.y != lastMousePos.y) { + lastMousePos = pt; + lastMirandaInput = GetTickCount(); + } + } + + return CallNextHookEx(hMirandaMouseHook, code, wParam, lParam); +} + +static LRESULT CALLBACK MirandaKeyBoardHookFunction(int code, WPARAM wParam, LPARAM lParam) +{ + if (code >= 0) { + if (ignoreAltCombo) { + if (((GetKeyState(VK_MENU) < 0) || (wParam == VK_MENU)) || + ((GetKeyState(VK_TAB) < 0) || (wParam == VK_TAB)) || + ((GetKeyState(VK_SHIFT) < 0) || (wParam == VK_SHIFT)) || + ((GetKeyState(VK_CONTROL) < 0) || (wParam == VK_CONTROL)) || + ((GetKeyState(VK_ESCAPE) < 0) || (wParam == VK_ESCAPE)) || + ((GetKeyState(VK_LWIN) < 0) || (wParam == VK_LWIN)) || + ((GetKeyState(VK_RWIN) < 0) || (wParam == VK_RWIN))) + { + return CallNextHookEx(hMirandaKeyBoardHook, code, wParam, lParam); + } + } + + switch (wParam) { + case VK_NUMLOCK: + case VK_CAPITAL: + case VK_SCROLL: + if (!ignoreLockKeys) + lastMirandaInput = GetTickCount(); + break; + + case VK_TAB: + case VK_SHIFT: + case VK_CONTROL: + case VK_MENU: + case VK_ESCAPE: + case VK_LWIN: + case VK_RWIN: + if (!ignoreSysKeys) + lastMirandaInput = GetTickCount(); + break; + + default: + lastMirandaInput = GetTickCount(); + break; + } + } + + return CallNextHookEx(hMirandaKeyBoardHook, code, wParam, lParam); +} + +static LRESULT CALLBACK MouseHookFunction(int code, WPARAM wParam, LPARAM lParam) +{ + if (code >= 0) { + PMOUSEHOOKSTRUCT mouseInfo = (PMOUSEHOOKSTRUCT)lParam; + POINT pt = mouseInfo->pt; + + /* TioDuke's KeyBoardNotifyExt: also grab clicks */ + if ((wParam >= WM_NCLBUTTONDOWN && wParam <= WM_NCXBUTTONDBLCLK && wParam != 0x00AA) || (wParam >= WM_LBUTTONDOWN && wParam <= WM_XBUTTONDBLCLK)) + lastInput = GetTickCount(); + + if (pt.x != lastMousePos.x || pt.y != lastMousePos.y) { + lastMousePos = pt; + lastInput = GetTickCount(); + } + } + + return CallNextHookEx(hMouseHook, code, wParam, lParam); +} + +static LRESULT CALLBACK KeyBoardHookFunction(int code, WPARAM wParam, LPARAM lParam) +{ + if (code >= 0) { + if (ignoreAltCombo) { + if (((GetKeyState(VK_MENU) < 0) || (wParam == VK_MENU)) || + ((GetKeyState(VK_TAB) < 0) || (wParam == VK_TAB)) || + ((GetKeyState(VK_SHIFT) < 0) || (wParam == VK_SHIFT)) || + ((GetKeyState(VK_CONTROL) < 0) || (wParam == VK_CONTROL)) || + ((GetKeyState(VK_ESCAPE) < 0) || (wParam == VK_ESCAPE)) || + ((GetKeyState(VK_LWIN) < 0) || (wParam == VK_LWIN)) || + ((GetKeyState(VK_RWIN) < 0) || (wParam == VK_RWIN))) + { + return CallNextHookEx(hKeyBoardHook, code, wParam, lParam); + } + } + + switch (wParam) { + case VK_NUMLOCK: + case VK_CAPITAL: + case VK_SCROLL: + if (!ignoreLockKeys) + lastInput = GetTickCount(); + break; + + case VK_TAB: + case VK_SHIFT: + case VK_CONTROL: + case VK_MENU: + case VK_ESCAPE: + case VK_LWIN: + case VK_RWIN: + if (!ignoreSysKeys) + lastInput = GetTickCount(); + break; + + default: + lastInput = GetTickCount(); + break; + } + } + + return CallNextHookEx(hKeyBoardHook, code, wParam, lParam); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Inits & stuff + +static int AutoAwayShutdown(WPARAM, LPARAM) +{ + KillTimer(NULL, hAutoAwayTimer); + +#ifdef TRIGGERPLUGIN + DeInitTrigger(); +#endif + UnhookWindowsHooks(); + DestroyHookableEvent(hStateChangedEvent); + + autoAwaySettings.destroy(); + return 0; +} + +int AAAModuleLoaded(WPARAM, LPARAM) +{ + HookEvent(ME_PROTO_ACCLISTCHANGED, OnAAAAccChanged); + HookEvent(ME_OPT_INITIALISE, AutoAwayOptInitialise); + HookEvent(ME_SYSTEM_PRESHUTDOWN, AutoAwayShutdown); + HookEvent(ME_PROTO_ACK, ProcessProtoAck); + mouseStationaryTimer = 0; + lastInput = lastMirandaInput = GetTickCount(); + + //////////////////////////////////////////////////////////////////////////////////////// + + protoList = (OBJLIST<PROTOCOLSETTINGEX>*)&autoAwaySettings; + + int count; + PROTOACCOUNT** protos; + Proto_EnumAccounts(&count, &protos); + + for (int i = 0; i < count; i++) + if (IsSuitableProto(protos[i])) + autoAwaySettings.insert(new TAAAProtoSetting(protos[i])); + + //////////////////////////////////////////////////////////////////////////////////////// + + AAALoadOptions(autoAwaySettings, FALSE); + return 0; +} + +void AdvancedAutoAwayLoad() +{ + hAAAModuleLoadedHook = HookEvent(ME_SYSTEM_MODULESLOADED, AAAModuleLoaded); + hStateChangedEvent = CreateHookableEvent(ME_AAA_STATECHANGED); +} + +void AdvancedAutoAwayUnload() +{ + UnhookEvent(hAAAModuleLoadedHook); + DestroyHookableEvent(hStateChangedEvent); +}
\ No newline at end of file diff --git a/plugins/StatusManager/src/AdvancedAutoAway/advancedautoaway.h b/plugins/StatusManager/src/AdvancedAutoAway/advancedautoaway.h new file mode 100644 index 0000000000..70118e0e38 --- /dev/null +++ b/plugins/StatusManager/src/AdvancedAutoAway/advancedautoaway.h @@ -0,0 +1,94 @@ +/* + AdvancedAutoAway Plugin for Miranda-IM (www.miranda-im.org) + Copyright 2003-2006 P. Boon + + 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 +*/ +#ifndef __ADVANCED_AUTOAWAY_HEADER +#define __ADVANCED_AUTOAWAY_HEADER + +#define AAAMODULENAME "AdvancedAutoAway" +#define SETTING_IGNLOCK "IgnoreLockKeys" +#define SETTING_IGNSYSKEYS "IgnoreSysKeys" +#define SETTING_IGNALTCOMBO "IgnoreAltCombo" +#define SETTING_SAMESETTINGS "SameAutoAwaySettings" +#define SETTING_ALL "ALLPROTOS" +#define SETTING_MSGCUSTOM "Custom" +#define SETTING_STATUSMSG "Msg" +#define SETTING_CONFIRMDELAY "ConfirmTimeout" + +#define SETTING_AWAYTIME_DEFAULT 5 +#define SETTING_NATIME_DEFAULT 20 +#define SETTING_AWAYCHECKTIMEINSECS "CheckInterval" + +#define STATUS_RESET 1 +#define STATUS_AUTOAWAY 2 +#define STATUS_AUTONA 3 + +#define SETTING_MONITORMOUSE "MonitorMouse" +#define SETTING_MONITORKEYBOARD "MonitorKeyboard" + +#define FLAG_ONSAVER 0x0001 // db: set lv1 status on screensaver ? +#define FLAG_ONMOUSE 0x0002 // db: set after inactivity ? +#define FLAG_SETNA 0x0004 // db: set NA after xx of away time ? +#define FLAG_CONFIRM 0x0008 // db: show confirm dialog ? +#define FLAG_RESET 0x0010 // db: restore status ? +#define FLAG_LV2ONINACTIVE 0x0020 // db: set lv2 only on inactivity +#define FLAG_MONITORMIRANDA 0x0040 // db: monitor miranda activity only +#define FLAG_ONLOCK 0x0080 // db: on work station lock +#define FLAG_FULLSCREEN 0x0100 // db: on full screen + +struct TAAAProtoSetting : public PROTOCOLSETTINGEX, public MZeroedObject +{ + TAAAProtoSetting(PROTOACCOUNT *pa); + ~TAAAProtoSetting(); + + int originalStatusMode; + STATES + oldState, + curState; + BOOL statusChanged; // AAA changed the status, don't update mStatus + BOOL mStatus; // status changed manually or not ? + int optionFlags, // db: see above + awayTime, // db: time to wait for inactivity + naTime, // db: time to wait after away is set + statusFlags; // db: set lv1 status if this is original status + WORD lv1Status, // db + lv2Status; // db + unsigned int sts1setTimer; +}; + +static int AAACompareSettings(const TAAAProtoSetting *p1, const TAAAProtoSetting *p2) +{ + return mir_strcmp(p1->szName, p2->szName); +} + +struct AAMSGSETTING +{ + short useCustom; + int status; + char* msg; +}; + +void AdvancedAutoAwayLoad(); +void AdvancedAutoAwayUnload(); + +typedef OBJLIST<TAAAProtoSetting> TAAAProtoSettingList; +extern TAAAProtoSettingList autoAwaySettings; + +int LoadAutoAwaySetting(TAAAProtoSetting &autoAwaySetting, char *protoName); +void AAALoadOptions(TAAAProtoSettingList &settings, BOOL override); + +#endif |