summaryrefslogtreecommitdiff
path: root/plugins/NewAwaySysMod/src/Client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/NewAwaySysMod/src/Client.cpp')
-rw-r--r--plugins/NewAwaySysMod/src/Client.cpp232
1 files changed, 232 insertions, 0 deletions
diff --git a/plugins/NewAwaySysMod/src/Client.cpp b/plugins/NewAwaySysMod/src/Client.cpp
new file mode 100644
index 0000000000..9d8c520f7c
--- /dev/null
+++ b/plugins/NewAwaySysMod/src/Client.cpp
@@ -0,0 +1,232 @@
+/*
+ New Away System - plugin for Miranda IM
+ Copyright (c) 2005-2007 Chervov Dmitry
+ Copyright (c) 2004-2005 Iksaif Entertainment
+ Copyright (c) 2002-2003 Goblineye Entertainment
+
+ 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 "Common.h"
+#include "MsgTree.h"
+#include "Properties.h"
+
+#define PARSE_INTERVAL 10000
+
+HANDLE g_hTerminateUpdateMsgsThread = NULL;
+HANDLE g_hUpdateMsgsThread = NULL;
+
+void __cdecl UpdateMsgsThreadProc(void *)
+{
+ int ProtoCount;
+ PROTOCOLDESCRIPTOR **proto;
+ CallService(MS_PROTO_ENUMACCOUNTS, (WPARAM)&ProtoCount, (LPARAM)&proto);
+ int I;
+ while (WaitForSingleObject(g_hTerminateUpdateMsgsThread, 0) == WAIT_TIMEOUT && !Miranda_Terminated())
+ {
+ DWORD MinUpdateTimeDifference = g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_UPDATEMSGSPERIOD) * 1000; // in milliseconds
+ for (I = 0; I < ProtoCount; I++)
+ {
+ if (proto[I]->type == PROTOTYPE_PROTOCOL && CallProtoService(proto[I]->szName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND && !IsAnICQProto(proto[I]->szName))
+ {
+ int Status = CallProtoService(proto[I]->szName, PS_GETSTATUS, 0, 0);
+ if (Status < ID_STATUS_OFFLINE || Status > ID_STATUS_OUTTOLUNCH)
+ {
+ Status = g_ProtoStates[proto[I]->szName].Status;
+ }
+ if (CallProtoService(proto[I]->szName, PS_GETCAPS, PFLAGNUM_3, 0) & Proto_Status2Flag(Status) && g_ProtoStates[proto[I]->szName].CurStatusMsg.GetUpdateTimeDifference() >= MinUpdateTimeDifference)
+ {
+ TCString CurMsg(GetDynamicStatMsg(INVALID_CONTACT_ID, proto[I]->szName));
+ if ((TCString)g_ProtoStates[proto[I]->szName].CurStatusMsg != (const TCHAR*)CurMsg) // if the message has changed
+ {
+ g_ProtoStates[proto[I]->szName].CurStatusMsg = CurMsg;
+ CallAllowedPS_SETAWAYMSG(proto[I]->szName, Status, (char*)_T2A(CurMsg));
+ }
+ }
+ }
+ }
+ SleepEx(PARSE_INTERVAL, true);
+ }
+}
+
+
+static void __stdcall DummyAPCFunc(ULONG_PTR)
+{
+ return;
+}
+
+
+void InitUpdateMsgs()
+{
+ int UpdateMsgs = g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_UPDATEMSGS);
+ if (g_hUpdateMsgsThread && !UpdateMsgs)
+ {
+ _ASSERT(WaitForSingleObject(g_hUpdateMsgsThread, 0) == WAIT_TIMEOUT);
+ SetEvent(g_hTerminateUpdateMsgsThread);
+ QueueUserAPC(DummyAPCFunc, g_hUpdateMsgsThread, 0); // wake up the thread, as it's most probably in SleepEx() now
+ WaitForSingleObject(g_hUpdateMsgsThread, INFINITE);
+ g_hUpdateMsgsThread = NULL;
+ CloseHandle(g_hTerminateUpdateMsgsThread);
+ } else if (!g_hUpdateMsgsThread && UpdateMsgs)
+ {
+ g_hTerminateUpdateMsgsThread = CreateEvent(NULL, TRUE, FALSE, NULL);
+ g_hUpdateMsgsThread = (HANDLE)mir_forkthread(UpdateMsgsThreadProc, NULL);
+ }
+}
+
+
+void ChangeProtoMessages(char* szProto, int iMode, TCString &Msg)
+{
+ TCString CurMsg(Msg);
+ if (szProto)
+ {
+ if (Msg == NULL)
+ {
+ CurMsg = GetDynamicStatMsg(INVALID_CONTACT_ID, szProto);
+ }
+ CallAllowedPS_SETAWAYMSG(szProto, iMode, (char*)_T2A(CurMsg));
+ g_ProtoStates[szProto].CurStatusMsg = CurMsg;
+ } else // change message of all protocols
+ {
+ int ProtoCount;
+ PROTOCOLDESCRIPTOR **proto;
+ CallService(MS_PROTO_ENUMACCOUNTS, (WPARAM)&ProtoCount, (LPARAM)&proto);
+ int I;
+ for (I = 0; I < ProtoCount; I++)
+ {
+ if (proto[I]->type == PROTOTYPE_PROTOCOL && !db_get_b(NULL, proto[I]->szName, "LockMainStatus", 0))
+ {
+ if (Msg == NULL)
+ {
+ CurMsg = GetDynamicStatMsg(INVALID_CONTACT_ID, proto[I]->szName);
+ }
+ CallAllowedPS_SETAWAYMSG(proto[I]->szName, iMode, (char*)_T2A(CurMsg));
+ g_ProtoStates[proto[I]->szName].CurStatusMsg = CurMsg;
+ }
+ }
+ }
+ static struct
+ {
+ int Status;
+ char *Setting;
+ } StatusSettings[] = {
+ ID_STATUS_OFFLINE, "Off",
+ ID_STATUS_ONLINE, "On",
+ ID_STATUS_AWAY, "Away",
+ ID_STATUS_NA, "Na",
+ ID_STATUS_DND, "Dnd",
+ ID_STATUS_OCCUPIED, "Occupied",
+ ID_STATUS_FREECHAT, "FreeChat",
+ ID_STATUS_INVISIBLE, "Inv",
+ ID_STATUS_ONTHEPHONE, "Otp",
+ ID_STATUS_OUTTOLUNCH, "Otl",
+ ID_STATUS_IDLE, "Idl"
+ };
+ int I;
+ for (I = 0; I < lengthof(StatusSettings); I++)
+ {
+ if (iMode == StatusSettings[I].Status)
+ {
+ db_set_ts(NULL, "SRAway", CString(StatusSettings[I].Setting) + "Msg", CurMsg);
+ db_set_ts(NULL, "SRAway", CString(StatusSettings[I].Setting) + "Default", CurMsg); // TODO: make it more accurate, and change not only here, but when changing status messages through UpdateMsgsTimerFunc too; and when changing messages through AutoAway() ?
+ break;
+ }
+ }
+// InitUpdateMsgs();
+}
+
+
+int GetRecentGroupID(int iMode)
+{ // returns an ID of a group where recent messages are stored, accordingly to current settings and status mode.
+ // -1 if the group is not found
+// COptPage MoreOptData(g_MoreOptPage);
+ COptPage MsgTreeData(g_MsgTreePage);
+ COptItem_TreeCtrl *TreeCtrl = (COptItem_TreeCtrl*)MsgTreeData.Find(IDV_MSGTREE);
+ TreeCtrl->DBToMem(CString(MOD_NAME));
+ int Order;
+ if (g_MoreOptPage.GetDBValueCopy(IDC_MOREOPTDLG_PERSTATUSMRM))
+ {
+ for (Order = 0; Order < TreeCtrl->Value.GetSize(); Order++) // find a group named accordingly to the current status
+ {
+ if (TreeCtrl->Value[Order].ParentID == g_Messages_RecentRootID && TreeCtrl->Value[Order].Flags & TIF_GROUP && !_tcsicmp(TreeCtrl->Value[Order].Title, iMode ? (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iMode, GSMDF_TCHAR) : MSGTREE_RECENT_OTHERGROUP))
+ {
+ return TreeCtrl->Value[Order].ID;
+ }
+ }
+ } else // simply use Recent Messages category
+ {
+ return g_Messages_RecentRootID;
+ }
+ return -1;
+}
+
+
+int ICQStatusToGeneralStatus(int bICQStat)
+{
+ switch (bICQStat)
+ {
+ case MTYPE_AUTOONLINE: return ID_STATUS_ONLINE;
+ case MTYPE_AUTOAWAY: return ID_STATUS_AWAY;
+ case MTYPE_AUTONA: return ID_STATUS_NA;
+ case MTYPE_AUTODND: return ID_STATUS_DND;
+ case MTYPE_AUTOBUSY: return ID_STATUS_OCCUPIED;
+ case MTYPE_AUTOFFC: return ID_STATUS_FREECHAT;
+ default: return 0;
+ }
+}
+
+
+TCString VariablesEscape(TCString Str)
+{
+ if (!Str.GetLen())
+ {
+ return _T("");
+ }
+ enum eState
+ {
+ ST_TEXT, ST_QUOTE
+ };
+ eState State = ST_QUOTE;
+ TCString Result(_T("`"));
+ const TCHAR *p = Str;
+ while (*p)
+ {
+ if (*p == '`')
+ {
+ if (State == ST_TEXT)
+ {
+ Result += _T("````");
+ State = ST_QUOTE;
+ } else
+ {
+ Result += _T("``");
+ }
+ } else
+ {
+ Result += *p;
+ State = ST_TEXT;
+ }
+ p++;
+ }
+ if (State == ST_QUOTE)
+ {
+ Result.GetBuffer()[Result.GetLen() - 1] = '\0';
+ Result.ReleaseBuffer();
+ } else
+ {
+ Result += '`';
+ }
+ return Result;
+}