diff options
| author | Vadim Dashevskiy <watcherhd@gmail.com> | 2012-07-23 13:49:28 +0000 | 
|---|---|---|
| committer | Vadim Dashevskiy <watcherhd@gmail.com> | 2012-07-23 13:49:28 +0000 | 
| commit | a9580df150d799246eaecbf3c1fb5cecf9f8ab49 (patch) | |
| tree | ce046b1cd432d65718c9f6af80521d533ce6d4ca /plugins/SeenPlugin/src | |
| parent | 60338d55bb73d0c45b6e092703c4bb88a3c49755 (diff) | |
SecureIM, SeenPlugin, SendSS, Sessions: changed folder structure 
git-svn-id: http://svn.miranda-ng.org/main/trunk@1122 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/SeenPlugin/src')
| -rw-r--r-- | plugins/SeenPlugin/src/file.cpp | 119 | ||||
| -rw-r--r-- | plugins/SeenPlugin/src/history.cpp | 347 | ||||
| -rw-r--r-- | plugins/SeenPlugin/src/main.cpp | 136 | ||||
| -rw-r--r-- | plugins/SeenPlugin/src/menu.cpp | 113 | ||||
| -rw-r--r-- | plugins/SeenPlugin/src/missed.cpp | 301 | ||||
| -rw-r--r-- | plugins/SeenPlugin/src/options.cpp | 494 | ||||
| -rw-r--r-- | plugins/SeenPlugin/src/resource.h | 93 | ||||
| -rw-r--r-- | plugins/SeenPlugin/src/seen.h | 134 | ||||
| -rw-r--r-- | plugins/SeenPlugin/src/userinfo.cpp | 95 | ||||
| -rw-r--r-- | plugins/SeenPlugin/src/utils.cpp | 878 | 
10 files changed, 2710 insertions, 0 deletions
diff --git a/plugins/SeenPlugin/src/file.cpp b/plugins/SeenPlugin/src/file.cpp new file mode 100644 index 0000000000..cac37f8c30 --- /dev/null +++ b/plugins/SeenPlugin/src/file.cpp @@ -0,0 +1,119 @@ +/*
 +"Last Seen mod" plugin for Miranda IM
 +Copyright ( C ) 2002-03  micron-x
 +Copyright ( C ) 2005-07  Y.B.
 +
 +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.
 +
 +File name      : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/file.c $
 +Revision       : $Rev: 1570 $
 +Last change on : $Date: 2007-12-30 01:30:07 +0300 (Вс, 30 дек 2007) $
 +Last change by : $Author: y_b $
 +*/
 +
 +#include "seen.h"
 +/*
 +Prepares the log file:
 +- calculates the absolute path (and store it in the db)
 +- creates the directory
 +
 +*/
 +int InitFileOutput(void)
 +{
 +	char szfpath[256]="",szmpath[256]="",*str;
 +	DBVARIANT dbv;
 +
 +	GetModuleFileName(NULL,szmpath,MAX_PATH);
 +	strcpy(szfpath,!DBGetContactSetting(NULL,S_MOD,"FileName",&dbv)?dbv.pszVal:DEFAULT_FILENAME);
 +
 +	DBFreeVariant(&dbv);
 +
 +	if(szfpath[0]=='\\')
 +		strcpy(szfpath,szfpath+1);
 +
 +	str=strrchr(szmpath,'\\');
 +	if(str!=NULL)
 +		*++str=0;
 +
 +	strcat(szmpath,szfpath);
 +	
 +	strcpy(szfpath,szmpath);
 +
 +	str=strrchr(szmpath,'\\');
 +	if(str!=NULL)
 +		*++str=0;
 +/*
 +//we dont need this anylonger. the directory is created in filewrite 
 +	if (!CreateDirectory(szmpath,NULL))
 +	{
 +		if (!(GetFileAttributes(szmpath) & FILE_ATTRIBUTE_DIRECTORY))
 +		{		
 +			MessageBox(NULL,"Directory could not be created\nPlease choose another!","Last seen plugin",MB_OK|MB_ICONERROR);
 +			DBWriteContactSettingByte(NULL,S_MOD,"FileOutput",0);
 +			return 0;
 +		}
 +	}
 +*/
 +	DBWriteContactSettingString(NULL,S_MOD,"PathToFile",szfpath);
 +
 +	return 0;
 +}
 +
 +//borrowed from netliblog.c
 +static void CreateDirectoryTree(char *szDir)
 +{
 +	DWORD dwAttributes;
 +	char *pszLastBackslash,szTestDir[MAX_PATH];
 +
 +	lstrcpynA(szTestDir,szDir,sizeof(szTestDir));
 +	if ((dwAttributes=GetFileAttributesA(szTestDir))!=0xffffffff && dwAttributes&FILE_ATTRIBUTE_DIRECTORY) return;
 +	pszLastBackslash=strrchr(szTestDir,'\\');
 +	if(pszLastBackslash==NULL) return;
 +	*pszLastBackslash='\0';
 +	CreateDirectoryTree(szTestDir);
 +	CreateDirectoryA(szTestDir,NULL);
 +}
 +
 +/*
 +Writes a line into the log.
 +*/
 +void FileWrite(HANDLE hcontact)
 +{
 +	HANDLE fhout;
 +	DWORD byteswritten;
 +	char szout[1024],sznl[3]="\r\n";
 +	DBVARIANT dbv;
 +
 +	DBGetContactSetting(NULL,S_MOD,"PathToFile",&dbv);
 +	strcpy(szout,ParseString(dbv.pszVal,hcontact,1));
 +	fhout=CreateFile(szout,GENERIC_WRITE,0,NULL,OPEN_ALWAYS,0,NULL);
 +	if (fhout==INVALID_HANDLE_VALUE){
 +		CreateDirectoryTree(szout);
 +		fhout=CreateFile(szout,GENERIC_WRITE,0,NULL,OPEN_ALWAYS,0,NULL);
 +		if (fhout==INVALID_HANDLE_VALUE) return;
 +	}
 +	DBFreeVariant(&dbv);
 +	SetFilePointer(fhout,0,0,FILE_END);
 +
 +	strcpy(szout,ParseString(!DBGetContactSetting(NULL,S_MOD,"FileStamp",&dbv)?dbv.pszVal:DEFAULT_FILESTAMP,hcontact,1));
 +	DBFreeVariant(&dbv);
 +	
 +	WriteFile(fhout,szout, (DWORD)_tcslen(szout),&byteswritten,NULL);
 +	WriteFile(fhout,sznl, (DWORD)_tcslen(sznl),&byteswritten,NULL);
 +
 +	CloseHandle(fhout);
 +
 +	
 +}
 diff --git a/plugins/SeenPlugin/src/history.cpp b/plugins/SeenPlugin/src/history.cpp new file mode 100644 index 0000000000..724cfd5612 --- /dev/null +++ b/plugins/SeenPlugin/src/history.cpp @@ -0,0 +1,347 @@ +/*
 +"Last Seen mod" plugin for Miranda IM
 +Copyright ( C ) 2002-03  micron-x
 +Copyright ( C ) 2005-06  Y.B.
 +
 +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.
 +
 +File name      : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/history.c $
 +Revision       : $Rev: 1056 $
 +Last change on : $Date: 2006-10-30 06:22:07 +0300 (Пн, 30 окт 2006) $
 +Last change by : $Author: y_b $
 +*/
 +#include "seen.h"
 +
 +
 +extern HINSTANCE hInstance;
 +
 +static HANDLE hWindowList;
 +
 +char* BuildSetting(int historyLast) {
 +	static char setting[15];
 +	static char sztemp[15];
 +	*setting = '\0';
 +	strcat(setting, "History_");
 +	strcat(setting, itoa(historyLast, sztemp, 10));
 +	return setting;
 +}
 +
 +void HistoryWrite(HANDLE hContact)
 +{
 +	short historyFirst, historyLast, historyMax;
 +	DBVARIANT dbv;
 +
 +	historyMax = DBGetContactSettingWord(NULL,S_MOD,"HistoryMax",10);
 +	if (historyMax < 0) historyMax=0; else if (historyMax > 99) historyMax = 99;
 +	if (historyMax == 0) return;
 +	historyFirst = DBGetContactSettingWord(hContact,S_MOD,"HistoryFirst",0);
 +	if (historyFirst >=  historyMax) historyFirst = 0;
 +	historyLast = DBGetContactSettingWord(hContact,S_MOD,"HistoryLast",0);
 +	if (historyLast >= historyMax) historyLast = historyMax-1;
 +
 +	DBWriteContactSettingString(hContact,S_MOD,BuildSetting(historyLast),
 +			ParseString(!DBGetContactSetting(NULL,S_MOD,"HistoryStamp",&dbv)?dbv.pszVal:DEFAULT_HISTORYSTAMP,hContact,0));
 +	DBFreeVariant(&dbv);
 +
 +	historyLast = (historyLast+1) % historyMax;
 +	DBWriteContactSettingWord(hContact,S_MOD,"HistoryLast",historyLast);
 +	if (historyLast == historyFirst) {
 +		DBWriteContactSettingWord(hContact,S_MOD,"HistoryFirst",(short) ((historyFirst+1) % historyMax));
 +	}
 +
 +}
 +
 +void LoadHistoryList(HANDLE hContact, HWND hwnd, int nList) {
 +	short historyFirst, historyLast, historyMax;
 +	short i;
 +	DBVARIANT dbv;
 +
 +
 +	SendDlgItemMessage(hwnd, nList, LB_RESETCONTENT, 0, 0);
 +	historyMax = DBGetContactSettingWord(NULL,S_MOD,"HistoryMax",10);
 +	if (historyMax < 0) historyMax = 0; else if (historyMax > 99) historyMax = 99;
 +	if (historyMax == 0) return;
 +	historyFirst = DBGetContactSettingWord(hContact,S_MOD,"HistoryFirst",0);
 +	if (historyFirst >=  historyMax) historyFirst = 0;
 +	historyLast = DBGetContactSettingWord(hContact,S_MOD,"HistoryLast",0);
 +	if (historyLast >= historyMax) historyLast = historyMax-1;
 +	
 +	i = historyLast;
 +	while (i != historyFirst) {
 +		i = (i-1+historyMax) % historyMax;
 +		SendDlgItemMessage(hwnd, nList, LB_ADDSTRING, 0, 
 +				(LPARAM)(!DBGetContactSetting(hContact,S_MOD,BuildSetting(i),&dbv)?dbv.pszVal:""));
 +		DBFreeVariant(&dbv);
 +	}
 +
 +}
 +
 +
 +HDWP MyResizeWindow (HDWP hDwp, HWND hwndDlg, HWND hwndControl,
 +				 int nHorizontalOffset, int nVerticalOffset, 
 +				 int nWidthOffset, int nHeightOffset)
 +{
 +	POINT pt;
 +	RECT rcinit;
 +
 +	// get current bounding rectangle
 +	GetWindowRect(hwndControl, &rcinit);
 +	
 +	// get current top left point
 +	pt.x = rcinit.left;
 +	pt.y = rcinit.top;
 +	ScreenToClient(hwndDlg, &pt);
 +
 +	// resize control
 +/*	MoveWindow(hwndControl, 
 +			pt.x + nHorizontalOffset, 
 +			pt.y + nVerticalOffset,
 +			rcinit.right - rcinit.left + nWidthOffset, 
 +			rcinit.bottom - rcinit.top + nHeightOffset,
 +			FALSE);
 +*/
 +	return DeferWindowPos(hDwp, hwndControl, NULL,
 +			pt.x + nHorizontalOffset, 
 +			pt.y + nVerticalOffset,
 +			rcinit.right - rcinit.left + nWidthOffset, 
 +			rcinit.bottom - rcinit.top + nHeightOffset,
 +			SWP_NOZORDER);
 +
 +
 +}
 +
 +HDWP MyHorizCenterWindow (HDWP hDwp, HWND hwndDlg, HWND hwndControl,
 +				 int nClientWidth, int nVerticalOffset, 
 +				 int nHeightOffset)
 +{
 +	POINT pt;
 +	RECT rcinit;
 +
 +	// get current bounding rectangle
 +	GetWindowRect(hwndControl, &rcinit);
 +	
 +	// get current top left point
 +	pt.x = rcinit.left;
 +	pt.y = rcinit.top;
 +	ScreenToClient(hwndDlg, &pt);
 +
 +	// resize control
 +/*	MoveWindow(hwndControl, 
 +			(int) ((nClientWidth - (rcinit.right - rcinit.left))/2), 
 +			pt.y + nVerticalOffset,
 +			rcinit.right - rcinit.left, 
 +			rcinit.bottom - rcinit.top + nHeightOffset,
 +			TRUE);
 +*/
 +	return DeferWindowPos(hDwp, hwndControl, NULL,
 +			(int) ((nClientWidth - (rcinit.right - rcinit.left))/2), 
 +			pt.y + nVerticalOffset,
 +			rcinit.right - rcinit.left, 
 +			rcinit.bottom - rcinit.top + nHeightOffset,
 +			SWP_NOZORDER);
 +
 +}
 +void MyResizeGetOffset (HWND hwndDlg, HWND hwndControl, 
 +				 int nWidth, int nHeight,
 +				 int* nDx, int* nDy)
 +{
 +	RECT rcinit;
 +
 +	// get current bounding rectangle
 +	GetWindowRect(hwndControl, &rcinit);
 +	
 +	// calculate offsets
 +	*nDx = nWidth - (rcinit.right - rcinit.left);
 +	*nDy = nHeight - (rcinit.bottom - rcinit.top);
 +}
 +
 +INT_PTR CALLBACK HistoryDlgProc(HWND hwndDlg, UINT Message, WPARAM wparam, LPARAM lparam)
 +{
 +	HANDLE hContact;
 +	char sztemp[1024]="";
 +	static HIMAGELIST hIml=NULL;
 +	
 +	switch(Message)
 +    {
 +		case WM_INITDIALOG:
 +			TranslateDialogDefault(hwndDlg);
 +			hContact = (HANDLE)lparam;
 +			SetWindowLongPtr(hwndDlg,GWLP_USERDATA,lparam);
 +			strcpy(sztemp,(char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,0));
 +			strcat(sztemp, ": ");
 +			strcat(sztemp, Translate("last seen history"));
 +			SendMessage(hwndDlg, WM_SETTEXT, 0, (LPARAM)sztemp);
 +			SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) LoadSkinnedIcon(SKINICON_OTHER_MIRANDA));
 +			SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_SMALL, (LPARAM) LoadSkinnedIcon(SKINICON_OTHER_MIRANDA));
 +
 +//			LoadHistoryList(hContact, hwndDlg, IDC_HISTORYLIST);
 +
 +			if (DBGetContactSettingByte(hContact,S_MOD,"OnlineAlert",0))
 +				SendDlgItemMessage(hwndDlg, IDC_STATUSCHANGE, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
 +			{
 +				hIml=ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),ILC_COLOR32|ILC_MASK,3,3);
 +				ImageList_AddIcon(hIml,LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_USERDETAILS)));
 +				ImageList_AddIcon(hIml,LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_DOWNARROW)));
 +				ImageList_AddIcon(hIml,LoadSkinnedIcon(SKINICON_EVENT_MESSAGE));
 +				SendDlgItemMessage(hwndDlg,IDC_DETAILS,BM_SETIMAGE,IMAGE_ICON,(WPARAM)ImageList_GetIcon(hIml,0,ILD_NORMAL));
 +				SendDlgItemMessage(hwndDlg,IDC_USERMENU,BM_SETIMAGE,IMAGE_ICON,(WPARAM)ImageList_GetIcon(hIml,1,ILD_NORMAL));
 +				SendDlgItemMessage(hwndDlg,IDC_SENDMSG,BM_SETIMAGE,IMAGE_ICON,(WPARAM)ImageList_GetIcon(hIml,2,ILD_NORMAL));
 +			}
 +
 +			//set-up tooltips
 +			{
 +				HWND hwndDlgToolTips;
 +				TOOLINFO ti;
 +
 +				hwndDlgToolTips = CreateWindowEx(WS_EX_TOPMOST,TOOLTIPS_CLASS,"",WS_POPUP,0,0,0,0,NULL,NULL,GetModuleHandle(NULL),NULL);
 +				ZeroMemory(&ti,sizeof(ti));
 +				ti.cbSize=sizeof(ti);
 +				ti.uFlags=TTF_IDISHWND|TTF_SUBCLASS;
 +				ti.uId=(UINT)GetDlgItem(hwndDlg,IDC_USERMENU);
 +				ti.lpszText=Translate("User Menu");
 +				SendMessage(hwndDlgToolTips,TTM_ADDTOOL,0,(LPARAM)&ti);
 +				ti.uId=(UINT)GetDlgItem(hwndDlg,IDC_DETAILS);
 +				ti.lpszText=Translate("View User's Details");
 +				SendMessage(hwndDlgToolTips,TTM_ADDTOOL,0,(LPARAM)&ti);
 +				ti.uId=(UINT)GetDlgItem(hwndDlg,IDC_SENDMSG);
 +				ti.lpszText=Translate("Send Instant Message");
 +				SendMessage(hwndDlgToolTips,TTM_ADDTOOL,0,(LPARAM)&ti);
 +			}
 +
 +
 +			Utils_RestoreWindowPositionNoMove(hwndDlg,NULL,S_MOD,"History_");
 +			ShowWindow(hwndDlg, SW_SHOW);
 +			break;
 +
 +		case WM_MEASUREITEM:
 +			return CallService(MS_CLIST_MENUMEASUREITEM,wparam,lparam);
 +		case WM_DRAWITEM:
 +			return CallService(MS_CLIST_MENUDRAWITEM,wparam,lparam);
 +        case WM_COMMAND:
 +			hContact=(HANDLE)GetWindowLongPtr(hwndDlg,GWLP_USERDATA);
 +			if(CallService(MS_CLIST_MENUPROCESSCOMMAND,MAKEWPARAM(LOWORD(wparam),MPCF_CONTACTMENU),(LPARAM)hContact))
 +				break;
 +            switch(LOWORD(wparam))
 +            {
 +				case IDCANCEL:
 +					SendMessage(hwndDlg, WM_CLOSE, 0, 0);
 +					break;
 +				case IDOK:
 +					if (SendDlgItemMessage(hwndDlg, IDC_STATUSCHANGE, BM_GETCHECK, 0, 0) == BST_CHECKED)
 +						DBWriteContactSettingByte(hContact,S_MOD,"OnlineAlert",1);
 +					else
 +						DBWriteContactSettingByte(hContact,S_MOD,"OnlineAlert",0);
 +					SendMessage(hwndDlg, WM_CLOSE, 0, 0);
 +					break;
 +				case IDC_USERMENU:
 +					{	
 +						RECT rc;
 +						HMENU hMenu=(HMENU)CallService(MS_CLIST_MENUBUILDCONTACT,(WPARAM)hContact,0);
 +						GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU),&rc);
 +						TrackPopupMenu(hMenu,0,rc.left,rc.bottom,0,hwndDlg,NULL);
 +						DestroyMenu(hMenu);
 +					}
 +					break;
 +				case IDC_DETAILS:
 +					CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)hContact,0);
 +					break;
 +				case IDC_SENDMSG:
 +					CallService(MS_MSG_SENDMESSAGE,(WPARAM)hContact,0);
 +					break;
 +                case IDC_TEST:
 +					debug(ParseString("Date: %d.%m.%y(%Y) \n Date desc: %W - %w - %E - %e \n Time: %H:%M:%S (%h-%p) \n user: %n - %u \n Status: %s \n IP: %i - %r",hContact,0));
 +					break;
 +            }
 +			break;
 +		case WM_SIZE:
 +			{
 +				int dx, dy;
 +				HDWP hDwp;
 +
 +				hDwp = BeginDeferWindowPos(6);
 +				MyResizeGetOffset(hwndDlg, GetDlgItem(hwndDlg, IDC_HISTORYLIST), 
 +						LOWORD(lparam)-15, HIWORD(lparam)-99, &dx, &dy);
 +				hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_USERMENU), 
 +						dx, 0, 0, 0);
 +				hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_DETAILS), 
 +						dx, 0, 0, 0);
 +				hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_SENDMSG), 
 +						dx, 0, 0, 0);
 +				hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_HISTORYLIST), 
 +						0, 0, dx, dy);
 +				hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_STATUSCHANGE), 
 +						0, dy, dx, 0);
 +				hDwp = MyHorizCenterWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDOK), 
 +						LOWORD(lparam), dy, 0);
 +				EndDeferWindowPos(hDwp);
 +			}				
 +			break;
 +		case WM_GETMINMAXINFO:
 +			{
 +				MINMAXINFO mmi;
 +				CopyMemory (&mmi, (LPMINMAXINFO) lparam, sizeof (MINMAXINFO));
 +
 +				/* The minimum width in points*/
 +				mmi.ptMinTrackSize.x = 200;
 +				/* The minimum height in points*/
 +				mmi.ptMinTrackSize.y = 190;
 +
 +				CopyMemory ((LPMINMAXINFO) lparam, &mmi, sizeof (MINMAXINFO));
 +			}
 +			break;
 +
 +        case WM_CLOSE:
 +            DestroyWindow(hwndDlg);
 +			WindowList_Remove(hWindowList,hwndDlg);
 +			break;
 +		case WM_DESTROY:
 +			Utils_SaveWindowPosition(hwndDlg,NULL,S_MOD,"History_");
 +			ImageList_Destroy(hIml);
 +			break;
 +        default:
 +            return FALSE;
 +    }
 +	return TRUE;
 +}
 +
 +void ShowHistory(HANDLE hContact, BYTE isAlert)
 +{
 +	HWND hHistoryDlg;
 +	
 +	hHistoryDlg = WindowList_Find(hWindowList,hContact);
 +	if (hHistoryDlg == NULL)
 +	{
 +		hHistoryDlg = CreateDialogParam(hInstance,MAKEINTRESOURCE(IDD_HISTORY),NULL,HistoryDlgProc,(LPARAM)hContact);
 +		LoadHistoryList(hContact, hHistoryDlg, IDC_HISTORYLIST);
 +		WindowList_Add(hWindowList,hHistoryDlg,hContact);
 +	} 
 +	else 
 +	{
 +		SetForegroundWindow(hHistoryDlg);
 +		LoadHistoryList(hContact, hHistoryDlg, IDC_HISTORYLIST);
 +		SetFocus(hHistoryDlg);
 +	}
 +	
 +	if (isAlert) 
 +	{
 +		SkinPlaySound("LastSeenTrackedStatusChange");
 +	}
 +}
 +
 +
 +void InitHistoryDialog(void)
 +{
 +	hWindowList=(HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST,0,0);
 +}
 diff --git a/plugins/SeenPlugin/src/main.cpp b/plugins/SeenPlugin/src/main.cpp new file mode 100644 index 0000000000..68a774e435 --- /dev/null +++ b/plugins/SeenPlugin/src/main.cpp @@ -0,0 +1,136 @@ +/*
 +"Last Seen mod" plugin for Miranda IM
 +Copyright ( C ) 2002-03  micron-x
 +Copyright ( C ) 2005-07  Y.B.
 +
 +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.
 +
 +File name      : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/main.c $
 +Revision       : $Rev: 1571 $
 +Last change on : $Date: 2007-12-30 04:55:51 +0300 (Вс, 30 дек 2007) $
 +Last change by : $Author: y_b $
 +*/
 +#include "seen.h"
 +
 +HINSTANCE hInstance;
 +HANDLE ehdb = NULL, ehproto = NULL, ehmissed = NULL, ehuserinfo = NULL, ehmissed_proto = NULL, hOptInit = NULL, hMainInit = NULL;
 +
 +int hLangpack;
 +
 +PLUGININFOEX pluginInfo={
 +		sizeof(PLUGININFOEX),
 +		"Last seen",
 +	     PLUGIN_MAKE_VERSION(5,0,4,7),
 +		"Log when a user was last seen online and which users were online while you were away.",
 +		"Heiko Schillinger, YB",
 +		"y_b@saaplugin.no-ip.info",
 +		" 2001-2002 Heiko Schillinger, 2003 modified by Bruno Rino, 2005-7 Modified by YB",
 +		"http://nightly.miranda.im/",
 +		UNICODE_AWARE,
 +		{ 0x2d506d46,0xc94e,0x4ef8,{0x85, 0x37, 0xf1, 0x12, 0x33, 0xa8, 0x03, 0x81}}/* 2d506d46-c94e-4ef8-8537-f11233a80381 */
 +};
 +
 +#define TRANSNUMBER 2
 +DBVTranslation idleTr[TRANSNUMBER]={
 +	{(TranslateFunc*)any_to_IdleNotidleUnknown, _T("Any to Idle/Not Idle/Unknown"),0},
 +	{(TranslateFunc*)any_to_Idle, _T("Any to /Idle or empty"),0}
 +};
 +
 +BOOL includeIdle;
 +logthread_info **contactQueue = NULL;
 +int contactQueueSize = 0;
 +
 +int MainInit(WPARAM wparam,LPARAM lparam)
 +{
 +	contactQueueSize = 16*sizeof(logthread_info *);
 +	contactQueue = (logthread_info **)malloc(contactQueueSize);
 +	memset(&contactQueue[0], 0, contactQueueSize);
 +	contactQueueSize = 16;
 +	includeIdle = (BOOL )DBGetContactSettingByte(NULL,S_MOD,"IdleSupport",1);
 +	hOptInit = HookEvent(ME_OPT_INITIALISE, OptionsInit);
 +	
 +	if(DBGetContactSettingByte(NULL,S_MOD,"MenuItem",1)) {
 +		InitMenuitem();
 +	}
 +	
 +	if(DBGetContactSettingByte(NULL,S_MOD,"UserinfoTab",1))
 +		ehuserinfo = HookEvent(ME_USERINFO_INITIALISE,UserinfoInit);
 +
 +	if(DBGetContactSettingByte(NULL,S_MOD,"FileOutput",0))
 +		InitFileOutput();
 +
 +	if(DBGetContactSettingByte(NULL,S_MOD,"MissedOnes",0))
 +		ehmissed_proto=HookEvent(ME_PROTO_ACK,ModeChange_mo);
 +
 +	ehdb = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, UpdateValues);
 +	ehproto = HookEvent(ME_PROTO_ACK,ModeChange);
 +
 +	SkinAddNewSoundEx("LastSeenTrackedStatusChange", LPGEN("LastSeen"), LPGEN("User status change"));
 +	SkinAddNewSoundEx("LastSeenTrackedStatusOnline", LPGEN("LastSeen"), LPGEN("Changed to Online"));
 +	SkinAddNewSoundEx("LastSeenTrackedStatusOffline", LPGEN("LastSeen"), LPGEN("User Logged Off"));
 +	SkinAddNewSoundEx("LastSeenTrackedStatusFromOffline", LPGEN("LastSeen"), LPGEN("User Logged In"));
 +	
 +	// known modules list
 +	if (ServiceExists("DBEditorpp/RegisterSingleModule"))
 +		CallService("DBEditorpp/RegisterSingleModule", (WPARAM)S_MOD, 0);
 +	DBWriteContactSettingString(NULL,"Uninstall",Translate("Last seen"),S_MOD);
 +
 +
 +	if ( ServiceExists(MS_TIPPER_ADDTRANSLATION)) {
 +		int i;
 +		for (i=0; i < TRANSNUMBER; i++)
 +			CallService(MS_TIPPER_ADDTRANSLATION, 0, (LPARAM)&idleTr[i]);
 +	}
 +
 +	return 0;
 +}
 +
 +extern "C" __declspec(dllexport) PLUGININFOEX * MirandaPluginInfoEx(DWORD mirandaVersion)
 +{
 +	return &pluginInfo;
 +}
 +
 +extern "C" __declspec(dllexport) int Unload(void)
 +{
 +	UnhookEvent(ehdb);
 +	if(ehmissed) UnhookEvent(ehmissed);
 +	UnhookEvent(ehproto);
 +	if(ehmissed_proto) UnhookEvent(ehmissed_proto);
 +	UnhookEvent(hOptInit);
 +	UnhookEvent(hMainInit);
 +	if (ehuserinfo) UnhookEvent(ehuserinfo);
 +	UninitMenuitem();
 +//	free(contactQueue);
 +	return 0;
 +}
 +
 +BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID lpvReserved)
 +{
 +	hInstance=hinst;
 +	return 1;
 +}
 +
 +extern "C" __declspec(dllexport) int Load(void)
 +{
 +
 +	mir_getLP(&pluginInfo);
 +	// this isn't required for most events
 +	// but the ME_USERINFO_INITIALISE
 +	// I decided to hook all events after
 +	// everything is loaded because it seems
 +	// to be safer in my opinion
 +	hMainInit = HookEvent(ME_SYSTEM_MODULESLOADED,MainInit);
 +	return 0;
 +}
\ No newline at end of file diff --git a/plugins/SeenPlugin/src/menu.cpp b/plugins/SeenPlugin/src/menu.cpp new file mode 100644 index 0000000000..02f241b793 --- /dev/null +++ b/plugins/SeenPlugin/src/menu.cpp @@ -0,0 +1,113 @@ +/*
 +"Last Seen mod" plugin for Miranda IM
 +Copyright ( C ) 2002-03  micron-x
 +Copyright ( C ) 2005-07  Y.B.
 +
 +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.
 +
 +File name      : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/menu.c $
 +Revision       : $Rev: 1570 $
 +Last change on : $Date: 2007-12-30 01:30:07 +0300 (Вс, 30 дек 2007) $
 +Last change by : $Author: y_b $
 +*/
 +#include "seen.h"
 +
 +HANDLE hmenuitem=NULL, hLSUserDet = NULL, hBuildMenu = NULL;
 +
 +void ShowHistory(HANDLE hContact, BYTE isAlert);
 +void InitHistoryDialog(void);
 +
 +/*
 +Handles the messages sent by clicking the contact's menu item
 +*/
 +INT_PTR MenuitemClicked(WPARAM wparam,LPARAM lparam)
 +{
 +	ShowHistory((HANDLE)wparam, 0);
 +	return 0;
 +}
 +
 +int BuildContactMenu(WPARAM wparam,LPARAM lparam)
 +{
 +	CLISTMENUITEM cmi;
 +	DBVARIANT dbv;
 +	int id=-1,isetting;
 +	HANDLE hContact;
 +	char *szProto;
 +
 +	hContact = (HANDLE)wparam;
 +	szProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0);
 +
 +	ZeroMemory(&cmi,sizeof(cmi));
 +	cmi.cbSize=sizeof(cmi);
 +	if (!IsWatchedProtocol(szProto) || !DBGetContactSettingByte(NULL,S_MOD,"MenuItem",1))
 +	{
 +		cmi.flags=CMIM_FLAGS|CMIF_HIDDEN;
 +	}
 +	else
 +	{
 +		cmi.flags=CMIM_NAME|CMIM_FLAGS|CMIM_ICON;
 +		cmi.hIcon=NULL;
 +		cmi.pszName=ParseString(!DBGetContactSetting(NULL,S_MOD,"MenuStamp",&dbv)?dbv.pszVal:DEFAULT_MENUSTAMP,(HANDLE)wparam,0);
 +		
 +		if (!strcmp(cmi.pszName,Translate("<unknown>")))
 +		{	
 +			if (IsWatchedProtocol(szProto))
 +				cmi.flags|=CMIF_GRAYED;
 +			else
 +				cmi.flags|=CMIF_HIDDEN;	
 +		} 
 +		else if(DBGetContactSettingByte(NULL,S_MOD,"ShowIcon",1))
 +		{
 +			isetting=DBGetContactSettingWord((HANDLE)hContact,S_MOD,"StatusTriger",-1);
 +			cmi.hIcon=LoadSkinnedProtoIcon(szProto,isetting|0x8000);
 +			
 +		}
 +	}
 +
 +	CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hmenuitem,(LPARAM)&cmi);
 +	DBFreeVariant(&dbv);
 +
 +	return 0;
 +}
 +
 +
 +
 +void InitMenuitem()
 +{
 +	CLISTMENUITEM cmi;
 +
 +	hLSUserDet = CreateServiceFunction("LastSeenUserDetails", MenuitemClicked);
 +
 +	ZeroMemory(&cmi,sizeof(cmi));
 +	cmi.cbSize=sizeof(cmi);
 +	cmi.flags=0;
 +	cmi.hIcon=NULL;
 +	cmi.hotKey=0;
 +	cmi.position=-0x7FFFFFFF;
 +	cmi.pszContactOwner=NULL;
 +	cmi.pszName="<none>";
 +	cmi.pszService="LastSeenUserDetails";
 +	hmenuitem = Menu_AddContactMenuItem(&cmi);
 +	
 +	hBuildMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU,BuildContactMenu);
 +
 +	InitHistoryDialog();
 +}
 +
 +void UninitMenuitem()
 +{
 +	DestroyServiceFunction(hLSUserDet);
 +	UnhookEvent(hBuildMenu);
 +}
\ No newline at end of file diff --git a/plugins/SeenPlugin/src/missed.cpp b/plugins/SeenPlugin/src/missed.cpp new file mode 100644 index 0000000000..179dd8ee4d --- /dev/null +++ b/plugins/SeenPlugin/src/missed.cpp @@ -0,0 +1,301 @@ +/*
 +"Last Seen mod" plugin for Miranda IM
 +Copyright ( C ) 2002-03  micron-x
 +Copyright ( C ) 2005-07  Y.B.
 +
 +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.
 +
 +File name      : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/missed.c $
 +Revision       : $Rev: 1570 $
 +Last change on : $Date: 2007-12-30 01:30:07 +0300 (Вс, 30 дек 2007) $
 +Last change by : $Author: y_b $
 +*/
 +#include "seen.h"
 +
 +#include <m_ignore.h>
 +
 +
 +
 +MISSEDCONTACTS mcs;
 +extern HANDLE ehmissed;
 +extern HINSTANCE hInstance;
 +
 +
 +
 +WPARAM IsUserMissed(WPARAM contact)
 +{
 +	int loop=0;
 +
 +	for (;loop<mcs.count;loop++)
 +	{
 +		if(mcs.wpcontact[loop]==contact)
 +			return MAKEWPARAM(1,loop);
 +	}
 +
 +	return 0;
 +}
 +
 +
 +
 +int RemoveUser(int pos)
 +{
 +	int loop;
 +
 +	for(loop=pos;loop<mcs.count-1;loop++)
 +		mcs.wpcontact[loop]=mcs.wpcontact[loop+1];
 +
 +	mcs.count--;
 +
 +	return 0;
 +}
 +
 +
 +
 +int ResetMissed(void)
 +{
 +	HANDLE hcontact=NULL;
 +
 +	hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);
 +	while(hcontact!=NULL)
 +	{
 +		DBWriteContactSettingByte(hcontact,S_MOD,"Missed",0);
 +		hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hcontact,0);
 +	}
 +
 +	ZeroMemory(&mcs,sizeof(mcs));
 +
 +	return 0;
 +}
 +
 +
 +int CheckIfOnline(void)
 +{
 +	HANDLE hcontact;
 +//	char *szProto;
 +//	WORD status;
 +
 +	hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);
 +	while(hcontact!=NULL)
 +	{
 +/*		szProto=(char *)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hcontact,0);
 +		status=(szProto==NULL)?ID_STATUS_OFFLINE:DBGetContactSettingWord(hcontact,szProto,"Status",ID_STATUS_OFFLINE);
 +		if(status!=ID_STATUS_OFFLINE)
 +*/
 +		if(CallService(MS_CLIST_GETCONTACTICON,(WPARAM)hcontact,0)!=ICON_OFFLINE)
 +			DBWriteContactSettingByte(hcontact,S_MOD,"Missed",2);
 +
 +		hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hcontact,0);
 +	}
 +
 +	return 0;
 +}
 +
 +
 +
 +INT_PTR CALLBACK MissedDlgProc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam)
 +{
 +	POINT pt;
 +	RECT rcinit,rcresized,rcb,rcd;
 +	HWND htemp;
 +		
 +	switch(msg){
 +
 +		case WM_INITDIALOG:
 +			TranslateDialogDefault(hdlg);
 +
 +			htemp=GetDlgItem(hdlg,IDC_CONTACTS);
 +			GetWindowRect(htemp,&rcinit);
 +			SetWindowPos(htemp,NULL,0,0,rcinit.right-rcinit.left,mcs.count*(rcinit.bottom-rcinit.top)/2,SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE);
 +			GetWindowRect(htemp,&rcresized);
 +
 +			htemp=GetDlgItem(hdlg,IDOK);
 +			GetWindowRect(htemp,&rcb);
 +			pt.x=rcb.left;
 +			pt.y=rcb.top;
 +
 +			ScreenToClient(hdlg,&pt);
 +			MoveWindow(htemp,pt.x,pt.y+(rcresized.bottom-rcinit.bottom),(rcb.right-rcb.left),(rcb.bottom-rcb.top),FALSE);
 +			GetWindowRect(hdlg,&rcd);
 +			SetWindowPos(hdlg,NULL,0,0,rcd.right-rcd.left,rcd.bottom-rcd.top+(rcresized.bottom-rcinit.bottom),SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE);
 +			
 +			SetDlgItemText(hdlg,IDC_CONTACTS,(LPCSTR)lparam);
 +			ShowWindow(hdlg,SW_SHOWNOACTIVATE);
 +			break;
 +
 +		case WM_CLOSE:
 +			EndDialog(hdlg,0);
 +			break;
 +
 +		case WM_COMMAND:
 +			if(LOWORD(wparam)==IDOK)
 +				SendMessage(hdlg,WM_CLOSE,0,0);
 +			break;
 +	}
 +
 +	return 0;
 +}
 +
 +
 +
 +
 +int ShowMissed(void)
 +{
 +	int loop=0;
 +	char sztemp[1024]="",szcount[7];
 +
 +	if (!mcs.count) return 0;
 +
 +	for (;loop<mcs.count;loop++)
 +	{
 +		strcat(sztemp,(const char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,mcs.wpcontact[loop],0));
 +		if(DBGetContactSettingByte(NULL,S_MOD,"MissedOnes_Count",0))
 +		{
 +			wsprintf(szcount," [%i]",mcs.times[loop]);
 +			strcat(sztemp,szcount);
 +		}
 +
 +		strcat(sztemp,"\n");
 +	}
 +
 +	CreateDialogParam(hInstance,MAKEINTRESOURCE(IDD_MISSED),NULL,MissedDlgProc,(LPARAM)&sztemp[0]);
 +
 +	return 0;
 +}
 +
 +/*
 +
 +int LogStatus(WPARAM wparam,LPARAM lparam)
 +{
 +	DBCONTACTWRITESETTING *cws;
 +	WPARAM wpvar;
 +	
 +	cws=(DBCONTACTWRITESETTING *)lparam;
 +
 +	if(strcmp(cws->szSetting,"Status") || (strcmp(cws->szModule,"ICQ") && strcmp(cws->szModule,"MSN")) || (HANDLE)wparam==NULL) return 0;
 +
 +	if(CallService(MS_IGNORE_ISIGNORED,wparam,IGNOREEVENT_USERONLINE))
 +		return 0;
 +
 +	if(cws->value.wVal==ID_STATUS_OFFLINE)
 +	{
 +		if(DBGetContactSettingByte((HANDLE)wparam,S_MOD,"Missed",0)==1)
 +		{
 +			mcs.times[mcs.count]++;
 +			mcs.wpcontact[mcs.count++]=wparam;
 +			DBWriteContactSettingByte((HANDLE)wparam,S_MOD,"Missed",0);
 +		}
 +
 +		else if(DBGetContactSettingByte((HANDLE)wparam,S_MOD,"Missed",0)==3)
 +			mcs.times[HIWORD(IsUserMissed(wparam))]++;
 +
 +		return 0;
 +	}
 +
 +	wpvar=IsUserMissed(wparam);
 +	if(LOWORD(wpvar))
 +		DBWriteContactSettingByte((HANDLE)wparam,S_MOD,"Missed",3);
 +
 +	else
 +		DBWriteContactSettingByte((HANDLE)wparam,S_MOD,"Missed",1);
 +
 +	return 0;
 +}
 +
 +*/
 +
 +int Test(WPARAM wparam,LPARAM lparam)
 +{
 +	if(lparam<ICON_OFFLINE || lparam>ICON_INVIS)
 +		return 0;
 +
 +	if(CallService(MS_IGNORE_ISIGNORED,wparam,IGNOREEVENT_USERONLINE))
 +		return 0;
 +
 +	if(DBGetContactSettingByte((HANDLE)wparam,S_MOD,"Missed",0)==2)
 +		return 0;
 +
 +	switch(lparam){
 +
 +		case ICON_OFFLINE:
 +			if(DBGetContactSettingByte((HANDLE)wparam,S_MOD,"Missed",0)==1)
 +			{
 +				WORD missed=IsUserMissed(wparam);
 +
 +				if (!LOWORD(missed))
 +				{
 +					mcs.times[mcs.count]=1;
 +					mcs.wpcontact[mcs.count++]=wparam;
 +				}
 +				else
 +					mcs.times[HIWORD(missed)]++;
 +
 +				DBWriteContactSettingByte((HANDLE)wparam,S_MOD,"Missed",0);
 +			}
 +			break;
 +
 +		case ICON_ONLINE:
 +		case ICON_AWAY:
 +		case ICON_NA:
 +		case ICON_OCC:
 +		case ICON_DND:
 +		case ICON_FREE:
 +		case ICON_INVIS:
 +			DBWriteContactSettingByte((HANDLE)wparam,S_MOD,"Missed",1);
 +			break;
 +	}
 +		
 +	return 0;
 +}
 +
 +
 +
 +int ModeChange_mo(WPARAM wparam,LPARAM lparam)
 +{
 +	ACKDATA *ack;
 +	int isetting=0;
 +
 +	ack=(ACKDATA *)lparam;
 +
 +	if(ack->type!=ACKTYPE_STATUS || ack->result!=ACKRESULT_SUCCESS || ack->hContact!=NULL) return 0;
 +
 +	isetting=CallProtoService(ack->szModule,PS_GETSTATUS,0,0);
 +
 +	switch(isetting){
 +
 +		case ID_STATUS_AWAY:
 +		case ID_STATUS_DND:
 +		case ID_STATUS_NA:
 +			if(ehmissed==NULL)
 +			{
 +				ZeroMemory(&mcs,sizeof(mcs));
 +				CheckIfOnline();
 +				//ehmissed=HookEvent(ME_DB_CONTACT_SETTINGCHANGED,LogStatus);
 +				ehmissed=HookEvent(ME_CLIST_CONTACTICONCHANGED,Test);
 +			}
 +			break;
 +
 +		default:
 +			if(ehmissed!=NULL)
 +			{
 +				UnhookEvent(ehmissed);
 +				ehmissed=NULL;
 +				ShowMissed();
 +				ResetMissed();
 +			}
 +			break;
 +	}
 +
 +	return 0;
 +}
 diff --git a/plugins/SeenPlugin/src/options.cpp b/plugins/SeenPlugin/src/options.cpp new file mode 100644 index 0000000000..daab1e8ee3 --- /dev/null +++ b/plugins/SeenPlugin/src/options.cpp @@ -0,0 +1,494 @@ +/*
 +"Last Seen mod" plugin for Miranda IM
 +Copyright ( C ) 2002-03  micron-x
 +Copyright ( C ) 2005-07  Y.B.
 +
 +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.
 +
 +File name      : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/options.c $
 +Revision       : $Rev: 1570 $
 +Last change on : $Date: 2007-12-30 01:30:07 +0300 (Вс, 30 дек 2007) $
 +Last change by : $Author: y_b $
 +*/
 +#include "seen.h"
 +
 +
 +
 +extern HINSTANCE hInstance;
 +extern HANDLE ehuserinfo,hmenuitem,ehmissed_proto;
 +void BuildInfo(char *,char *,char *);
 +int BuildContactMenu(WPARAM,LPARAM);
 +int UserinfoInit(WPARAM,LPARAM);
 +int InitFileOutput(void);
 +void ShutdownFileOutput(void);
 +void InitMenuitem(void);
 +int ModeChange_mo(WPARAM,LPARAM);
 +int CheckIfOnline(void);
 +int ResetMissed(void);
 +static BOOL (WINAPI *pfnEnableThemeDialogTexture)(HANDLE, DWORD) = 0;
 +
 +INT_PTR CALLBACK OptsPopUpsDlgProc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam)
 +{
 +	DBVARIANT dbv;
 +	int i;
 +	char szstamp[256];
 +	BOOL hasPopups;
 +	switch(msg)
 +	{
 +		case WM_INITDIALOG:{
 +			if (hasPopups = (ServiceExists(MS_POPUP_QUERY) != 0))
 +				hasPopups = CallService(MS_POPUP_QUERY,PUQS_GETSTATUS,0);
 +			TranslateDialogDefault(hdlg);
 +			ShowWindow(GetDlgItem(hdlg,IDC_MISSPOPUP),hasPopups?SW_HIDE:SW_SHOW);
 +			ShowWindow(GetDlgItem(hdlg,IDC_POPUPS),hasPopups?SW_SHOW:SW_HIDE);
 +			ShowWindow(GetDlgItem(hdlg,IDC_POPUPSTAMP),hasPopups?SW_SHOW:SW_HIDE);
 +			ShowWindow(GetDlgItem(hdlg,IDC_LABTEXT),hasPopups?SW_SHOW:SW_HIDE);
 +			ShowWindow(GetDlgItem(hdlg,IDC_LABTTITLE),hasPopups?SW_SHOW:SW_HIDE);
 +			ShowWindow(GetDlgItem(hdlg,IDC_POPUPSTAMPTEXT),hasPopups?SW_SHOW:SW_HIDE);
 +			CheckDlgButton(hdlg,IDC_POPUPS,DBGetContactSettingByte(NULL,S_MOD,"UsePopups",0)&hasPopups);
 +			EnableWindow(GetDlgItem(hdlg,IDC_POPUPS),hasPopups);
 +			hasPopups = IsDlgButtonChecked(hdlg,IDC_POPUPS);
 +			EnableWindow(GetDlgItem(hdlg,IDC_POPUPSTAMP),hasPopups);
 +			EnableWindow(GetDlgItem(hdlg,IDC_POPUPSTAMPTEXT),hasPopups);
 +			for (i=ID_STATUS_OFFLINE;i<=ID_STATUS_OUTTOLUNCH;i++) {
 +				DWORD sett;
 +				COLORREF back, text;
 +				sprintf(szstamp, "Col_%d",i-ID_STATUS_OFFLINE);
 +				sett = DBGetContactSettingDword(NULL,S_MOD,szstamp,StatusColors15bits[i-ID_STATUS_OFFLINE]);
 +				GetColorsFromDWord(&back, &text, sett);
 +				SendDlgItemMessage(hdlg,i,CPM_SETCOLOUR,0,back);
 +				SendDlgItemMessage(hdlg,i+20,CPM_SETCOLOUR,0,text);
 +				EnableWindow(GetDlgItem(hdlg,i),hasPopups);
 +				EnableWindow(GetDlgItem(hdlg,i+20),hasPopups);
 +			}
 +
 +			SetDlgItemText(hdlg,IDC_POPUPSTAMP,!DBGetContactSetting(NULL,S_MOD,"PopupStamp",&dbv)?dbv.pszVal:DEFAULT_POPUPSTAMP);
 +			DBFreeVariant(&dbv);
 +			SetDlgItemText(hdlg,IDC_POPUPSTAMPTEXT,!DBGetContactSetting(NULL,S_MOD,"PopupStampText",&dbv)?dbv.pszVal:DEFAULT_POPUPSTAMPTEXT);
 +			DBFreeVariant(&dbv);
 +
 +		}
 +		break; //case WM_INITDIALOG
 +		case WM_COMMAND:
 +			if ((HIWORD(wparam)==BN_CLICKED || HIWORD(wparam)==EN_CHANGE) && GetFocus()==(HWND)lparam)
 +				SendMessage(GetParent(hdlg),PSM_CHANGED,0,0);
 +			else if (HIWORD(wparam)==CPN_COLOURCHANGED){
 +				WORD idText, idBack;
 +				POPUPDATAEX ppd = {0};
 +				DBVARIANT dbv = {0};
 +				DWORD temp;
 +				if (LOWORD(wparam)>ID_STATUS_OUTTOLUNCH){ // we have clicked a text color
 +					idText = wparam; idBack = wparam-20;
 +				} else {idText = wparam+20; idBack = wparam;}
 +				ppd.colorBack = SendDlgItemMessage(hdlg,idBack,CPM_GETCOLOUR,0,0);
 +				ppd.colorText = SendDlgItemMessage(hdlg,idText,CPM_GETCOLOUR,0,0);
 +				temp = GetDWordFromColors(ppd.colorBack,ppd.colorText);
 +				GetColorsFromDWord(&ppd.colorBack,&ppd.colorText,temp);
 +				SendDlgItemMessage(hdlg,idBack,CPM_SETCOLOUR,0,ppd.colorBack);
 +				SendDlgItemMessage(hdlg,idText,CPM_SETCOLOUR,0,ppd.colorText);
 +				ppd.lchIcon = LoadSkinnedProtoIcon(NULL, idBack);
 +				GetDlgItemText(hdlg,IDC_POPUPSTAMP,szstamp,255);
 +				strncpy(ppd.lpzContactName,ParseString(szstamp,NULL,0),MAX_CONTACTNAME);
 +				GetDlgItemText(hdlg,IDC_POPUPSTAMPTEXT,szstamp,255);
 +				strncpy(ppd.lpzText,ParseString(szstamp,NULL,0),MAX_SECONDLINE);
 +				CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0);
 +
 +				SendMessage(GetParent(hdlg),PSM_CHANGED,0,0);
 +			} 
 +			if(HIWORD(wparam)==BN_CLICKED)
 +			{
 +				switch(LOWORD(wparam)) {
 +					case IDC_POPUPS:
 +						hasPopups = IsDlgButtonChecked(hdlg,IDC_POPUPS);
 +						EnableWindow(GetDlgItem(hdlg,IDC_POPUPSTAMP),hasPopups);
 +						EnableWindow(GetDlgItem(hdlg,IDC_POPUPSTAMPTEXT),hasPopups);
 +						for (i=ID_STATUS_OFFLINE;i<=ID_STATUS_OUTTOLUNCH;i++) {
 +							EnableWindow(GetDlgItem(hdlg,i),hasPopups);
 +							EnableWindow(GetDlgItem(hdlg,i+20),hasPopups);
 +						}
 +						break;
 +					case IDC_DEFAULTCOL:
 +						for (i=ID_STATUS_OFFLINE;i<=ID_STATUS_OUTTOLUNCH;i++) {
 +							DWORD sett;
 +							COLORREF back, text;
 +							sprintf(szstamp, "Col_%d",i-ID_STATUS_OFFLINE);
 +							sett = StatusColors15bits[i-ID_STATUS_OFFLINE];
 +							GetColorsFromDWord(&back, &text, sett);
 +							SendDlgItemMessage(hdlg,i,CPM_SETCOLOUR,0,back);
 +							SendDlgItemMessage(hdlg,i+20,CPM_SETCOLOUR,0,text);
 +						}
 +						break;
 +				}
 +			}
 +			break; //case WM_COMMAND
 +
 +		case WM_NOTIFY:
 +			switch(((LPNMHDR)lparam)->idFrom) 
 +			{
 +				case 0: 
 +					switch (((LPNMHDR)lparam)->code)
 +					{
 +						BYTE checkValue;
 +
 +						case PSN_APPLY:
 +							GetDlgItemText(hdlg,IDC_POPUPSTAMP,szstamp,256);
 +							DBWriteContactSettingString(NULL,S_MOD,"PopupStamp",szstamp);
 +							GetDlgItemText(hdlg,IDC_POPUPSTAMPTEXT,szstamp,256);
 +							DBWriteContactSettingString(NULL,S_MOD,"PopupStampText",szstamp);
 +
 +							checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_POPUPS);
 +							if (DBGetContactSettingByte(NULL,S_MOD,"UsePopups",0) != checkValue) {
 +								DBWriteContactSettingByte(NULL,S_MOD,"UsePopups",checkValue);
 +							}
 +							for (i=ID_STATUS_OFFLINE;i<=ID_STATUS_OUTTOLUNCH;i++) {
 +								DWORD sett;
 +								COLORREF back=0, text=0;
 +								sprintf(szstamp, "Col_%d",i-ID_STATUS_OFFLINE);
 +								back = SendDlgItemMessage(hdlg,i,CPM_GETCOLOUR,0,0);
 +								text = SendDlgItemMessage(hdlg,i+20,CPM_GETCOLOUR,0,0);
 +								sett=GetDWordFromColors(back,text);
 +								if (sett!=StatusColors15bits[i-ID_STATUS_OFFLINE])
 +									DBWriteContactSettingDword(NULL,S_MOD,szstamp,sett);
 +								else DBDeleteContactSetting(NULL,S_MOD,szstamp);
 +							}
 +
 +							break; //case PSN_APPLY
 +					}
 +					break; //case 0
 +			}
 +			break;//case WM_NOTIFY
 +       
 +	}
 +
 +	return 0;
 +}
 +
 +INT_PTR CALLBACK OptsSettingsDlgProc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam)
 +{
 +	DBVARIANT dbv;
 +	char szstamp[256];
 +	BYTE bchecked=0;
 +	WPARAM wpsend=0;
 +
 +	switch(msg)
 +	{
 +		case WM_INITDIALOG:{
 +			TranslateDialogDefault(hdlg);
 +
 +			CheckDlgButton(hdlg,IDC_MENUITEM,DBGetContactSettingByte(NULL,S_MOD,"MenuItem",1));
 +			CheckDlgButton(hdlg,IDC_USERINFO,DBGetContactSettingByte(NULL,S_MOD,"UserinfoTab",1));
 +			CheckDlgButton(hdlg,IDC_FILE,DBGetContactSettingByte(NULL,S_MOD,"FileOutput",0));
 +			CheckDlgButton(hdlg,IDC_HISTORY,DBGetContactSettingByte(NULL,S_MOD,"KeepHistory",0));
 +			CheckDlgButton(hdlg,IDC_IGNOREOFFLINE,DBGetContactSettingByte(NULL,S_MOD,"IgnoreOffline",1));
 +			CheckDlgButton(hdlg,IDC_MISSEDONES,DBGetContactSettingByte(NULL,S_MOD,"MissedOnes",0));
 +			CheckDlgButton(hdlg,IDC_SHOWICON,DBGetContactSettingByte(NULL,S_MOD,"ShowIcon",1));
 +			CheckDlgButton(hdlg,IDC_COUNT,DBGetContactSettingByte(NULL,S_MOD,"MissedOnes_Count",0));
 +			CheckDlgButton(hdlg,IDC_IDLESUPPORT,DBGetContactSettingByte(NULL,S_MOD,"IdleSupport",1));
 +
 +			EnableWindow(GetDlgItem(hdlg,IDC_MENUSTAMP),IsDlgButtonChecked(hdlg,IDC_MENUITEM));
 +			EnableWindow(GetDlgItem(hdlg,IDC_SHOWICON),IsDlgButtonChecked(hdlg,IDC_MENUITEM));
 +			EnableWindow(GetDlgItem(hdlg,IDC_USERSTAMP),IsDlgButtonChecked(hdlg,IDC_USERINFO));
 +			EnableWindow(GetDlgItem(hdlg,IDC_FILESTAMP),IsDlgButtonChecked(hdlg,IDC_FILE));
 +			EnableWindow(GetDlgItem(hdlg,IDC_FILENAME),IsDlgButtonChecked(hdlg,IDC_FILE));
 +			EnableWindow(GetDlgItem(hdlg,IDC_HISTORYSIZE),IsDlgButtonChecked(hdlg,IDC_HISTORY));
 +			EnableWindow(GetDlgItem(hdlg,IDC_HISTORYSTAMP),IsDlgButtonChecked(hdlg,IDC_HISTORY));
 +			EnableWindow(GetDlgItem(hdlg,IDC_COUNT),IsDlgButtonChecked(hdlg,IDC_MISSEDONES));
 +
 +			SetDlgItemText(hdlg,IDC_MENUSTAMP,!DBGetContactSetting(NULL,S_MOD,"MenuStamp",&dbv)?dbv.pszVal:DEFAULT_MENUSTAMP);
 +			DBFreeVariant(&dbv);
 +			SetDlgItemText(hdlg,IDC_USERSTAMP,!DBGetContactSetting(NULL,S_MOD,"UserStamp",&dbv)?dbv.pszVal:DEFAULT_USERSTAMP);
 +			DBFreeVariant(&dbv);
 +			SetDlgItemText(hdlg,IDC_FILESTAMP,!DBGetContactSetting(NULL,S_MOD,"FileStamp",&dbv)?dbv.pszVal:DEFAULT_FILESTAMP);
 +			DBFreeVariant(&dbv);
 +			SetDlgItemText(hdlg,IDC_FILENAME,!DBGetContactSetting(NULL,S_MOD,"FileName",&dbv)?dbv.pszVal:DEFAULT_FILENAME);
 +			DBFreeVariant(&dbv);
 +			SetDlgItemInt(hdlg,IDC_HISTORYSIZE,DBGetContactSettingWord(NULL,S_MOD,"HistoryMax",10-1)-1,FALSE);
 +			SetDlgItemText(hdlg,IDC_HISTORYSTAMP,!DBGetContactSetting(NULL,S_MOD,"HistoryStamp",&dbv)?dbv.pszVal:DEFAULT_HISTORYSTAMP);
 +			DBFreeVariant(&dbv);
 +
 +			// load protocol list
 +			SetWindowLongPtr(GetDlgItem(hdlg,IDC_PROTOCOLLIST),GWL_STYLE,GetWindowLongPtr(GetDlgItem(hdlg,IDC_PROTOCOLLIST),GWL_STYLE)|TVS_CHECKBOXES);
 +			{	
 +				TVINSERTSTRUCT tvis;
 +				int numberOfProtocols,i;
 +				PROTOCOLDESCRIPTOR** protos;
 +				char *protoName;
 +				char *protoLabel;
 +
 +				tvis.hParent=NULL;
 +				tvis.hInsertAfter=TVI_LAST;
 +				tvis.item.mask=TVIF_TEXT | TVIF_HANDLE | TVIF_STATE | TVIF_PARAM;
 +				tvis.item.stateMask = TVIS_STATEIMAGEMASK;
 +
 +				CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM)&numberOfProtocols,(LPARAM)&protos);
 +				for (i=0; i<numberOfProtocols; i++) {
 +					if(protos[i]->type!=PROTOTYPE_PROTOCOL || CallProtoService(protos[i]->szName,PS_GETCAPS,PFLAGNUM_2,0)==0) continue;
 +					protoName = (char *)malloc(strlen(protos[i]->szName)+1);
 +					strcpy(protoName,protos[i]->szName);
 +//debug(protoName);
 +					protoLabel = (char *)malloc(MAXMODULELABELLENGTH+1);
 +					CallProtoService(protoName,PS_GETNAME,MAXMODULELABELLENGTH,(LPARAM)protoLabel);
 +//debug(protoLabel);
 +					tvis.item.pszText = protoLabel;
 +					tvis.item.lParam = (LPARAM)protoName;
 +					tvis.item.state = INDEXTOSTATEIMAGEMASK(IsWatchedProtocol(protoName)+1);
 +					TreeView_InsertItem(GetDlgItem(hdlg,IDC_PROTOCOLLIST),&tvis);
 +					free(protoLabel);
 +
 +				}
 +			}
 +		   }
 +			break; //case WM_INITDIALOG
 +
 +		case WM_COMMAND:
 +			if ((HIWORD(wparam)==BN_CLICKED || HIWORD(wparam)==EN_CHANGE) && GetFocus()==(HWND)lparam)
 +				if (LOWORD(wparam)!=IDC_VARIABLES)SendMessage(GetParent(hdlg),PSM_CHANGED,0,0);
 +
 +			if(HIWORD(wparam)==BN_CLICKED)
 +			{
 +				switch(LOWORD(wparam)) {
 +					case IDC_MENUITEM:
 +						EnableWindow(GetDlgItem(hdlg,IDC_MENUSTAMP),IsDlgButtonChecked(hdlg,IDC_MENUITEM));
 +						EnableWindow(GetDlgItem(hdlg,IDC_SHOWICON),IsDlgButtonChecked(hdlg,IDC_MENUITEM));
 +						break;
 +					case IDC_USERINFO:
 +						EnableWindow(GetDlgItem(hdlg,IDC_USERSTAMP),IsDlgButtonChecked(hdlg,IDC_USERINFO));
 +						break;
 +					case IDC_FILE:
 +						EnableWindow(GetDlgItem(hdlg,IDC_FILESTAMP),IsDlgButtonChecked(hdlg,IDC_FILE));
 +						EnableWindow(GetDlgItem(hdlg,IDC_FILENAME),IsDlgButtonChecked(hdlg,IDC_FILE));
 +						break;
 +					case IDC_HISTORY:
 +						EnableWindow(GetDlgItem(hdlg,IDC_HISTORYSTAMP),IsDlgButtonChecked(hdlg,IDC_HISTORY));
 +						EnableWindow(GetDlgItem(hdlg,IDC_HISTORYSIZE),IsDlgButtonChecked(hdlg,IDC_HISTORY));
 +						break;
 +					case IDC_MISSEDONES:
 +						EnableWindow(GetDlgItem(hdlg,IDC_COUNT),IsDlgButtonChecked(hdlg,IDC_MISSEDONES));
 +						break;
 +				}
 +			}
 +			
 +			if (LOWORD(wparam)==IDC_VARIABLES)
 +			{
 +				char szout[2048]="";
 +				wsprintf(szout,VARIABLE_LIST);
 +				MessageBox(NULL,szout,Translate("Last Seen Variables"),MB_OK|MB_TOPMOST);
 +			}
 +
 +			break; //case WM_COMMAND
 +
 +		case WM_NOTIFY:
 +			switch(((LPNMHDR)lparam)->idFrom) 
 +			{
 +				case 0: 
 +					switch (((LPNMHDR)lparam)->code)
 +					{
 +						BYTE checkValue;
 +
 +						case PSN_APPLY:
 +
 +							GetDlgItemText(hdlg,IDC_MENUSTAMP,szstamp,256);
 +							DBWriteContactSettingString(NULL,S_MOD,"MenuStamp",szstamp);
 +
 +							GetDlgItemText(hdlg,IDC_USERSTAMP,szstamp,256);
 +							DBWriteContactSettingString(NULL,S_MOD,"UserStamp",szstamp);
 +
 +							GetDlgItemText(hdlg,IDC_FILESTAMP,szstamp,256);
 +							DBWriteContactSettingString(NULL,S_MOD,"FileStamp",szstamp);
 +
 +							GetDlgItemText(hdlg,IDC_FILENAME,szstamp,256);
 +							DBWriteContactSettingString(NULL,S_MOD,"FileName",szstamp);
 +
 +							GetDlgItemText(hdlg,IDC_HISTORYSTAMP,szstamp,256);
 +							DBWriteContactSettingString(NULL,S_MOD,"HistoryStamp",szstamp);
 +							
 +							DBWriteContactSettingWord(NULL,S_MOD,"HistoryMax",(WORD)(GetDlgItemInt(hdlg,IDC_HISTORYSIZE,NULL,FALSE)+1));
 +
 +							checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_MENUITEM);
 +							if (DBGetContactSettingByte(NULL,S_MOD,"MenuItem",1) != checkValue) {
 +								DBWriteContactSettingByte(NULL,S_MOD,"MenuItem",checkValue);
 +								if(hmenuitem==NULL && checkValue) {
 +									InitMenuitem();
 +								}
 +							}
 +
 +							checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_USERINFO);
 +							if (DBGetContactSettingByte(NULL,S_MOD,"UserinfoTab",1) != checkValue) {
 +								DBWriteContactSettingByte(NULL,S_MOD,"UserinfoTab",checkValue);
 +								if(checkValue) {
 +									ehuserinfo=HookEvent(ME_USERINFO_INITIALISE,UserinfoInit);
 +								} else {
 +									UnhookEvent(ehuserinfo);
 +								}
 +							}
 +
 +							checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_FILE);
 +							if (DBGetContactSettingByte(NULL,S_MOD,"FileOutput",0) != checkValue) {
 +								DBWriteContactSettingByte(NULL,S_MOD,"FileOutput",checkValue);
 +								if(checkValue) {
 +									InitFileOutput();
 +								}
 +							}
 +
 +							checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_HISTORY);
 +							if (DBGetContactSettingByte(NULL,S_MOD,"KeepHistory",0) != checkValue) {
 +								DBWriteContactSettingByte(NULL,S_MOD,"KeepHistory",checkValue);
 +							}
 +
 +							checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_IGNOREOFFLINE);
 +							if (DBGetContactSettingByte(NULL,S_MOD,"IgnoreOffline",1) != checkValue) {
 +								DBWriteContactSettingByte(NULL,S_MOD,"IgnoreOffline",checkValue);
 +							}
 +
 +							checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_MISSEDONES);
 +							if (DBGetContactSettingByte(NULL,S_MOD,"MissedOnes",0) != checkValue) {
 +								DBWriteContactSettingByte(NULL,S_MOD,"MissedOnes",checkValue);
 +								if(checkValue) {
 +									ehmissed_proto=HookEvent(ME_PROTO_ACK,ModeChange_mo);
 +								} else {
 +									UnhookEvent(ehmissed_proto);
 +								}
 +							}
 +
 +							checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_SHOWICON);
 +							if (DBGetContactSettingByte(NULL,S_MOD,"ShowIcon",1) != checkValue) {
 +								DBWriteContactSettingByte(NULL,S_MOD,"ShowIcon",checkValue);
 +							}
 +
 +							checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_COUNT);
 +							if (DBGetContactSettingByte(NULL,S_MOD,"MissedOnes_Count",0) != checkValue) {
 +								DBWriteContactSettingByte(NULL,S_MOD,"MissedOnes_Count",checkValue);
 +							}
 +
 +							includeIdle = (BYTE)IsDlgButtonChecked(hdlg,IDC_IDLESUPPORT);
 +							if (DBGetContactSettingByte(NULL,S_MOD,"IdleSupport",1) != includeIdle) {
 +								DBWriteContactSettingByte(NULL,S_MOD,"IdleSupport",(BYTE)includeIdle);
 +							}
 +
 +							// save protocol list
 +							{
 +								HWND hwndTreeView = GetDlgItem(hdlg,IDC_PROTOCOLLIST);
 +								HTREEITEM hItem;
 +								TVITEM tvItem;
 +								char *watchedProtocols;
 +								char *protocol;
 +								int size=1;
 +
 +								watchedProtocols = (char *)malloc(sizeof(char));
 +								*watchedProtocols = '\0';
 +								hItem = TreeView_GetRoot(hwndTreeView);
 +								tvItem.mask = TVIF_HANDLE | TVIF_STATE | TVIF_PARAM;
 +								tvItem.stateMask = TVIS_STATEIMAGEMASK;
 +
 +								while (hItem != NULL) {
 +									tvItem.hItem = hItem;
 +									TreeView_GetItem(hwndTreeView, &tvItem);
 +									protocol = (char*)tvItem.lParam;
 +									if ((BOOL)(tvItem.state >> 12) -1) {
 +										size = (size + (int)_tcslen(protocol)+2) * sizeof(char);
 +										watchedProtocols = (char *)realloc(watchedProtocols, size);
 +										strcat(watchedProtocols, protocol); 
 +										strcat(watchedProtocols, " "); 
 +									}
 +									hItem = TreeView_GetNextSibling(hwndTreeView, hItem);
 +								}
 +								DBWriteContactSettingString(NULL,S_MOD,"WatchedProtocols",watchedProtocols);
 +								free(watchedProtocols);
 +							}
 +
 +							break; //case PSN_APPLY
 +					}
 +					break; //case 0
 +
 +				case IDC_PROTOCOLLIST:
 +					switch (((LPNMHDR)lparam)->code) 
 +					{
 +						case NM_CLICK:
 +							{
 +								HWND hTree=((LPNMHDR)lparam)->hwndFrom;
 +								TVHITTESTINFO hti;
 +								HTREEITEM hItem;
 +
 +								hti.pt.x=(short)LOWORD(GetMessagePos());
 +								hti.pt.y=(short)HIWORD(GetMessagePos());
 +								ScreenToClient(hTree,&hti.pt);
 +								if(hItem=TreeView_HitTest(hTree,&hti))
 +								{
 +									if (hti.flags & TVHT_ONITEM) 
 +										TreeView_SelectItem(hTree,hItem);
 +									if (hti.flags & TVHT_ONITEMSTATEICON) 
 +										SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0);
 +									
 +								}
 +							}
 +							break; 
 +					}
 +					break; //case IDC_PROTOCOLLIST
 +			}
 +			break;//case WM_NOTIFY
 +        
 +		case WM_DESTROY:
 +			// free protocol list 
 +			{
 +				HWND hwndTreeView = GetDlgItem(hdlg,IDC_PROTOCOLLIST);
 +				HTREEITEM hItem;
 +				TVITEM tvItem;
 +
 +				hItem = TreeView_GetRoot(hwndTreeView);
 +				tvItem.mask = TVIF_HANDLE | TVIF_PARAM;
 +
 +				while (hItem != NULL) {
 +					tvItem.hItem = hItem;
 +					TreeView_GetItem(hwndTreeView, &tvItem);
 +					free((void *)tvItem.lParam);
 +					hItem = TreeView_GetNextSibling(hwndTreeView, hItem);
 +				}
 +			}
 +			break;
 +
 +	}
 +
 +	return 0;
 +}
 +
 +int OptionsInit(WPARAM wparam,LPARAM lparam)
 +{
 +	OPTIONSDIALOGPAGE odp = { 0 };
 +
 +	if(IsWinVerXPPlus()) {
 +		HMODULE hUxTheme = GetModuleHandle(_T("uxtheme.dll"));
 +		if (hUxTheme)   
 +			pfnEnableThemeDialogTexture = (BOOL (WINAPI *)(HANDLE, DWORD))GetProcAddress(hUxTheme, "EnableThemeDialogTexture");
 +	}
 +
 +	odp.cbSize = sizeof(odp);
 +	odp.position = 100000000;
 +	odp.hInstance = hInstance;
 +	odp.flags = ODPF_BOLDGROUPS;
 +	odp.pszTemplate = MAKEINTRESOURCE(IDD_SETTINGS);
 +	odp.pszGroup = LPGEN("Services");
 +	odp.pszTitle = LPGEN("Last seen");
 +	odp.pfnDlgProc = OptsSettingsDlgProc;
 +	Options_AddPage(wparam,&odp);
 +
 +	if (ServiceExists(MS_POPUP_ADDPOPUP)) {
 +		odp.pszTemplate = MAKEINTRESOURCE(IDD_POPUPS);
 +		odp.pszGroup = LPGEN("PopUps");
 +		odp.pszTitle = LPGEN("Last seen");
 +		odp.pfnDlgProc = OptsPopUpsDlgProc;
 +		Options_AddPage(wparam,&odp);
 +	}
 +	return 0;
 +}
 diff --git a/plugins/SeenPlugin/src/resource.h b/plugins/SeenPlugin/src/resource.h new file mode 100644 index 0000000000..110639bb3b --- /dev/null +++ b/plugins/SeenPlugin/src/resource.h @@ -0,0 +1,93 @@ +//{{NO_DEPENDENCIES}}
 +// Microsoft Developer Studio generated include file.
 +// Used by resource.rc
 +//
 +
 +#ifndef TVS_NOTOOLTIPS
 +#define TVS_NOTOOLTIPS 0x0080
 +#endif
 +
 +#define ID_STATUS_OFFLINE               40071
 +#define ID_STATUS_ONLINE                40072
 +#define ID_STATUS_AWAY                  40073
 +#define ID_STATUS_DND                   40074
 +#define ID_STATUS_NA                    40075
 +#define ID_STATUS_OCCUPIED              40076
 +#define ID_STATUS_FREECHAT              40077
 +#define ID_STATUS_INVISIBLE             40078
 +#define ID_STATUS_ONTHEPHONE            40079
 +#define ID_STATUS_OUTTOLUNCH            40080
 +#define ID_STATUS_IDLE                  40081 /* do not use as a status */
 +
 +
 +#define IDD_SETTINGS                    101
 +#define IDD_USERINFO                    102
 +#define IDD_MISSED                      103
 +#define IDD_USERDETAILS                 104
 +#define IDD_HISTORY                     105
 +#define IDD_POPUPS                      106
 +#define IDC_SEENMENUITEM                1000
 +#define IDC_MENUITEM                    1001
 +#define IDC_UINFOTAB                    1002
 +#define IDC_USERINFO                    1003
 +#define IDC_USERTIME                    1004
 +#define IDC_HISTORY                     1005
 +#define IDC_FILE                        1006
 +#define IDC_FILEGROUP                   1007
 +#define IDC_POPUPS                      1008
 +#define IDC_TIME                        1009
 +#define IDC_OWNSTATUS                   1010
 +#define IDC_TIMESTAMPGROUP              1011
 +#define IDC_EDIT1                       1012
 +#define IDC_TIMESTAMP                   1013
 +#define IDC_FILESTAMP                   1014
 +#define IDC_CONTACTS                    1015
 +#define IDC_INFOTEXT                    1016
 +#define IDC_TIMESTAMPHELP               1017
 +#define IDC_USERSTAMP                   1018
 +#define IDC_DELCHAR                     1019
 +#define IDC_HISTORYSTAMP                1020
 +#define IDC_DELCHARHELP                 1021
 +#define IDC_POPUPSTAMP                  1022
 +#define IDC_MENUGROUP                   1023
 +#define IDC_POPUPSTAMPTEXT              1023
 +#define IDC_MENUTIME                    1024
 +#define IDC_MENUSTATUS                  1025
 +#define IDC_MENUSTAMP                   1026
 +#define IDC_LABTEXT                     1027
 +#define IDC_MISSPOPUP                   1028
 +#define IDC_DEFAULTCOL                  1029
 +#define IDC_FILENAME                    1030
 +#define IDC_IGNOREOFFLINE               1031
 +#define IDC_MISSEDONES                  1032
 +#define IDC_SHOWICON                    1033
 +#define IDC_COUNT                       1034
 +#define IDC_FILENAME2                   1035
 +#define IDC_HISTORYSIZE                 1036
 +#define IDC_LASTSEENLIST                1037
 +#define IDC_HISTORYLIST                 1038
 +#define IDC_STATUSCHANGE                1039
 +#define IDC_VARIABLES                   1040
 +#define IDC_PROTOCOLLIST                1041
 +#define IDC_USERMENU                    1042
 +#define IDC_TEST                        1043
 +#define IDC_DETAILS                     1044
 +#define IDC_SENDMSG                     1045
 +#define IDC_LABTTITLE                   1046
 +#define IDC_OPTIONSTAB                  1047
 +#define IDC_IDLESUPPORT			1050
 +#define IDC_MAINGROUP                   -1
 +#define IDC_INFO                        -1
 +#define IDC_TEXT                        -1
 +#define IDC_STATIC                      -1
 +
 +// Next default values for new objects
 +//
 +#ifdef APSTUDIO_INVOKED
 +#ifndef APSTUDIO_READONLY_SYMBOLS
 +#define _APS_NEXT_RESOURCE_VALUE        107
 +#define _APS_NEXT_COMMAND_VALUE         40001
 +#define _APS_NEXT_CONTROL_VALUE         1051
 +#define _APS_NEXT_SYMED_VALUE           101
 +#endif
 +#endif
 diff --git a/plugins/SeenPlugin/src/seen.h b/plugins/SeenPlugin/src/seen.h new file mode 100644 index 0000000000..ba2b13a6c2 --- /dev/null +++ b/plugins/SeenPlugin/src/seen.h @@ -0,0 +1,134 @@ +/*
 +"Last Seen mod" plugin for Miranda IM
 +Copyright ( C ) 2002-03  micron-x
 +Copyright ( C ) 2005-07  Y.B.
 +
 +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.
 +
 +File name      : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/seen.h $
 +Revision       : $Rev: 1570 $
 +Last change on : $Date: 2007-12-30 01:30:07 +0300 (Вс, 30 дек 2007) $
 +Last change by : $Author: y_b $
 +*/
 +#ifndef _WIN32_IE
 +#define _WIN32_IE 0x0300
 +#endif
 +#define ETDT_ENABLE         0x00000002
 +#define ETDT_USETABTEXTURE  0x00000004
 +#define ETDT_ENABLETAB      (ETDT_ENABLE  | ETDT_USETABTEXTURE)
 +#define MIRANDA_VER    0x0A00
 +
 +#include <windows.h>
 +#include <win2k.h>
 +#include <commctrl.h>
 +#include <stdio.h>
 +#include <string.h>
 +
 +#include "resource.h"
 +#include <newpluginapi.h>
 +#include <m_database.h>
 +#include <m_langpack.h>
 +
 +#include <m_system.h>
 +#include <m_skin.h>
 +#include <m_utils.h>
 +#include <m_options.h>
 +#include <m_userinfo.h>
 +#include <m_clist.h>
 +#include <m_userinfo.h>
 +#include <m_contacts.h>
 +#include <m_message.h>
 +#include <m_protosvc.h>
 +#include <m_protocols.h>
 +#include <m_popup.h>
 +#include <m_system.h>
 +
 +#include "m_tipper.h"
 +WCHAR *any_to_IdleNotidleUnknown(HANDLE hContact, const char *module_name, const char *setting_name, WCHAR *buff, int bufflen);
 +WCHAR *any_to_Idle(HANDLE hContact, const char *module_name, const char *setting_name, WCHAR *buff, int bufflen);
 +
 +#ifdef __GNUC__
 +#define NUM100NANOSEC  116444736000000000ULL
 +#else
 +#define NUM100NANOSEC  116444736000000000
 +#endif
 +
 +#define S_MOD "SeenModule"
 +
 +//#define UM_CHECKHOOKS (WM_USER+1)
 +
 +#define debug(a) MessageBox(NULL,a,"Debug",MB_OK)
 +
 +#define IDI_USERDETAILS                 160
 +#define IDI_DOWNARROW                   264
 +#define IDI_RECVMSG                     136
 +
 +#define ICON_OFFLINE		13
 +#define ICON_ONLINE			14
 +#define ICON_AWAY			15
 +#define ICON_NA				16
 +#define ICON_OCC			17
 +#define ICON_DND			18
 +#define ICON_FREE			19
 +#define	ICON_INVIS			20
 +
 +#define DEFAULT_MENUSTAMP          "%d.%m.%Y - %H:%M [%s]"
 +#define DEFAULT_POPUPSTAMP         Translate("%n is %s (%u)")
 +#define DEFAULT_POPUPSTAMPTEXT     Translate("%i(%r)%bWas %o")
 +#define DEFAULT_USERSTAMP          Translate("Name:%t%N%bStatus:%t%s%bDay:%t%d.%m.%Y%bTime:%t%H:%M:%S%bPrevious Status:%t%o%b%b%P ID:%t%u%bExternal IP:%t%i%bInternal IP:%t%r%bClientID: %t%C%b%bStatus Message:%t%T")
 +#define DEFAULT_FILESTAMP          "%d.%m.%Y %H:%M:%S%t%n%t%s%t%u%t%r | %i%t%N"
 +#define DEFAULT_FILENAME           "logs\\%P.txt"
 +#define DEFAULT_HISTORYSTAMP       "%d.%m.%Y - %H:%M [%s]"
 +#define DEFAULT_WATCHEDPROTOCOLS   ""
 +
 +#define VARIABLE_LIST "%s \n%%Y: \t %s \n%%y: \t %s \n%%m: \t %s \n%%E: \t %s \n%%e: \t %s \n%%d: \t %s \n%%W: \t %s \n%%w: \t %s \n\n%s \n%%H: \t %s \n%%h: \t %s \n%%p: \t %s \n%%M: \t %s \n%%S: \t %s \n\n%s \n%%n: \t %s \n%%N: \t %s \n%%u: \t %s \n%%G: \t %s \n%%s: \t %s \n%%T: \t %s \n%%o: \t %s \n%%i: \t %s \n%%r: \t %s \n%%C: \t %s \n%%P: \t %s \n\n%s \n%%t: \t %s \n%%b: \t %s\n\n%s\t%s \"#\" %s\n\t%s %s", Translate("-- Date --"), Translate("year (4 digits)"), Translate("year (2 digits)"), Translate("month"), Translate("name of month"), Translate("short name of month"), Translate("day"), Translate("weekday (full)"), Translate("weekday (abbreviated)"), Translate("-- Time --"), Translate("hours (24)"), Translate("hours (12)"), Translate("AM/PM"), Translate("minutes"), Translate("seconds"), Translate("-- User --"), Translate("username"), Translate("nick"), Translate("UIN/handle"), Translate("Group"), Translate("Status"), Translate("Status message"), Translate("Old status"), Translate("external IP"), Translate("internal IP"),Translate("Client info"),Translate("Protocol"), Translate("-- Format --"), Translate("tabulator"), Translate("line break"), Translate("Note:"),Translate("Use"),Translate("for empty string"),Translate("instead of"),Translate("<unknown>")
 +
 +#ifndef LPCOLORREF
 +typedef DWORD   *LPCOLORREF;
 +#endif
 +
 +typedef struct{
 +	int count;
 +	WPARAM wpcontact[1024];
 +	BYTE times[1024];
 +} MISSEDCONTACTS;
 +
 +int IsWatchedProtocol(const char* szProto);
 +char *ParseString(char *,HANDLE,BYTE);
 +extern DWORD StatusColors15bits[];
 +void GetColorsFromDWord(LPCOLORREF First, LPCOLORREF Second, DWORD colDword);
 +DWORD GetDWordFromColors(COLORREF First, COLORREF Second);
 +int OptionsInit(WPARAM,LPARAM);
 +int UserinfoInit(WPARAM,LPARAM);
 +int InitFileOutput(void);
 +void InitMenuitem(void);
 +int UpdateValues(WPARAM, LPARAM);
 +int ModeChange(WPARAM,LPARAM);
 +void SetOffline(void);
 +int ModeChange_mo(WPARAM,LPARAM);
 +int CheckIfOnline(void);
 +void UninitMenuitem();
 +
 +extern BOOL includeIdle;
 +typedef struct logthread_info {
 +  char sProtoName[MAXMODULELABELLENGTH];
 +  HANDLE hContact;
 +  WORD courStatus;
 +  int queueIndex;
 +} logthread_info;
 +
 +extern logthread_info **contactQueue;
 +extern int contactQueueSize;
 +
 diff --git a/plugins/SeenPlugin/src/userinfo.cpp b/plugins/SeenPlugin/src/userinfo.cpp new file mode 100644 index 0000000000..442860bb86 --- /dev/null +++ b/plugins/SeenPlugin/src/userinfo.cpp @@ -0,0 +1,95 @@ +/*
 +"Last Seen mod" plugin for Miranda IM
 +Copyright ( C ) 2002-03  micron-x
 +Copyright ( C ) 2005-07  Y.B.
 +
 +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.
 +
 +File name      : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/userinfo.c $
 +Revision       : $Rev: 1570 $
 +Last change on : $Date: 2007-12-30 01:30:07 +0300 (Вс, 30 дек 2007) $
 +Last change by : $Author: y_b $
 +*/
 +#include "seen.h"
 +
 +
 +
 +WNDPROC MainProc;
 +
 +
 +
 +extern HINSTANCE hInstance;
 +extern DWORD dwmirver;
 +
 +
 +
 +BOOL CALLBACK EditProc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam)
 +{
 +	switch(msg){
 +		case WM_SETCURSOR:
 +			SetCursor(LoadCursor(NULL,IDC_ARROW));
 +			return 1;
 +
 +		default:
 +			break;
 +	}
 +	return CallWindowProc(MainProc,hdlg,msg,wparam,lparam);
 +}
 +
 +
 +
 +INT_PTR CALLBACK UserinfoDlgProc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam)
 +{
 +	char *szout;
 +	DBVARIANT dbv;
 +	
 +	switch(msg){
 +
 +		case WM_INITDIALOG:
 +			MainProc=(WNDPROC)SetWindowLongPtr(GetDlgItem(hdlg,IDC_INFOTEXT),GWLP_WNDPROC,(LONG)EditProc);
 +			szout=strdup(ParseString((!DBGetContactSetting(NULL,S_MOD,"UserStamp",&dbv)?dbv.pszVal:DEFAULT_USERSTAMP),(HANDLE)lparam,0));
 +			SetDlgItemText(hdlg,IDC_INFOTEXT,szout);
 +			if (!strcmp(szout,Translate("<unknown>")))
 +			EnableWindow(GetDlgItem(hdlg,IDC_INFOTEXT),FALSE);
 +			free(szout);
 +			DBFreeVariant(&dbv);
 +			break;
 +
 +		case WM_COMMAND:
 +			if(HIWORD(wparam)==EN_SETFOCUS)
 +				SetFocus(GetParent(hdlg));
 +			break;
 +	}
 +
 +	return 0;
 +}
 +
 +
 +
 +int UserinfoInit(WPARAM wparam,LPARAM lparam)
 +{
 +	char *proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO,lparam,0);
 +	if (IsWatchedProtocol(proto)) {
 +		OPTIONSDIALOGPAGE uip;
 +		ZeroMemory(&uip,sizeof(uip));
 +		uip.cbSize=sizeof(uip);
 +		uip.hInstance=hInstance;
 +		uip.pszTemplate=MAKEINTRESOURCE(IDD_USERINFO);
 +		uip.pszTitle="Last seen";
 +		uip.pfnDlgProc=UserinfoDlgProc;
 +		UserInfo_AddPage(wparam, &uip);
 +	}
 +	return 0;
 +}
 diff --git a/plugins/SeenPlugin/src/utils.cpp b/plugins/SeenPlugin/src/utils.cpp new file mode 100644 index 0000000000..d989f9e999 --- /dev/null +++ b/plugins/SeenPlugin/src/utils.cpp @@ -0,0 +1,878 @@ +/*
 +"Last Seen mod" plugin for Miranda IM
 +Copyright ( C ) 2002-03  micron-x
 +Copyright ( C ) 2005-07  Y.B.
 +
 +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.
 +
 +File name      : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/utils.c $
 +Revision       : $Rev: 1570 $
 +Last change on : $Date: 2007-12-30 01:30:07 +0300 (Вс, 30 дек 2007) $
 +Last change by : $Author: y_b $
 +*/
 +#include "seen.h"
 +#include <m_ignore.h>
 +#include <time.h>
 +
 +
 +void FileWrite(HANDLE);
 +void HistoryWrite(HANDLE hcontact);
 +//void SetOffline(void);
 +void ShowHistory(HANDLE hContact, BYTE isAlert);
 +
 +char * courProtoName = 0;
 +
 +//copied from ..\..\miranda32\protocols\protocols\protocols.c
 +PROTOCOLDESCRIPTOR* Proto_IsProtocolLoaded(const char* szProto)
 +{
 +	return (PROTOCOLDESCRIPTOR*) CallService(MS_PROTO_ISPROTOCOLLOADED, 0, (LPARAM)szProto);
 +}
 +
 +
 +/*
 +Returns true if the protocols is to be monitored
 +*/
 +int IsWatchedProtocol(const char* szProto)
 +{
 +	DBVARIANT dbv;
 +	char *szProtoPointer, *szWatched;
 +	int iProtoLen, iWatchedLen;
 +	int retval = 0;
 +	PROTOCOLDESCRIPTOR *pd;
 +
 +	if (szProto == NULL)
 +		return 0;
 +	
 +	pd=Proto_IsProtocolLoaded(szProto);
 +	if (pd==NULL || pd->type!=PROTOTYPE_PROTOCOL || CallProtoService(pd->szName,PS_GETCAPS,PFLAGNUM_2,0)==0)
 +		return 0;
 +
 +	iProtoLen = (int)_tcslen(szProto);
 +	if(DBGetContactSetting(NULL, S_MOD, "WatchedProtocols", &dbv))
 +		szWatched = DEFAULT_WATCHEDPROTOCOLS;
 +	else
 +		szWatched = dbv.pszVal;
 +	iWatchedLen = (int)_tcslen(szWatched);
 +
 +	if (*szWatched == '\0') 
 +	{
 +		retval=1; //empty string: all protocols are watched
 +	} 
 +	else 
 +	{
 +		char sTemp [MAXMODULELABELLENGTH+1]="";
 +		strcat(sTemp,szProto);
 +		strcat(sTemp," ");
 +		szProtoPointer = strstr(szWatched, sTemp);
 +		if (szProtoPointer == NULL)
 +			retval=0;
 +		else 
 +			retval=1;
 +	}
 +
 +	DBFreeVariant(&dbv);
 +	return retval;
 +}
 +
 +BOOL isYahoo(char * protoname){
 +	if (protoname) {
 +		char *pszUniqueSetting = (char*)CallProtoService(protoname, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0);
 +		if (pszUniqueSetting){
 +			return (!strcmp(pszUniqueSetting,"yahoo_id"));
 +	}	}
 +	return FALSE;
 +}
 +BOOL isJabber(char * protoname){
 +	if (protoname) {
 +		char *pszUniqueSetting = (char*)CallProtoService(protoname, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0);
 +		if (pszUniqueSetting){
 +			return (!strcmp(pszUniqueSetting,"jid"));
 +	}	}
 +	return FALSE;
 +}
 +BOOL isICQ(char * protoname){
 +	if (protoname) {
 +		char *pszUniqueSetting = (char*)CallProtoService(protoname, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0);
 +		if (pszUniqueSetting){
 +			return (!strcmp(pszUniqueSetting,"UIN"));
 +	}	}
 +	return FALSE;
 +}
 +BOOL isMSN(char * protoname){
 +	if (protoname) {
 +		char *pszUniqueSetting = (char*)CallProtoService(protoname, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0);
 +		if (pszUniqueSetting){
 +			return (!strcmp(pszUniqueSetting,"e-mail"));
 +	}	}
 +	return FALSE;
 +}
 +
 +DWORD isSeen(HANDLE hcontact, SYSTEMTIME *st){
 +	DWORD res = 0;
 +	FILETIME ft;
 +	ULONGLONG ll;
 +	res = DBGetContactSettingDword(hcontact,S_MOD,"seenTS",0);
 +	if (res){
 +		if (st) {
 +			ll = UInt32x32To64(CallService(MS_DB_TIME_TIMESTAMPTOLOCAL,res,0), 10000000) + NUM100NANOSEC;
 +			ft.dwLowDateTime = (DWORD)ll;
 +			ft.dwHighDateTime = (DWORD)(ll >> 32);
 +			FileTimeToSystemTime(&ft, st);
 +		}
 +		return res;
 +	} else {
 +		SYSTEMTIME lst;
 +		ZeroMemory(&lst,sizeof(lst));
 +		if (lst.wYear = DBGetContactSettingWord(hcontact,S_MOD,"Year",0)) {
 +			if (lst.wMonth = DBGetContactSettingWord(hcontact,S_MOD,"Month",0)) {
 +				if (lst.wDay = DBGetContactSettingWord(hcontact,S_MOD,"Day",0)) {
 +					lst.wDayOfWeek = DBGetContactSettingWord(hcontact,S_MOD,"WeekDay",0);
 +					lst.wHour = DBGetContactSettingWord(hcontact,S_MOD,"Hours",0);
 +					lst.wMinute = DBGetContactSettingWord(hcontact,S_MOD,"Minutes",0);
 +					lst.wSecond = DBGetContactSettingWord(hcontact,S_MOD,"Seconds",0);
 +					if (SystemTimeToFileTime(&lst,&ft)) {
 +						ll = ((LONGLONG)ft.dwHighDateTime<<32)|((LONGLONG)ft.dwLowDateTime);
 +						ll -= NUM100NANOSEC;
 +						ll /= 10000000;
 +						//perform LOCALTOTIMESTAMP
 +						res = (DWORD)ll - CallService(MS_DB_TIME_TIMESTAMPTOLOCAL,0,0);
 +						//nevel look for Year/Month/Day/Hour/Minute/Second again
 +						DBWriteContactSettingDword(hcontact,S_MOD,"seenTS",res);
 +					}
 +		}	}	}
 +		if (st) CopyMemory (st, &lst, sizeof (SYSTEMTIME));
 +	}
 +	return res;
 +}
 +
 +char *ParseString(char *szstring,HANDLE hcontact,BYTE isfile)
 +{
 +#define MAXSIZE 1024
 +	static char sztemp[MAXSIZE+1];
 +	int sztemplen = 0;
 +	char szdbsetting[128]="";
 +	char *charPtr;
 +	UINT loop=0;
 +	int isetting=0;
 +	DWORD dwsetting=0;
 +	struct in_addr ia;
 +	char *weekdays[]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
 +	char *wdays_short[]={"Sun.","Mon.","Tue.","Wed.","Thu.","Fri.","Sat."};
 +	char *monthnames[]={"January","February","March","April","May","June","July","August","September","October","November","December"};
 +	char *mnames_short[]={"Jan.","Feb.","Mar.","Apr.","May","Jun.","Jul.","Aug.","Sep.","Oct.","Nov.","Dec."};
 +	CONTACTINFO ci;
 +	BOOL wantempty;
 +	SYSTEMTIME st;
 +
 +	sztemp[0] = '\0';
 +	if (!isSeen(hcontact,&st)) {
 +		strcat(sztemp,Translate("<never seen>"));
 +		return sztemp;
 +	}
 +
 +	ci.cbSize=sizeof(CONTACTINFO);
 +	ci.hContact=hcontact;
 +	ci.szProto=hcontact?(char *)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hcontact,0):courProtoName;
 +	for (;loop<strlen(szstring);loop++)
 +	{
 +		if (sztemplen == MAXSIZE) break;
 +		if ((szstring[loop]!='%')&(szstring[loop]!='#'))
 +		{
 +			strncat(sztemp,szstring+loop,1);
 +			sztemplen++;
 +			continue;
 +		}
 +
 +		else
 +		{
 +			wantempty = (szstring[loop]=='#');
 +			switch(szstring[++loop]) {
 +				case 'Y':
 +					if (!st.wYear) goto LBL_noData;
 +					sztemplen += mir_snprintf(sztemp+sztemplen,MAXSIZE-sztemplen,"%04i",st.wYear);
 +					break;
 +
 +				case 'y':
 +					if (!st.wYear) goto LBL_noData;
 +					wsprintf(szdbsetting,"%04i",st.wYear);
 +					sztemplen += mir_snprintf(sztemp+sztemplen,MAXSIZE-sztemplen,"%s",szdbsetting+2);
 +					break;
 +
 +				case 'm':
 +					if (!(isetting=st.wMonth)) goto LBL_noData;
 +LBL_2DigNum:
 +					sztemplen += mir_snprintf(sztemp+sztemplen,MAXSIZE-sztemplen,"%02i",isetting);
 +					break;
 +
 +				case 'd':
 +					if (isetting=st.wDay) goto LBL_2DigNum;
 +					else goto LBL_noData;
 +
 +				case 'W':
 +					isetting=st.wDayOfWeek;
 +					if(isetting==-1){
 +LBL_noData:
 +						charPtr = wantempty?"":Translate("<unknown>");
 +						goto LBL_charPtr;
 +					}
 +					charPtr = Translate(weekdays[isetting]);
 +LBL_charPtr:
 +					sztemplen += mir_snprintf(sztemp+sztemplen,MAXSIZE-sztemplen,"%s",charPtr);
 +					break;
 +
 +				case 'w':
 +					isetting=st.wDayOfWeek;
 +					if(isetting==-1)goto LBL_noData;
 +					charPtr = Translate(wdays_short[isetting]);
 +					goto LBL_charPtr;
 +
 +				case 'E':
 +					if (!(isetting=st.wMonth))goto LBL_noData;
 +					charPtr = Translate(monthnames[isetting-1]);
 +					goto LBL_charPtr;
 +
 +				case 'e':
 +					if (!(isetting=st.wMonth))goto LBL_noData;
 +					charPtr = Translate(mnames_short[isetting-1]);
 +					goto LBL_charPtr;
 +
 +				case 'H':
 +					if ((isetting=st.wHour)==-1)goto LBL_noData;
 +					goto LBL_2DigNum;
 +
 +				case 'h':
 +					if ((isetting=st.wHour)==-1)goto LBL_noData;
 +					if (!isetting) isetting=12;
 +					isetting = isetting-((isetting>12)?12:0);
 +					goto LBL_2DigNum;
 +
 +				case 'p':
 +					if ((isetting=st.wHour)==-1)goto LBL_noData;
 +					charPtr = (isetting>=12)?"PM":"AM";
 +					goto LBL_charPtr;
 +
 +				case 'M':
 +					if ((isetting=st.wMinute)==-1)goto LBL_noData;
 +					goto LBL_2DigNum;
 +
 +				case 'S':
 +					if ((isetting=st.wHour)==-1)goto LBL_noData;
 +					goto LBL_2DigNum;
 +
 +				case 'n':
 +					charPtr = hcontact?(char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hcontact,0):(wantempty?"":"---");
 +					goto LBL_charPtr;
 +				case 'N':
 +					ci.dwFlag=CNF_NICK;
 +					if (!CallService(MS_CONTACT_GETCONTACTINFO,(WPARAM)0,(LPARAM)&ci)) {
 +						charPtr = ci.pszVal;
 +					} else goto LBL_noData;
 +					goto LBL_charPtr;
 +				case 'G':
 +					{
 +						DBVARIANT dbv;
 +						if (!DBGetContactSetting(hcontact,"CList","Group",&dbv)) {
 +							strcpy(szdbsetting,dbv.pszVal);
 +							DBFreeVariant(&dbv);
 +							charPtr = szdbsetting;
 +							goto LBL_charPtr;
 +						} else; //do nothing
 +					}
 +					break;
 +
 +				case 'u':
 +					ci.dwFlag=CNF_UNIQUEID;
 +					if (!CallService(MS_CONTACT_GETCONTACTINFO,(WPARAM)0,(LPARAM)&ci))
 +					{
 +						switch(ci.type)
 +						{
 +							case CNFT_BYTE:
 +								ltoa(ci.bVal,szdbsetting,10);
 +								break;
 +							case CNFT_WORD:
 +								ltoa(ci.wVal,szdbsetting,10);
 +								break;
 +							case CNFT_DWORD:
 +								ltoa(ci.dVal,szdbsetting,10);
 +								break;
 +							case CNFT_ASCIIZ:
 +								strcpy(szdbsetting,ci.pszVal);
 +								break;
 +						}
 +
 +					}
 +					else if (ci.szProto != NULL) 
 +					{
 +						if (isYahoo(ci.szProto)) // YAHOO support
 +						{
 +							DBVARIANT dbv;
 +							DBGetContactSetting(hcontact,ci.szProto,"id",&dbv);
 +							strcpy(szdbsetting,dbv.pszVal);
 +							DBFreeVariant(&dbv);
 +						}
 +						else if (isJabber(ci.szProto)) // JABBER support
 +						{
 +							DBVARIANT dbv;
 +							if (DBGetContactSetting(hcontact,ci.szProto,"LoginName",&dbv)) goto LBL_noData;
 +							strcpy(szdbsetting,dbv.pszVal);
 +							DBFreeVariant(&dbv);
 +							DBGetContactSetting(hcontact,ci.szProto,"LoginServer",&dbv);
 +							strcat(szdbsetting,"@");
 +							strcat(szdbsetting,dbv.pszVal);
 +							DBFreeVariant(&dbv);
 +						} else goto LBL_noData;
 +					}
 +					else goto LBL_noData;
 +					charPtr = szdbsetting;
 +					goto LBL_charPtr;
 +
 +				case 's':
 +					if (isetting=DBGetContactSettingWord(hcontact,S_MOD,hcontact?"StatusTriger":courProtoName,0)) {
 +						strcpy(szdbsetting,Translate((const char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,(WPARAM)(isetting|0x8000),0)));
 +						if (!(isetting&0x8000)) {
 +							strcat(szdbsetting,"/");
 +							strcat(szdbsetting,Translate("Idle"));
 +						}
 +						charPtr = szdbsetting;
 +					} else goto LBL_noData;
 +					goto LBL_charPtr;
 +				case 'T':
 +					{
 +						DBVARIANT dbv;
 +						if (!DBGetContactSetting(hcontact,"CList","StatusMsg",&dbv)) {
 +							sztemplen += mir_snprintf(sztemp+sztemplen,MAXSIZE-sztemplen,"%s",dbv.pszVal);
 +							DBFreeVariant(&dbv);
 +						} else goto LBL_noData;
 +					}
 +					break;
 +				case 'o':
 +					if (isetting=DBGetContactSettingWord(hcontact,S_MOD,hcontact?"OldStatus":courProtoName,0)) {
 +						strcpy(szdbsetting,Translate((const char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,(WPARAM)isetting,0)));
 +						if (includeIdle) if (hcontact) if (DBGetContactSettingByte(hcontact,S_MOD,"OldIdle",0)) {
 +							strcat(szdbsetting,"/");
 +							strcat(szdbsetting,Translate("Idle"));
 +						}
 +						charPtr = szdbsetting;
 +					} else goto LBL_noData;
 +					goto LBL_charPtr;
 +
 +				case 'i':
 +				case 'r': if (isJabber(ci.szProto)) {
 +							DBVARIANT dbv;
 +							if (!DBGetContactSetting(hcontact,ci.szProto,szstring[loop]=='i'?"Resource":"System",&dbv)) {
 +								strcpy(szdbsetting,dbv.pszVal);
 +								DBFreeVariant(&dbv);
 +								charPtr = szdbsetting;
 +							} else goto LBL_noData;
 +						  } else {
 +							dwsetting=DBGetContactSettingDword(hcontact,ci.szProto,szstring[loop]=='i'?"IP":"RealIP",0);
 +							if(dwsetting){
 +								ia.S_un.S_addr=htonl(dwsetting);
 +								charPtr = inet_ntoa(ia);
 +							} else goto LBL_noData;
 +						  }
 +					goto LBL_charPtr;
 +				case 'P':if (ci.szProto) charPtr = ci.szProto; else charPtr = wantempty?"":"ProtoUnknown";
 +					goto LBL_charPtr;
 +				case 'b':
 +					charPtr = /*"\n"*/"\x0D\x0A";
 +					goto LBL_charPtr;
 +				case 'C': // Get Client Info
 +					if (isMSN(ci.szProto)) {
 +						if (hcontact) {
 +							dwsetting = (int)DBGetContactSettingDword(hcontact,ci.szProto,"FlagBits",0);
 +							wsprintf(szdbsetting,"MSNC%i",(dwsetting&0x70000000)>>28);
 +							if (dwsetting & 0x00000001) strcat(szdbsetting," MobD"); //Mobile Device
 +							if (dwsetting & 0x00000004) strcat(szdbsetting," InkG"); //GIF Ink Send/Receive
 +							if (dwsetting & 0x00000008) strcat(szdbsetting," InkI"); //ISF Ink Send/Receive
 +							if (dwsetting & 0x00000010) strcat(szdbsetting," WCam"); //Webcam
 +							if (dwsetting & 0x00000020) strcat(szdbsetting," MPkt"); //Multi packet messages
 +							if (dwsetting & 0x00000040) strcat(szdbsetting," SMSr"); //Paging
 +							if (dwsetting & 0x00000080) strcat(szdbsetting," DSMS"); //Using MSN Direct
 +							if (dwsetting & 0x00000200) strcat(szdbsetting," WebM"); //WebMessenger
 +							if (dwsetting & 0x00001000) strcat(szdbsetting," MS7+"); //Unknown (Msgr 7 always[?] sets it)
 +							if (dwsetting & 0x00004000) strcat(szdbsetting," DirM"); //DirectIM
 +							if (dwsetting & 0x00008000) strcat(szdbsetting," Wink"); //Send/Receive Winks
 +							if (dwsetting & 0x00010000) strcat(szdbsetting," MSrc"); //MSN Search ??
 +							if (dwsetting & 0x00040000) strcat(szdbsetting," VoiC"); //Voice Clips
 +						} else strcpy(szdbsetting,"Miranda");
 +					} else {
 +						DBVARIANT dbv;
 +						if (!DBGetContactSetting(hcontact,ci.szProto,"MirVer",&dbv)) {
 +							strcpy(szdbsetting,dbv.pszVal);
 +							DBFreeVariant(&dbv);
 +						} else goto LBL_noData;
 +					}
 +					charPtr = szdbsetting;
 +					goto LBL_charPtr;
 +				case 't':
 +					charPtr = "\t";
 +					goto LBL_charPtr;
 +
 +				default:
 +					strncpy(szdbsetting,szstring+loop-1,2);
 +					goto LBL_charPtr;
 +			}
 +		}
 +	}
 +
 +	return sztemp;
 +}
 +
 +
 +
 +void _DBWriteTime(SYSTEMTIME *st,HANDLE hcontact)
 +{
 +	DBWriteContactSettingWord((HANDLE)hcontact,S_MOD,"Day",st->wDay);
 +	DBWriteContactSettingWord((HANDLE)hcontact,S_MOD,"Month",st->wMonth);
 +	DBWriteContactSettingWord((HANDLE)hcontact,S_MOD,"Year",st->wYear);
 +	DBWriteContactSettingWord((HANDLE)hcontact,S_MOD,"Hours",st->wHour);
 +	DBWriteContactSettingWord((HANDLE)hcontact,S_MOD,"Minutes",st->wMinute);
 +	DBWriteContactSettingWord((HANDLE)hcontact,S_MOD,"Seconds",st->wSecond);
 +	DBWriteContactSettingWord((HANDLE)hcontact,S_MOD,"WeekDay",st->wDayOfWeek);
 +
 +}
 +
 +void DBWriteTimeTS(DWORD t, HANDLE hcontact){
 +	SYSTEMTIME st;
 +	FILETIME ft;
 +	ULONGLONG ll = UInt32x32To64(CallService(MS_DB_TIME_TIMESTAMPTOLOCAL,t,0), 10000000) + NUM100NANOSEC;
 +	ft.dwLowDateTime = (DWORD)ll;
 +	ft.dwHighDateTime = (DWORD)(ll >> 32);
 +	FileTimeToSystemTime(&ft, &st);
 +	DBWriteContactSettingDword(hcontact,S_MOD,"seenTS",t);
 +	_DBWriteTime(&st, hcontact);
 +}
 +void GetColorsFromDWord(LPCOLORREF First, LPCOLORREF Second, DWORD colDword){
 +	WORD temp;
 +	COLORREF res=0;
 +	temp = (WORD)(colDword>>16);
 +	res |= ((temp & 0x1F) <<3);
 +	res |= ((temp & 0x3E0) <<6);
 +	res |= ((temp & 0x7C00) <<9);
 +	if (First) *First = res;
 +	res = 0;
 +	temp = (WORD)colDword;
 +	res |= ((temp & 0x1F) <<3);
 +	res |= ((temp & 0x3E0) <<6);
 +	res |= ((temp & 0x7C00) <<9);
 +	if (Second) *Second = res;
 +}
 +
 +DWORD StatusColors15bits[] = {
 +	0x63180000, // 0x00C0C0C0, 0x00000000, Offline - LightGray
 +	0x7B350000, // 0x00F0C8A8, 0x00000000, Online  - LightBlue
 +	0x33fe0000, // 0x0070E0E0, 0x00000000, Away -LightOrange
 +	0x295C0000, // 0x005050E0, 0x00000000, DND  -DarkRed
 +	0x5EFD0000, // 0x00B8B8E8, 0x00000000, NA   -LightRed
 +	0x295C0000, // 0x005050E0, 0x00000000, Occupied
 +	0x43900000, // 0x0080E080, 0x00000000, Free for chat - LightGreen
 +	0x76AF0000, // 0x00E8A878, 0x00000000, Invisible
 +	0x431C0000, // 0x0080C0E0, 0x00000000, On the phone
 +	0x5EFD0000, // 0x00B8B8E8, 0x00000000, Out to lunch
 +};
 +
 +DWORD GetDWordFromColors(COLORREF First, COLORREF Second){
 +	DWORD res = 0;
 +	res |= (First&0xF8)>>3;
 +	res |= (First&0xF800)>>6;
 +	res |= (First&0xF80000)>>9;
 +	res <<= 16;
 +	res |= (Second&0xF8)>>3;
 +	res |= (Second&0xF800)>>6;
 +	res |= (Second&0xF80000)>>9;
 +	return res;
 +}
 +
 +LRESULT CALLBACK PopupDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
 +
 +	switch(message) {
 +		case WM_COMMAND: 
 +			if (HIWORD(wParam) == STN_CLICKED){
 +				HANDLE hContact = PUGetContact(hwnd);
 +				if (hContact > 0) CallService(MS_MSG_SENDMESSAGE,(WPARAM)hContact,0);
 +			}
 +		case WM_CONTEXTMENU:
 +			PUDeletePopUp(hwnd);
 +			break;
 +		case UM_INITPOPUP: return 0;
 +	}
 +	return DefWindowProc(hwnd, message, wParam, lParam);
 +};
 +
 +void ShowPopup(HANDLE hcontact, const char * lpzProto, int newStatus){
 +	if(CallService(MS_IGNORE_ISIGNORED,(WPARAM)hcontact,IGNOREEVENT_USERONLINE)) return;
 +	if (ServiceExists(MS_POPUP_QUERY)) {
 +		if (DBGetContactSettingByte(NULL,S_MOD,"UsePopups",0)) {
 +			if (!DBGetContactSettingByte(hcontact,"CList","Hidden",0)) {
 +				POPUPDATAEX ppd = {0};
 +				DBVARIANT dbv = {0};
 +				char szstamp[10];
 +				DWORD sett;
 +				sprintf(szstamp, "Col_%d",newStatus-ID_STATUS_OFFLINE);
 +				sett = DBGetContactSettingDword(NULL,S_MOD,szstamp,StatusColors15bits[newStatus-ID_STATUS_OFFLINE]);
 +				GetColorsFromDWord(&ppd.colorBack,&ppd.colorText,sett);
 +				ppd.lchContact = hcontact;
 +				ppd.lchIcon = LoadSkinnedProtoIcon(lpzProto, newStatus);
 +				strncpy(ppd.lpzContactName,ParseString(!DBGetContactSetting(NULL,S_MOD,"PopupStamp",&dbv)?dbv.pszVal:DEFAULT_POPUPSTAMP,hcontact,0),MAX_CONTACTNAME);
 +				DBFreeVariant(&dbv);
 +				strncpy(ppd.lpzText,ParseString(!DBGetContactSetting(NULL,S_MOD,"PopupStampText",&dbv)?dbv.pszVal:DEFAULT_POPUPSTAMPTEXT,hcontact,0),MAX_SECONDLINE);
 +				DBFreeVariant(&dbv);
 +				ppd.PluginWindowProc = (WNDPROC)PopupDlgProc;
 +				CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0);
 +			}
 +		}
 +	}
 +}
 +
 +void myPlaySound(HANDLE hcontact, WORD newStatus, WORD oldStatus){
 +	if(CallService(MS_IGNORE_ISIGNORED,(WPARAM)hcontact,IGNOREEVENT_USERONLINE)) return;
 +	//oldStatus and hcontact are not used yet
 +	if (DBGetContactSettingByte(NULL,"Skin","UseSound",1)) {
 +		char * soundname=0;
 +		if ((newStatus==ID_STATUS_ONLINE) || (newStatus==ID_STATUS_FREECHAT)) soundname = "LastSeenTrackedStatusOnline";
 +		else if (newStatus==ID_STATUS_OFFLINE) soundname = "LastSeenTrackedStatusOffline";
 +		else if (oldStatus==ID_STATUS_OFFLINE) soundname = "LastSeenTrackedStatusFromOffline";
 +		else soundname = "LastSeenTrackedStatusChange";
 +		if (!DBGetContactSettingByte(NULL,"SkinSoundsOff",soundname,0)) {
 +			DBVARIANT dbv;
 +			if (!DBGetContactSetting(NULL,"SkinSounds",soundname,&dbv)) {
 +				PlaySoundA(dbv.pszVal, NULL, SND_ASYNC | SND_FILENAME | SND_NOWAIT);
 +				DBFreeVariant(&dbv);
 +}	}	}	}
 +
 +//will give hContact position or zero
 +int isContactQueueActive(HANDLE hContact){
 +	int i = 0;
 +	if (!hContact) {
 +//		MessageBox(0,"Is myself in the queue: never","LastSeen-Mod",0);
 +		return 0;
 +	}
 +	for (i=1;i<contactQueueSize;i++) {
 +		if (contactQueue[i])
 +			if (contactQueue[i]->hContact==hContact) return i;
 +	}
 +	return 0;
 +}
 +
 +//will add hContact to queue and will return position;
 +int addContactToQueue(HANDLE hContact){
 +	int i = 0;
 +	if (!hContact) {
 +//		MessageBox(0,"Adding myself to queue","LastSeen-Mod",0);
 +		return 0;
 +	}
 +	for (i=1;i<contactQueueSize;i++) {
 +		if (!contactQueue[i]) {
 +			contactQueue[i] = (logthread_info *)malloc(sizeof(logthread_info));
 +			contactQueue[i]->queueIndex = i;
 +			contactQueue[i]->hContact = hContact;
 +			return i;
 +		}
 +	}
 +	//no free space. Create some
 +	//MessageBox(0,"Creating more space","LastSeen-Mod",0);
 +	contactQueue = (logthread_info **)realloc(contactQueue,(contactQueueSize+16)*sizeof(logthread_info *));
 +	memset(&contactQueue[contactQueueSize],0, 16*sizeof(logthread_info *));
 +	i = contactQueueSize;
 +	contactQueue[i] = (logthread_info *)malloc(sizeof(logthread_info));
 +	contactQueue[i]->queueIndex = i;
 +	contactQueue[i]->hContact = hContact;
 +	contactQueueSize += 16;
 +	return i;
 +}
 +
 +static DWORD __stdcall waitThread(logthread_info* infoParam)
 +{
 +	WORD prevStatus = DBGetContactSettingWord(infoParam->hContact,S_MOD,"StatusTriger",ID_STATUS_OFFLINE);
 +	Sleep(1500); // I hope in 1.5 second all the needed info will be set
 +	if (includeIdle)
 +		if (DBGetContactSettingDword(infoParam->hContact,infoParam->sProtoName,"IdleTS",0))
 +			infoParam->courStatus &=0x7FFF;
 +
 +	if (infoParam->courStatus != prevStatus){
 +		DBWriteContactSettingWord(infoParam->hContact,S_MOD,"OldStatus",(WORD)(prevStatus|0x8000));
 +		if (includeIdle)
 +			DBWriteContactSettingByte(infoParam->hContact,S_MOD,"OldIdle",(BYTE)((prevStatus&0x8000)==0));
 +
 +		DBWriteContactSettingWord(infoParam->hContact,S_MOD,"StatusTriger",infoParam->courStatus);
 +	}
 +
 +	contactQueue[infoParam->queueIndex] = 0;
 +	free(infoParam);
 +	return 0;
 +}
 +
 +
 +
 +int UpdateValues(WPARAM wparam,LPARAM lparam)
 +{
 +	DBCONTACTWRITESETTING *cws;
 +	BOOL isIdleEvent;
 +	// to make this code faster
 +	if (!wparam) return 0;
 +	cws=(DBCONTACTWRITESETTING *)lparam;
 +	//if(CallService(MS_IGNORE_ISIGNORED,(WPARAM)hContact,IGNOREEVENT_USERONLINE)) return 0;
 +	isIdleEvent = includeIdle?(strcmp(cws->szSetting,"IdleTS")==0):0;
 +	if (strcmp(cws->szSetting,"Status") && strcmp(cws->szSetting,"StatusTriger") && (isIdleEvent==0)) return 0;
 +	if (!strcmp(cws->szModule,S_MOD)) {
 +		//here we will come when Settings/SeenModule/StatusTriger is changed
 +		WORD prevStatus=DBGetContactSettingWord((HANDLE)wparam, S_MOD, "OldStatus", ID_STATUS_OFFLINE);
 +		if (includeIdle){
 +			if (DBGetContactSettingByte((HANDLE)wparam, S_MOD, "OldIdle", 0)) prevStatus &= 0x7FFF;
 +			else prevStatus |= 0x8000;
 +		}
 +		if ((cws->value.wVal|0x8000)<=ID_STATUS_OFFLINE)
 +		{
 +			char * proto;
 +			// avoid repeating the offline status
 +			if ((prevStatus|0x8000)<=ID_STATUS_OFFLINE)
 +				return 0;
 +			proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, wparam, 0);
 +			DBWriteContactSettingByte((HANDLE)wparam, S_MOD, "Offline", 1);
 +			{
 +				DWORD t;
 +				char *str = (char *)malloc(MAXMODULELABELLENGTH+9);
 +				mir_snprintf(str,MAXMODULELABELLENGTH+8,"OffTime-%s",proto);
 +				t = DBGetContactSettingDword(NULL,S_MOD,str,0);
 +				if (!t) t = time(NULL);
 +				free(str);
 +				DBWriteTimeTS(t, (HANDLE)wparam);
 +			}
 +
 +			if (!DBGetContactSettingByte(NULL,S_MOD,"IgnoreOffline",1))
 +			{
 +				char * sProto;
 +				if(DBGetContactSettingByte(NULL,S_MOD,"FileOutput",0))
 +					FileWrite((HANDLE)wparam);
 +
 +				if (CallProtoService(sProto = 
 +					(char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, wparam, 0),
 +					PS_GETSTATUS,0,0
 +					)>ID_STATUS_OFFLINE)	{
 +					myPlaySound((HANDLE)wparam, ID_STATUS_OFFLINE, prevStatus);
 +					if(DBGetContactSettingByte(NULL, S_MOD, "UsePopups", 0)) {
 +						ShowPopup((HANDLE)wparam, sProto, ID_STATUS_OFFLINE);
 +				}	}
 +
 +				if(DBGetContactSettingByte(NULL, S_MOD, "KeepHistory", 0))
 +					HistoryWrite((HANDLE)wparam);
 +
 +				if(DBGetContactSettingByte((HANDLE)wparam, S_MOD, "OnlineAlert", 0)) 
 +					ShowHistory((HANDLE)wparam, 1);
 +			}
 +
 +		} else {
 +
 +			if(cws->value.wVal==prevStatus && !DBGetContactSettingByte((HANDLE)wparam, S_MOD, "Offline", 0)) 
 +				return 0;
 +
 +			DBWriteTimeTS(time(NULL), (HANDLE)wparam);
 +
 +			//DBWriteContactSettingWord(hContact,S_MOD,"StatusTriger",(WORD)cws->value.wVal);
 +
 +			if(DBGetContactSettingByte(NULL, S_MOD, "FileOutput", 0)) FileWrite((HANDLE)wparam);
 +			if (prevStatus != cws->value.wVal) myPlaySound((HANDLE)wparam, cws->value.wVal, prevStatus);
 +			if(DBGetContactSettingByte(NULL, S_MOD, "UsePopups", 0))
 +				if (prevStatus != cws->value.wVal) ShowPopup((HANDLE)wparam, (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, wparam, 0), cws->value.wVal|0x8000);
 +
 +			if(DBGetContactSettingByte(NULL, S_MOD, "KeepHistory", 0)) HistoryWrite((HANDLE)wparam);
 +			if(DBGetContactSettingByte((HANDLE)wparam, S_MOD, "OnlineAlert", 0)) ShowHistory((HANDLE)wparam, 1);
 +			DBWriteContactSettingByte((HANDLE)wparam, S_MOD, "Offline", 0);
 +		}
 +	} else if (IsWatchedProtocol(cws->szModule)) {
 +		//here we will come when <User>/<module>/Status is changed or it is idle event and if <module> is watched
 +		if (CallProtoService(cws->szModule,PS_GETSTATUS,0,0)>ID_STATUS_OFFLINE){
 +			int index;
 +			if (!(index = isContactQueueActive((HANDLE)wparam))) {
 +				index = addContactToQueue((HANDLE)wparam);
 +				strncpy(contactQueue[index]->sProtoName,cws->szModule,MAXMODULELABELLENGTH);
 +	
 +				unsigned int dwThreadId;
 +				mir_forkthreadex((pThreadFuncEx)waitThread, contactQueue[index], &dwThreadId);
 +			}
 +			contactQueue[index]->courStatus = isIdleEvent ? DBGetContactSettingWord((HANDLE)wparam, cws->szModule, "Status", ID_STATUS_OFFLINE) : cws->value.wVal;
 +	}	}	
 +
 +	return 0;
 +}
 +
 +static DWORD __stdcall cleanThread(logthread_info* infoParam)
 +{
 +	Sleep(10000); // I hope in 10 secons all logged-in contacts will be listed
 +
 +	HANDLE hcontact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);
 +	while(hcontact != NULL) {
 +		char *contactProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hcontact,0);
 +		if (contactProto) {
 +			if ( !strncmp(infoParam->sProtoName, contactProto, MAXMODULELABELLENGTH)) {
 +				WORD oldStatus = DBGetContactSettingWord(hcontact,S_MOD,"StatusTriger",ID_STATUS_OFFLINE) | 0x8000;
 +				if (oldStatus > ID_STATUS_OFFLINE) {
 +					if (DBGetContactSettingWord(hcontact,contactProto,"Status",ID_STATUS_OFFLINE)==ID_STATUS_OFFLINE){
 +						DBWriteContactSettingWord(hcontact,S_MOD,"OldStatus",(WORD)(oldStatus|0x8000));
 +						if (includeIdle)DBWriteContactSettingByte(hcontact,S_MOD,"OldIdle",(BYTE)((oldStatus&0x8000)?0:1));
 +						DBWriteContactSettingWord(hcontact,S_MOD,"StatusTriger",ID_STATUS_OFFLINE);
 +					}
 +				}
 +			}
 +		}
 +		hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hcontact,0);
 +	}
 +
 +	char *str = (char *)malloc(MAXMODULELABELLENGTH+9);
 +	mir_snprintf(str,MAXMODULELABELLENGTH+8,"OffTime-%s",infoParam->sProtoName);
 +	DBDeleteContactSetting(NULL,S_MOD,str);
 +	free(str);
 +
 +	free(infoParam);
 +	return 0;
 +}
 +
 +
 +int ModeChange(WPARAM wparam,LPARAM lparam)
 +{
 +	ACKDATA *ack;
 +	WORD isetting=0;
 +
 +	ack=(ACKDATA *)lparam;
 +
 +	if(ack->type!=ACKTYPE_STATUS || ack->result!=ACKRESULT_SUCCESS || ack->hContact!=NULL) return 0;
 +	courProtoName = (char *)ack->szModule;
 +	if (!IsWatchedProtocol(courProtoName) && strncmp(courProtoName,"MetaContacts",12)) 
 +	{
 +		//MessageBox(NULL,"Protocol not watched",courProtoName,0);
 +		return 0;
 +	}
 +
 +	DBWriteTimeTS(time(NULL),NULL);
 +
 +//	isetting=CallProtoService(ack->szModule,PS_GETSTATUS,0,0);
 +	isetting=(WORD)ack->lParam;
 +	if (isetting<ID_STATUS_OFFLINE) isetting = ID_STATUS_OFFLINE;
 +	if ((isetting>ID_STATUS_OFFLINE)&&((WORD)ack->hProcess<=ID_STATUS_OFFLINE)) {
 +		//we have just loged-in
 +		db_dword_set(NULL, "UserOnline", ack->szModule, GetTickCount());
 +		if (IsWatchedProtocol(ack->szModule)) {
 +			logthread_info *info;
 +			info = (logthread_info *)malloc(sizeof(logthread_info));
 +			strncpy(info->sProtoName,courProtoName,MAXMODULELABELLENGTH);
 +			info->hContact = 0;
 +			info->courStatus = 0;
 +
 +			unsigned int dwThreadId;
 +			CloseHandle( mir_forkthreadex((pThreadFuncEx)cleanThread, info, &dwThreadId));
 +		}
 +	} else if ((isetting==ID_STATUS_OFFLINE)&&((WORD)ack->hProcess>ID_STATUS_OFFLINE)) {
 +		//we have just loged-off
 +		if (IsWatchedProtocol(ack->szModule)) {
 +			char *str = (char *)malloc(MAXMODULELABELLENGTH+9);
 +			time_t t;
 +			time(&t);
 +			mir_snprintf(str,MAXMODULELABELLENGTH+8,"OffTime-%s",ack->szModule);
 +			DBWriteContactSettingDword(NULL,S_MOD,str,t);
 +			free(str);
 +	}	}
 +	if (isetting==DBGetContactSettingWord(NULL,S_MOD,courProtoName,ID_STATUS_OFFLINE)) return 0;
 +	DBWriteContactSettingWord(NULL,S_MOD,courProtoName,isetting);
 +
 +	// log "myself"
 +	if(DBGetContactSettingByte(NULL,S_MOD,"FileOutput",0))
 +		FileWrite(NULL);
 +
 +//	if(isetting==ID_STATUS_OFFLINE) //this is removed 'cause I want other contacts to be logged only if the status changed while I was offline
 +//		SetOffline();
 +
 +	courProtoName = NULL;
 +
 +	return 0;
 +}
 +
 +short int isDbZero(HANDLE hContact, const char *module_name, const char *setting_name){
 +	DBVARIANT dbv;
 +	if (!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
 +		short int res = 0;
 +		switch (dbv.type) {
 +			case DBVT_BYTE: res=dbv.bVal==0; break;
 +			case DBVT_WORD: res=dbv.wVal==0; break;
 +			case DBVT_DWORD: res=dbv.dVal==0; break;
 +			case DBVT_BLOB: res=dbv.cpbVal==0; break;
 +			default: res=dbv.pszVal[0]==0; break;
 +		}
 +		DBFreeVariant(&dbv); 
 +		return res;
 +	} else return -1;
 +}
 +
 +WCHAR *any_to_IdleNotidleUnknown(HANDLE hContact, const char *module_name, const char *setting_name, WCHAR *buff, int bufflen) {
 +	short int r = isDbZero(hContact, module_name, setting_name);
 +	if (r==-1){
 +		wcsncpy(buff, TranslateW(L"Unknown"), bufflen);
 +	} else {
 +		wcsncpy(buff, TranslateW(r?L"Not Idle":L"Idle"), bufflen);
 +	};
 +	buff[bufflen - 1] = 0;
 +	return buff;
 +}
 +WCHAR *any_to_Idle(HANDLE hContact, const char *module_name, const char *setting_name, WCHAR *buff, int bufflen) {
 +	if(isDbZero(hContact, module_name, setting_name)==0) { //DB setting is NOT zero and exists
 +		buff[0] = L'/';
 +		wcsncpy((WCHAR *)&buff[1], TranslateW(L"Idle"), bufflen-1);
 +	} else buff[0] = 0;
 +	buff[bufflen - 1] = 0;
 +	return buff;
 +}
 +
 +
 +/*int GetInfoAck(WPARAM wparam,LPARAM lparam)
 +{
 +	ACKDATA *ack;
 +	DWORD dwsetting=0;
 +
 +	ack=(ACKDATA *)lparam;
 +
 +	if(ack->type!=ACKTYPE_GETINFO || ack->hContact==NULL) return 0;
 +	if (((int)ack->hProcess-1)!=(int)ack->lParam) return 0;
 +	
 +	dwsetting=DBGetContactSettingDword(ack->hContact,ack->szModule,"IP",0);
 +	if(dwsetting)
 +		DBWriteContactSettingDword(ack->hContact,S_MOD,"IP",dwsetting);
 +
 +	dwsetting=DBGetContactSettingDword(ack->hContact,ack->szModule,"RealIP",0);
 +	if(dwsetting)
 +		DBWriteContactSettingDword(ack->hContact,S_MOD,"RealIP",dwsetting);
 +
 +	return 0;
 +}*/
 +
 +
 +
 +/*void SetOffline(void)
 +{
 +	HANDLE hcontact=NULL;
 +	char * szProto;
 +
 +	hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);
 +	while(hcontact!=NULL)
 +	{
 +		szProto=(char *)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hcontact,0);
 +		if (szProto != NULL && IsWatchedProtocol(szProto)) {	
 +			DBWriteContactSettingByte(hcontact,S_MOD,"Offline",1);
 +		}
 +		hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hcontact,0);
 +	}
 +}*/
 +
 +
 +
  | 
