summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocols/ICQ-WIM/res/resources.rc17
-rw-r--r--protocols/ICQ-WIM/src/options.cpp33
-rw-r--r--protocols/ICQ-WIM/src/poll.cpp17
-rw-r--r--protocols/ICQ-WIM/src/proto.cpp4
-rw-r--r--protocols/ICQ-WIM/src/proto.h6
-rw-r--r--protocols/ICQ-WIM/src/resource.h14
-rw-r--r--protocols/ICQ-WIM/src/server.cpp41
-rw-r--r--protocols/ICQ-WIM/src/utils.cpp10
8 files changed, 127 insertions, 15 deletions
diff --git a/protocols/ICQ-WIM/res/resources.rc b/protocols/ICQ-WIM/res/resources.rc
index a5644efe4d..e0b3a3a157 100644
--- a/protocols/ICQ-WIM/res/resources.rc
+++ b/protocols/ICQ-WIM/res/resources.rc
@@ -37,12 +37,12 @@ BEGIN
PUSHBUTTON "Sign in/sign up using phone",IDC_REGISTER,42,49,142,14
END
-IDD_OPTIONS_FULL DIALOGEX 0, 0, 310, 97
+IDD_OPTIONS_FULL DIALOGEX 0, 0, 310, 174
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
EXSTYLE WS_EX_CONTROLPARENT
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
- GROUPBOX "ICQ",IDC_STATIC,4,0,302,76
+ GROUPBOX "ICQ",IDC_STATIC,4,0,302,75
RTEXT "ICQ number:",IDC_STATIC,12,14,51,8
EDITTEXT IDC_UIN,68,12,106,12,ES_AUTOHSCROLL
RTEXT "Email:",IDC_STATIC,12,29,51,8
@@ -51,7 +51,16 @@ BEGIN
EDITTEXT IDC_PASSWORD,68,42,106,12,ES_PASSWORD | ES_AUTOHSCROLL
CONTROL "Do not open chat windows on creation",IDC_HIDECHATS,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,61,285,10
- PUSHBUTTON "Sign in/sign up using phone",IDC_REGISTER,163,79,142,14
+ GROUPBOX "Advanced",IDC_STATIC,4,75,302,77
+ LTEXT "After this number of seconds set offline contact to the following status (0 - disabled)",IDC_STATIC,12,88,204,23,0,WS_EX_DLGMODALFRAME
+ EDITTEXT IDC_DIFF1,221,85,54,12,ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS,275,84,11,14
+ COMBOBOX IDC_STATUS1,221,100,81,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "After that. set offline contact to the following status after this number of seconds (0 - disabled)",IDC_STATIC,12,121,204,23,0,WS_EX_DLGMODALFRAME
+ EDITTEXT IDC_DIFF2,221,118,54,12,ES_AUTOHSCROLL
+ CONTROL "",IDC_SPIN2,"msctls_updown32",UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS,275,117,11,14
+ COMBOBOX IDC_STATUS2,221,133,81,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "Sign in/sign up using phone",IDC_REGISTER,165,155,142,14
END
IDD_GROUPCHAT_INVITE DIALOGEX 0, 0, 215, 263
@@ -123,7 +132,7 @@ BEGIN
IDD_OPTIONS_FULL, DIALOG
BEGIN
- BOTTOMMARGIN, 81
+ BOTTOMMARGIN, 169
END
IDD_GROUPCHAT_INVITE, DIALOG
diff --git a/protocols/ICQ-WIM/src/options.cpp b/protocols/ICQ-WIM/src/options.cpp
index f948f64e21..dbac044638 100644
--- a/protocols/ICQ-WIM/src/options.cpp
+++ b/protocols/ICQ-WIM/src/options.cpp
@@ -155,6 +155,8 @@ void CIcqProto::OnLoginViaPhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pRe
class CIcqOptionsDlg : public CProtoDlgBase<CIcqProto>
{
CCtrlEdit edtUin, edtEmail, edtPassword;
+ CCtrlSpin spin1, spin2;
+ CCtrlCombo cmbStatus1, cmbStatus2;
CCtrlCheck chkHideChats;
CCtrlButton btnCreate;
CMStringW wszOldPass;
@@ -162,9 +164,13 @@ class CIcqOptionsDlg : public CProtoDlgBase<CIcqProto>
public:
CIcqOptionsDlg(CIcqProto *ppro, int iDlgID, bool bFullDlg) :
CProtoDlgBase<CIcqProto>(ppro, iDlgID),
+ spin1(this, IDC_SPIN1),
+ spin2(this, IDC_SPIN2),
edtUin(this, IDC_UIN),
edtEmail(this, IDC_EMAIL),
btnCreate(this, IDC_REGISTER),
+ cmbStatus1(this, IDC_STATUS1),
+ cmbStatus2(this, IDC_STATUS2),
edtPassword(this, IDC_PASSWORD),
chkHideChats(this, IDC_HIDECHATS)
{
@@ -173,14 +179,34 @@ public:
CreateLink(edtUin, ppro->m_dwUin);
CreateLink(edtEmail, ppro->m_szEmail);
CreateLink(edtPassword, ppro->m_szPassword);
- if (bFullDlg)
+ if (bFullDlg) {
+ CreateLink(spin1, ppro->m_iTimeDiff1);
+ CreateLink(spin2, ppro->m_iTimeDiff2);
CreateLink(chkHideChats, ppro->m_bHideGroupchats);
+ }
wszOldPass = ppro->m_szPassword;
}
bool OnInitDialog() override
{
+ if (cmbStatus1.GetHwnd()) {
+ for (int iStatus = ID_STATUS_OFFLINE; iStatus <= ID_STATUS_OUTTOLUNCH; iStatus++) {
+ int idx = cmbStatus1.AddString(Clist_GetStatusModeDescription(iStatus, 0));
+ cmbStatus1.SetItemData(idx, iStatus);
+ if (iStatus == m_proto->m_iStatus1)
+ cmbStatus1.SetCurSel(idx);
+
+ idx = cmbStatus2.AddString(Clist_GetStatusModeDescription(iStatus, 0));
+ cmbStatus2.SetItemData(idx, iStatus);
+ if (iStatus == m_proto->m_iStatus2)
+ cmbStatus2.SetCurSel(idx);
+
+ spin1.SetRange(3600);
+ spin2.SetRange(3600);
+ }
+ }
+
if (m_proto->m_dwUin == 0)
edtUin.SetText(L"");
return true;
@@ -188,6 +214,11 @@ public:
bool OnApply() override
{
+ if (cmbStatus1.GetHwnd()) {
+ m_proto->m_iStatus1 = cmbStatus1.GetItemData(cmbStatus1.GetCurSel());
+ m_proto->m_iStatus2 = cmbStatus2.GetItemData(cmbStatus2.GetCurSel());
+ }
+
if (wszOldPass != ptrW(edtPassword.GetText())) {
m_proto->delSetting(DB_KEY_ATOKEN);
m_proto->delSetting(DB_KEY_SESSIONKEY);
diff --git a/protocols/ICQ-WIM/src/poll.cpp b/protocols/ICQ-WIM/src/poll.cpp
index 3d987b334b..e6553c1f51 100644
--- a/protocols/ICQ-WIM/src/poll.cpp
+++ b/protocols/ICQ-WIM/src/poll.cpp
@@ -192,7 +192,22 @@ void CIcqProto::ProcessPresence(const JSONNode &ev)
IcqCacheItem *pCache = FindContactByUIN(dwUin);
if (pCache) {
- setDword(pCache->m_hContact, "Status", StatusFromString(ev["state"].as_mstring()));
+ int iNewStatus = StatusFromString(ev["state"].as_mstring());
+
+ // major crutch dedicated to the official client behaviour to go offline
+ // when its window gets closed. we don't really change the status of a contact
+ // but initialize a timer instead
+ if (iNewStatus == ID_STATUS_OFFLINE) {
+ if (m_iTimeDiff1)
+ pCache->m_timer1 = time(0);
+ else
+ setDword(pCache->m_hContact, "Status", iNewStatus);
+ }
+ // if a client returns back online, we clear timers not to play with statuses anymore
+ else {
+ pCache->m_timer1 = pCache->m_timer2 = 0;
+ setDword(pCache->m_hContact, "Status", iNewStatus);
+ }
Json2string(pCache->m_hContact, ev, "friendly", "Nick");
CheckAvatarChange(pCache->m_hContact, ev);
diff --git a/protocols/ICQ-WIM/src/proto.cpp b/protocols/ICQ-WIM/src/proto.cpp
index 38d65bf345..2e225891c4 100644
--- a/protocols/ICQ-WIM/src/proto.cpp
+++ b/protocols/ICQ-WIM/src/proto.cpp
@@ -42,6 +42,10 @@ CIcqProto::CIcqProto(const char* aProtoName, const wchar_t* aUserName) :
m_evRequestsQueue(CreateEvent(nullptr, FALSE, FALSE, nullptr)),
m_dwUin(this, DB_KEY_UIN, 0),
m_szEmail(this, "Email"),
+ m_iStatus1(this, "Status1", ID_STATUS_AWAY),
+ m_iStatus2(this, "Status2", ID_STATUS_NA),
+ m_iTimeDiff1(this, "TimeDiff1", 0),
+ m_iTimeDiff2(this, "TimeDiff2", 0),
m_szPassword(this, "Password"),
m_bHideGroupchats(this, "HideChats", 1)
{
diff --git a/protocols/ICQ-WIM/src/proto.h b/protocols/ICQ-WIM/src/proto.h
index 7fe801df0b..c9fb72f146 100644
--- a/protocols/ICQ-WIM/src/proto.h
+++ b/protocols/ICQ-WIM/src/proto.h
@@ -55,6 +55,7 @@ struct IcqCacheItem
MCONTACT m_hContact;
bool m_bInList = false;
int m_iApparentMode;
+ time_t m_timer1, m_timer2;
};
struct IcqOwnMessage
@@ -311,7 +312,12 @@ public:
CMOption<wchar_t*> m_szEmail; // email, if present
CMOption<wchar_t*> m_szPassword; // password, if present
CMOption<BYTE> m_bHideGroupchats; // don't pop up group chat windows on startup
+ CMOption<DWORD> m_iTimeDiff1; // set this status to m_iStatus1 after this interval of secs
+ CMOption<DWORD> m_iStatus1;
+ CMOption<DWORD> m_iTimeDiff2; // set this status to m_iStatus2 after this interval of secs
+ CMOption<DWORD> m_iStatus2;
+ void CheckStatus(void);
CMStringA GetUserId(MCONTACT);
int __cdecl OnContactMenu(WPARAM, LPARAM);
diff --git a/protocols/ICQ-WIM/src/resource.h b/protocols/ICQ-WIM/src/resource.h
index b38a314f8f..c62742adb3 100644
--- a/protocols/ICQ-WIM/src/resource.h
+++ b/protocols/ICQ-WIM/src/resource.h
@@ -7,7 +7,7 @@
#define IDD_GROUPCHAT_INVITE 103
#define IDD_INFO_ICQ 104
#define IDD_REGISTER 105
-#define IDD_EDITIGNORE 106
+#define IDD_EDITIGNORE 106
#define IDC_PASSWORD 1001
#define IDC_UIN 1002
#define IDC_UIN2 1003
@@ -24,15 +24,21 @@
#define IDC_MEMBERSINCE 1013
#define IDC_LASTSEEN 1014
#define IDC_EMAIL 1015
-#define IDC_LIST 1016
+#define IDC_LIST 1016
+#define IDC_DIFF1 1017
+#define IDC_SPIN1 1018
+#define IDC_STATUS1 1019
+#define IDC_DIFF2 1023
+#define IDC_SPIN2 1024
+#define IDC_STATUS2 1025
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 108
+#define _APS_NEXT_RESOURCE_VALUE 109
#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1017
+#define _APS_NEXT_CONTROL_VALUE 1020
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
diff --git a/protocols/ICQ-WIM/src/server.cpp b/protocols/ICQ-WIM/src/server.cpp
index 9f7a36ef15..c7f7bb3c05 100644
--- a/protocols/ICQ-WIM/src/server.cpp
+++ b/protocols/ICQ-WIM/src/server.cpp
@@ -97,6 +97,26 @@ void CIcqProto::CheckPassword()
else StartSession();
}
+void CIcqProto::CheckStatus()
+{
+ time_t now = time(0);
+ int diff1 = m_iTimeDiff1, diff2 = m_iTimeDiff2;
+
+ for (auto &it : m_arCache) {
+ if (diff2 && it->m_timer2 && now - it->m_timer2 > m_iTimeDiff2) {
+ it->m_timer2 = 0;
+ setDword(it->m_hContact, "Status", m_iStatus2);
+ continue;
+ }
+
+ if (diff1 && it->m_timer1 && now - it->m_timer1 > diff1) {
+ setDword(it->m_hContact, "Status", m_iStatus1);
+ it->m_timer1 = 0;
+ it->m_timer2 = now;
+ }
+ }
+}
+
void CIcqProto::ConnectionFailed(int iReason, int iErrorCode)
{
debugLogA("ConnectionFailed -> reason %d", iReason);
@@ -136,26 +156,47 @@ void CIcqProto::MoveContactToGroup(MCONTACT hContact, const wchar_t *pwszGroup,
Push(pReq);
}
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static void CALLBACK CheckStatusTimerProc(HWND, UINT, UINT_PTR id, DWORD)
+{
+ CIcqProto *ppro = (CIcqProto*)(id - 1);
+ ppro->CheckStatus();
+}
+
void CIcqProto::OnLoggedIn()
{
debugLogA("CIcqProto::OnLoggedIn");
m_bOnline = true;
+
+ ::SetTimer(g_hwndHeartbeat, UINT_PTR(this)+1, 1000, CheckStatusTimerProc);
+ for (auto &it : m_arCache)
+ it->m_timer1 = it->m_timer2 = 0;
+
SetServerStatus(m_iDesiredStatus);
RetrieveUserInfo(0);
GetPermitDeny();
}
+/////////////////////////////////////////////////////////////////////////////////////////
+
void CIcqProto::OnLoggedOut()
{
debugLogA("CIcqProto::OnLoggedOut");
m_bOnline = false;
+ ::KillTimer(g_hwndHeartbeat, UINT_PTR(this)+1);
+ for (auto &it : m_arCache)
+ it->m_timer1 = it->m_timer2 = 0;
+
ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)m_iStatus, ID_STATUS_OFFLINE);
m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
setAllContactStatuses(ID_STATUS_OFFLINE, false);
}
+/////////////////////////////////////////////////////////////////////////////////////////
+
MCONTACT CIcqProto::ParseBuddyInfo(const JSONNode &buddy, MCONTACT hContact)
{
// user chat?
diff --git a/protocols/ICQ-WIM/src/utils.cpp b/protocols/ICQ-WIM/src/utils.cpp
index a962cb6a3c..afebaba7f4 100644
--- a/protocols/ICQ-WIM/src/utils.cpp
+++ b/protocols/ICQ-WIM/src/utils.cpp
@@ -226,15 +226,15 @@ bool IsChat(const CMStringW &aimid)
int StatusFromString(const CMStringW &wszStatus)
{
- if (wszStatus == "online")
+ if (wszStatus == L"online")
return ID_STATUS_ONLINE;
- if (wszStatus == "n/a")
+ if (wszStatus == L"n/a")
return ID_STATUS_NA;
- if (wszStatus == "away")
+ if (wszStatus == L"away")
return ID_STATUS_AWAY;
- if (wszStatus == "occupied")
+ if (wszStatus == L"occupied")
return ID_STATUS_OCCUPIED;
- if (wszStatus == "dnd")
+ if (wszStatus == L"dnd")
return ID_STATUS_DND;
return ID_STATUS_OFFLINE;