summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/SmartAutoAway/AggressiveOptimize.h166
-rw-r--r--plugins/SmartAutoAway/aa_utils.cpp396
-rw-r--r--plugins/SmartAutoAway/autoaway.cpp662
-rw-r--r--plugins/SmartAutoAway/dlgproc.cpp281
-rw-r--r--plugins/SmartAutoAway/globals.cpp113
-rw-r--r--plugins/SmartAutoAway/globals.h349
-rw-r--r--plugins/SmartAutoAway/here.icobin0 -> 2550 bytes
-rw-r--r--plugins/SmartAutoAway/idle.cpp374
-rw-r--r--plugins/SmartAutoAway/idleMenu.cpp147
-rw-r--r--plugins/SmartAutoAway/idleMessages.cpp282
-rw-r--r--plugins/SmartAutoAway/long.icobin0 -> 2550 bytes
-rw-r--r--plugins/SmartAutoAway/reconnect.cpp328
-rw-r--r--plugins/SmartAutoAway/reconnect.icobin0 -> 2550 bytes
-rw-r--r--plugins/SmartAutoAway/resource.h77
-rw-r--r--plugins/SmartAutoAway/saa-res.rc238
-rw-r--r--plugins/SmartAutoAway/saa.cpp130
-rw-r--r--plugins/SmartAutoAway/saa.dsp291
-rw-r--r--plugins/SmartAutoAway/saa.dsw41
-rw-r--r--plugins/SmartAutoAway/saa.h1
-rw-r--r--plugins/SmartAutoAway/saamain.cpp415
-rw-r--r--plugins/SmartAutoAway/saani.c85
-rw-r--r--plugins/SmartAutoAway/saani.dsp107
-rw-r--r--plugins/SmartAutoAway/short.icobin0 -> 2550 bytes
-rw-r--r--plugins/SmartAutoAway/version.txt7
24 files changed, 4490 insertions, 0 deletions
diff --git a/plugins/SmartAutoAway/AggressiveOptimize.h b/plugins/SmartAutoAway/AggressiveOptimize.h
new file mode 100644
index 0000000000..51e5f5de04
--- /dev/null
+++ b/plugins/SmartAutoAway/AggressiveOptimize.h
@@ -0,0 +1,166 @@
+
+//////////////////////////////
+// Version 1.40
+// October 22nd, 2002 - .NET (VC7, _MSC_VER=1300) support!
+// Version 1.30
+// Nov 24th, 2000
+// Version 1.20
+// Jun 9th, 2000
+// Version 1.10
+// Jan 23rd, 2000
+// Version 1.00
+// May 20th, 1999
+// Todd C. Wilson, Fresh Ground Software
+// (todd@nopcode.com)
+// This header file will kick in settings for Visual C++ 5 and 6 that will (usually)
+// result in smaller exe's.
+// The "trick" is to tell the compiler to not pad out the function calls; this is done
+// by not using the /O1 or /O2 option - if you do, you implicitly use /Gy, which pads
+// out each and every function call. In one single 500k dll, I managed to cut out 120k
+// by this alone!
+// The other two "tricks" are telling the Linker to merge all data-type segments together
+// in the exe file. The relocation, read-only (constants) data, and code section (.text)
+// sections can almost always be merged. Each section merged can save 4k in exe space,
+// since each section is padded out to 4k chunks. This is very noticeable with smaller
+// exes, since you could have only 700 bytes of data, 300 bytes of code, 94 bytes of
+// strings - padded out, this could be 12k of runtime, for 1094 bytes of stuff! For larger
+// programs, this is less overall, but can save at least 4k.
+// Note that if you're using MFC static or some other 3rd party libs, you may get poor
+// results with merging the readonly (.rdata) section - the exe may grow larger.
+// To use this feature, define _MERGE_DATA_ in your project or before this header is used.
+// With Visual C++ 5, the program uses a file alignment of 512 bytes, which results
+// in a small exe. Under VC6, the program instead uses 4k, which is the same as the
+// section size. The reason (from what I understand) is that 4k is the chunk size of
+// the virtual memory manager, and that WinAlign (an end-user tuning tool for Win98)
+// will re-align the programs on this boundary. The problem with this is that all of
+// Microsoft's system exes and dlls are *NOT* tuned like this, and using 4k causes serious
+// exe bloat. This is very noticeable for smaller programs.
+// The "trick" for this is to use the undocumented FILEALIGN linker parm to change the
+// padding from 4k to 1/2k, which results in a much smaller exe - anywhere from 20%-75%
+// depending on the size. Note that this is the same as using /OPT:NOWIN98, which *is*
+// a previously documented switch, but was left out of the docs for some reason in VC6 and
+// all of the current MSDN's - see KB:Q235956 for more information.
+// Microsoft does say that using the 4k alignment will "speed up process loading",
+// but I've been unable to notice a difference, even on my P180, with a very large (4meg) exe.
+// Please note, however, that this will probably not change the size of the COMPRESSED
+// file (either in a .zip file or in an install archive), since this 4k is all zeroes and
+// gets compressed away.
+// Also, the /ALIGN:4096 switch will "magically" do the same thing, even though this is the
+// default setting for this switch. Apparently this sets the same values as the above two
+// switches do. We do not use this in this header, since it smacks of a bug and not a feature.
+// Thanks to Michael Geary <Mike@Geary.com> for some additional tips!
+//
+// Notes about using this header in .NET
+// First off, VC7 does not allow a lot of the linker command options in pragma's. There is no
+// honest or good reason why Microsoft decided to make this change, it just doesn't.
+// So that is why there are a lot of <1300 #if's in the header.
+// If you want to take full advantage of the VC7 linker options, you will need to do it on a
+// PER PROJECT BASIS; you can no longer use a global header file like this to make it better.
+// Items I strongly suggest putting in all your VC7 project linker options command line settings:
+// /ignore:4078 /RELEASE
+// Compiler options:
+// /GL (Whole Program Optimization)
+// If you're making an .EXE and not a .DLL, consider adding in:
+// /GA (Optimize for Windows Application)
+// Some items to consider using in your VC7 projects (not VC6):
+// Link-time Code Generation - whole code optimization. Put this in your exe/dll project link settings.
+// /LTCG:NOSTATUS
+// The classic no-padding and no-bloat compiler C/C++ switch:
+// /opt:nowin98
+//
+// (C++ command line options: /GL /opt:nowin98 and /GA for .exe files)
+// (Link command line options: /ignore:4078 /RELEASE /LTCG:NOSTATUS)
+//
+// Now, notes on using these options in VC7 vs VC6.
+// VC6 consistently, for me, produces smaller code from C++ the exact same sources,
+// with or without this header. On average, VC6 produces 5% smaller binaries compared
+// to VC7 compiling the exact same project, *without* this header. With this header, VC6
+// will make a 13k file, while VC7 will make a 64k one. VC7 is just bloaty, pure and
+// simple - all that managed/unmanaged C++ runtimes, and the CLR stuff must be getting
+// in the way of code generation. However, template support is better, so there.
+// Both VC6 and VC7 show the same end kind of end result savings - larger binary output
+// will shave about 2% off, where as smaller projects (support DLL's, cpl's,
+// activex controls, ATL libs, etc) get the best result, since the padding is usually
+// more than the actual usable code. But again, VC7 does not compile down as small as VC6.
+//
+// The argument can be made that doing this is a waste of time, since the "zero bytes"
+// will be compressed out in a zip file or install archive. Not really - it doesn't matter
+// if the data is a string of zeroes or ones or 85858585 - it will still take room (20 bytes
+// in a zip file, 29 bytes if only *4* of them 4k bytes are not the same) and time to
+// compress that data and decompress it. Also, 20k of zeros is NOT 20k on disk - it's the
+// size of the cluster slop- for Fat32 systems, 20k can be 32k, NTFS could make it 24k if you're
+// just 1 byte over (round up). Most end users do not have the dual P4 Xeon systems with
+// two gigs of RDram and a Raid 0+1 of Western Digital 120meg Special Editions that all
+// worthy developers have (all six of us), so they will need any space and LOADING TIME
+// savings they will need; taking an extra 32k or more out of your end user's 64megs of
+// ram on Windows 98 is Not a Good Thing.
+//
+// Now, as a ADDED BONUS at NO EXTRA COST TO YOU! Under VC6, using the /merge:.text=.data
+// pragma will cause the output file to be un-disassembleable! (is that a word?) At least,
+// with the normal tools - WinDisam, DumpBin, and the like will not work. Try it - use the
+// header, compile release, and then use DUMPBIN /DISASM filename.exe - no code!
+// Thanks to Gëzim Pani <gpani@siu.edu> for discovering this gem - for a full writeup on
+// this issue and the ramifactions of it, visit www.nopcode.com for the Aggressive Optimize
+// article.
+
+#ifndef _AGGRESSIVEOPTIMIZE_H_
+#define _AGGRESSIVEOPTIMIZE_H_
+
+#pragma warning(disable:4711)
+
+#ifdef NDEBUG
+// /Og (global optimizations), /Os (favor small code), /Oy (no frame pointers)
+#pragma optimize("gsy",on)
+
+#if (_MSC_VER<1300)
+ #pragma comment(linker,"/RELEASE")
+#endif
+
+// Note that merging the .rdata section will result in LARGER exe's if you using
+// MFC (esp. static link). If this is desirable, define _MERGE_RDATA_ in your project.
+#ifdef _MERGE_RDATA_
+#pragma comment(linker,"/merge:.rdata=.data")
+#endif // _MERGE_RDATA_
+
+#pragma comment(linker,"/merge:.text=.data")
+#if (_MSC_VER<1300)
+ // In VC7, this causes problems with the relocation and data tables, so best to not merge them
+ #pragma comment(linker,"/merge:.reloc=.data")
+#endif
+
+// Merging sections with different attributes causes a linker warning, so
+// turn off the warning. From Michael Geary. Undocumented, as usual!
+#if (_MSC_VER<1300)
+ // In VC7, you will need to put this in your project settings
+ #pragma comment(linker,"/ignore:4078")
+#endif
+
+// With Visual C++ 5, you already get the 512-byte alignment, so you will only need
+// it for VC6, and maybe later.
+#if _MSC_VER >= 1000
+
+// Option #1: use /filealign
+// Totally undocumented! And if you set it lower than 512 bytes, the program crashes.
+// Either leave at 0x200 or 0x1000
+//#pragma comment(linker,"/FILEALIGN:0x200")
+
+// Option #2: use /opt:nowin98
+// See KB:Q235956 or the READMEVC.htm in your VC directory for info on this one.
+// This is our currently preferred option, since it is fully documented and unlikely
+// to break in service packs and updates.
+#if (_MSC_VER<1300)
+ // In VC7, you will need to put this in your project settings
+ #pragma comment(linker,"/opt:nowin98")
+#else
+
+// Option #3: use /align:4096
+// A side effect of using the default align value is that it turns on the above switch.
+// Does nothing under Vc7 that /opt:nowin98 doesn't already give you
+// #pragma comment(linker,"/ALIGN:512")
+#endif
+
+#endif // _MSC_VER >= 1000
+
+#endif // NDEBUG
+
+#endif // _AGGRESSIVEOPTIMIZE_H_
diff --git a/plugins/SmartAutoAway/aa_utils.cpp b/plugins/SmartAutoAway/aa_utils.cpp
new file mode 100644
index 0000000000..c759cff91c
--- /dev/null
+++ b/plugins/SmartAutoAway/aa_utils.cpp
@@ -0,0 +1,396 @@
+#include "globals.h"
+
+
+//Proto_Status2Flag
+
+ int OldIndexToStatus(int oldIndex){
+ switch (oldIndex){
+ case 0 : return ID_STATUS_AWAY;
+ case 1 : return ID_STATUS_DND;
+ case 2 : return ID_STATUS_NA;
+ case 3 : return ID_STATUS_OCCUPIED;
+ case 4 : return ID_STATUS_INVISIBLE;
+ case 5 : return ID_STATUS_ONTHEPHONE;
+ case 6 : return ID_STATUS_OUTTOLUNCH;
+ case 7 : return ID_STATUS_ONLINE;
+ case 8 : return ID_STATUS_FREECHAT;
+ case 9 : return ID_STATUS_OFFLINE;
+ }
+ return 0;
+}
+ int StatusToOldIndex(int status){
+ switch (status){
+ case ID_STATUS_AWAY : return 0;
+ case ID_STATUS_DND : return 1;
+ case ID_STATUS_NA : return 2;
+ case ID_STATUS_OCCUPIED : return 3;
+ case ID_STATUS_INVISIBLE : return 4;
+ case ID_STATUS_ONTHEPHONE : return 5;
+ case ID_STATUS_OUTTOLUNCH : return 6;
+ case ID_STATUS_ONLINE : return 7;
+ case ID_STATUS_FREECHAT : return 8;
+ case ID_STATUS_OFFLINE : return 9;
+ }
+ return 0;
+}
+
+ unsigned long SetBits (unsigned long target,unsigned long mask,unsigned long value)
+{
+ int shift = 0;
+ unsigned long t;
+ while (!((mask>>shift)&1)) {
+ shift++;
+ }
+ t = mask ^ 0xFFFFFFFF;
+ target = target & t;
+ value = value<<shift;
+ target = target | (value&mask);
+ return target;
+}
+
+ unsigned long GetBits (unsigned long source,unsigned long mask)
+{
+ int shift = 0;
+ unsigned long t;
+ while (!((mask>>shift)&1)) {
+ shift++;
+ }
+ t = source & mask;
+ return t >> shift;
+}
+
+BOOL isInterestingProto(int j){
+ if ( proto[j]->type != PROTOTYPE_PROTOCOL ) return 0;
+ if (protoModes[j] > 1) return 1;
+ else return 0;
+ }
+
+ BOOL IsStatusBitSet(int status, int bits){
+ int i=0;
+ int mask=1;
+ for (i = numStatuses-1; i>=0; i--){
+ if (aa_Status[i]==status) return (mask & bits);
+ mask <<= 1;
+ }
+ return 0;
+}
+
+ int StatusByProtoIndex(int modes, int index){
+ int i=0;
+ int indexcount=0;
+ int mask = (1<<(numStatuses-1));
+ for (i = 0; i < numStatuses ; i++){
+ BOOL isset = (modes & mask);
+ if (isset) {
+ indexcount++;
+ if (indexcount==index) return aa_Status[i];
+ }
+ mask >>= 1;
+ }
+ return 0;
+}
+
+ int StatusToProtoIndex(int status, int modes){
+ int i=0;
+ int indexcount=0;
+ int mask = (1<<(numStatuses-1));
+ for (i = 0; i < numStatuses ; i++){
+ BOOL isset = (modes & mask);
+ if (isset) {
+ indexcount++;
+ if (status==aa_Status[i]) return indexcount;
+ }
+ mask >>= 1;
+ }
+ return 0;
+
+}
+ BOOL StrikeOut(HWND hWnd, int item, BOOL striked)
+{
+ LOGFONT lf;
+ HFONT hFont;
+ BOOL previous;
+
+ hFont = (HFONT)SendDlgItemMessage(hWnd, item, WM_GETFONT, 0, 0);
+ GetObject(hFont, sizeof(lf), &lf);
+ previous = lf.lfItalic;
+ lf.lfItalic = striked;
+ SendDlgItemMessage(hWnd, item, WM_SETFONT, (WPARAM)CreateFontIndirect(&lf), TRUE);
+ return previous;
+}
+
+ int GetCourSelProtocol(int sel){
+ int j;
+ int protoindex=0;
+ int selectedProto = 0;
+ for (j = 0 ; j < protoCount ; j++) {
+ if ( !isInterestingProto(j) ) continue;
+ {
+ if (protoindex==(sel)){
+ return j;
+ }
+ }
+ protoindex++;
+ }
+ return -1;
+}
+
+LRESULT SetDlgItems(HWND hwndDlg, int coursel)
+{
+ SendDlgItemMessage(hwndDlg, IDC_REQSTATUSLABEL, WM_SETTEXT, 0,(LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)reqStatus[coursel], GCMDF_TCHAR));
+ SendDlgItemMessage(hwndDlg, IDC_COURSTATUSLABEL, WM_SETTEXT, 0,(LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courStatus[coursel], GCMDF_TCHAR));
+ return TRUE;
+}
+
+int GetReconnectDelayFromSlider(int slide)
+{
+ if (slide < 4) return 6+slide;
+ else if (slide < 29) return 2+slide* 2;
+ else if (slide < 53) return -85+slide* 5;
+ else if (slide < 65) return -350+slide*10;
+ else if (slide < 85) return-1650+slide*30;
+ else return -4200+slide*60;
+}
+
+int GetSliderFromReconnectDelay(int delay)
+{
+ if (delay< 6) return 0;
+ else if (delay< 10) return -6+delay;
+ else if (delay< 60) return -1+delay/ 2;
+ else if (delay< 180) return 17+delay/ 5;
+ else if (delay< 300) return 35+delay/10;
+ else if (delay< 900) return 55+delay/30;
+ else if (delay<1800) return 70+delay/60;
+ else return 100;
+}
+BOOL GetStringFromDelay(TCHAR * str, int delay)
+{
+ int min,sec;
+ min = (int)delay/60;
+ sec = delay-min*60;
+ int pos = _stprintf(str,_T("%s "), TranslateT("Reconnect after"));
+ if (min) pos += _stprintf(&str[pos],_T("%d %s "),min,TranslateT("min"));
+ if (sec) pos += _stprintf(&str[pos],_T("%d %s"),sec,TranslateT("sec"));
+// if (!min) sprintf(str,"%s (Too fast!)",str);
+ return (delay<60);
+}
+
+
+void GetLastActiveLocalTime(SYSTEMTIME * at, unsigned long Seconds){
+ FILETIME ft;
+ ULARGE_INTEGER t;
+
+ GetSystemTimeAsFileTime(&ft);
+ t.u.LowPart = ft.dwLowDateTime;
+ t.u.HighPart = ft.dwHighDateTime;
+ t.QuadPart -= (__int64)Seconds*10000000;
+ ft.dwLowDateTime = t.u.LowPart;
+ ft.dwHighDateTime = t.u.HighPart;
+ FileTimeToSystemTime(&ft,at);
+ SystemTimeToTzSpecificLocalTime(NULL,at,at);
+}
+
+int GetTimeZone(TCHAR * name){
+ TIME_ZONE_INFORMATION tzi={0};
+ DWORD dwSta;
+
+ dwSta= GetTimeZoneInformation( &tzi );
+ switch (dwSta) {
+ case 0:
+ case TIME_ZONE_ID_STANDARD:
+#ifdef UNICODE
+ wcscpy(name,tzi.StandardName);
+#else
+ _stprintf(name,_T("%S"),tzi.StandardName);
+#endif
+ return -(tzi.Bias+tzi.StandardBias);
+ break;
+ case TIME_ZONE_ID_DAYLIGHT:
+#ifdef UNICODE
+ wcscpy(name,tzi.DaylightName);
+#else
+ _stprintf(name,_T("%S"),tzi.DaylightName);
+#endif
+ return -(tzi.Bias+tzi.DaylightBias);
+ break;
+ case TIME_ZONE_ID_INVALID:
+ default:
+ name[0] = 0;
+ return 0;
+ break;
+ }
+}
+void my_u2a(const TCHAR* src, char * target, unsigned int max){
+#ifdef UNICODE
+ int r = WideCharToMultiByte(codePage, 0, src, -1, target, max, NULL, NULL );
+ /*if (!r){
+ int err=GetLastError();
+ WCHAR errBuf[1024];
+ int p = wsprintf(errBuf,L"Error %u: \n",err);
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ err,
+ 0,
+ &errBuf[p],
+ 1024-p-1,
+ NULL);
+ MessageBoxW(NULL, errBuf, L"Error u2a", MB_OK);
+ }*/
+#else
+ strncpy(target,src,max);
+#endif
+ target[ max ] = 0;
+}
+
+void my_a2u(const char* src, TCHAR * target, unsigned int max){
+#ifdef UNICODE
+ int r = MultiByteToWideChar(codePage, 0, src, -1, target, max);
+#else
+ strncpy(target,src,max);
+#endif
+ target[ max ] = 0;
+}
+
+UINT ParseString(TCHAR *szstring,TCHAR *sztemp, unsigned int MaxOutLen)
+{
+ UINT loop=0;
+ TCHAR *weekdays[]={LPGENT("Sunday"),LPGENT("Monday"),LPGENT("Tuesday"),LPGENT("Wednesday"),LPGENT("Thursday"),LPGENT("Friday"),LPGENT("Saturday")};
+ TCHAR *wdays_short[]={LPGENT("Sun"),LPGENT("Mon"),LPGENT("Tue"),LPGENT("Wed"),LPGENT("Thu"),LPGENT("Fri"),LPGENT("Sat")};
+ TCHAR *monthnames[]={LPGENT("January"),LPGENT("February"),LPGENT("March"),LPGENT("April"),LPGENT("May"),LPGENT("June"),LPGENT("July"),LPGENT("August"),LPGENT("September"),LPGENT("October"),LPGENT("November"),LPGENT("December")};
+ TCHAR *mnames_short[]={LPGENT("Jan"),LPGENT("Feb"),LPGENT("Mar"),LPGENT("Apr"),LPGENT("May"),LPGENT("Jun"),LPGENT("Jul"),LPGENT("Aug"),LPGENT("Sep"),LPGENT("Oct"),LPGENT("Nov"),LPGENT("Dec")};
+ SYSTEMTIME st = {0};
+ BOOL stFilled = FALSE;
+ BOOL tzFilled = FALSE;
+ TCHAR tzName[128];
+ int tzDrift;
+ *sztemp = '\0';
+ UINT inpLen=_tcsclen(szstring);
+ UINT pos=0;
+ for(loop=0;loop<inpLen && pos<=MaxOutLen;loop++)
+ {
+ int res=0;
+ if(szstring[loop]!='%')
+ {
+ res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%c"),szstring[loop]);
+ }
+
+ else
+ {
+ switch(szstring[++loop]){
+ case 'Y':
+ case 'y':
+ case 'm':
+ case 'd':
+ case 'W':
+ case 'w':
+ case 'E':
+ case 'e':
+ case 'H':
+ case 'h':
+ case 'p':
+ case 'M':
+ case 'S':
+ case 'L':
+ case 'l':
+ case 'K':
+ case 'k':
+ if (!stFilled) {
+ GetLastActiveLocalTime(&st,secondsAfterLastActivity);
+ stFilled = TRUE;
+ }
+ switch (szstring[loop]){
+ case 'Y':
+ res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%04i"),st.wYear);
+ break;
+ case 'y':
+ res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%02i"),div(st.wYear,100).rem);
+ break;
+ case 'm':
+ res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%02i"),st.wMonth);
+ break;
+
+ case 'd':
+ res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%02i"),st.wDay);
+ break;
+
+ case 'W':case 'w':
+ res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%s"),TranslateTS((szstring[loop]=='W')?weekdays[st.wDayOfWeek]:wdays_short[st.wDayOfWeek]));
+ break;
+
+ case 'E':case 'e':
+ res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%s"),TranslateTS((szstring[loop]=='E')?monthnames[st.wMonth-1]:mnames_short[st.wMonth-1]));
+ break;
+
+ case 'H':
+ res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%02i"),st.wHour);
+ break;
+
+ case 'h':
+ res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%i"),(st.wHour)?(st.wHour-((st.wHour>12)?12:0)):12);
+ break;
+
+ case 'p':
+ res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%s"),TranslateTS((st.wHour>12)?_T("PM"):_T("AM")));
+ break;
+
+ case 'M':
+ res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%02i"),st.wMinute);
+ break;
+
+ case 'S':
+ res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%02i"),st.wSecond);
+ break;
+
+ case 'L':
+ case 'l':
+ case 'K':
+ case 'k':
+ {
+ switch (szstring[loop]){
+ case 'L':
+ case 'l':
+ res = GetDateFormat(localeID, szstring[loop]=='L'?DATE_LONGDATE:DATE_SHORTDATE, &st, NULL, &sztemp[pos], MaxOutLen-pos);
+ break;
+ case 'K':
+ case 'k':
+ res = GetTimeFormat(localeID, szstring[loop]=='K'?0:TIME_NOSECONDS, &st, NULL, &sztemp[pos], MaxOutLen-pos);
+ default:
+ break;
+ }
+ if (res>0) res--;
+ else res=0;
+ } break;
+ default:
+ break;
+ }
+ break;
+ case 'z': case 'Z':
+ if (!tzFilled) {
+ tzDrift = GetTimeZone(tzName);
+ tzFilled = TRUE;
+ }
+ if (szstring[loop]=='Z') res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%s"),tzName);
+ else {
+ res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%02d:%02d"),div(tzDrift,60).quot,tzDrift<0?-div(tzDrift,60).rem:div(tzDrift,60).rem);
+ }
+ break;
+ case 'b':
+ res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("\x0D\x0A"));
+ break;
+ case 't':
+ res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%c"),_T('\t'));
+ break;
+ default:
+ res = _sntprintf(&sztemp[pos],MaxOutLen-pos,_T("%%%c"),szstring[loop]);
+ break;
+ }
+ }
+ if (res<0) break;
+ else pos += res;
+ }
+ //sztemp[MaxOutLen]=sztemp[pos]=0; // Just in case
+ return pos;
+}
+
+
+
diff --git a/plugins/SmartAutoAway/autoaway.cpp b/plugins/SmartAutoAway/autoaway.cpp
new file mode 100644
index 0000000000..18754df9d2
--- /dev/null
+++ b/plugins/SmartAutoAway/autoaway.cpp
@@ -0,0 +1,662 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "globals.h"
+
+
+// globals
+//static HANDLE AutoAwayEventHandle = NULL;
+//static HANDLE StatusModeChangeEventHandle = NULL;
+//static HANDLE ProtoAckEventHandle = NULL;
+//static HANDLE AutoAwayShutdownHandle = NULL;
+//static HANDLE AutoAwayOptInitialiseHandle = NULL;
+
+
+//#define AA_LASTSTATUS "LastStatus_"
+//#define AA_ONLYIF "OnlyIf"
+//#define AA_ONLYIF2 "OnlyIf2"
+
+//#define ME_IDLE_CHANGED "Miranda/SmartIdle/Changed"
+//static HANDLE hIdleEvent = NULL;
+
+
+#define allprotomodes 0x03FF //0000 0011 1111 1111;
+#define aa_OnlyIfBitsDefault 0x01BB01B8 //2 x 0000 0001 1011 1011;
+ //1111 0000 0000 0000;
+//#define known 0x8000 //1000 0000 0000 0000;
+
+
+
+
+//static int aa_OnlyIfDefaults[] = {2,2,2,2,1,2,2,2,2,1};
+
+extern unsigned long lastIdleEventTime;
+
+
+int AutoAwayOptInitialise(WPARAM wParam,LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp;
+
+ ZeroMemory(&odp,sizeof(odp));
+ odp.cbSize=sizeof(odp);
+ odp.position=1000000000;
+#ifdef SAA_PLUGIN
+ odp.hInstance=g_hInst;
+#else
+ odp.hInstance=GetModuleHandle(NULL);
+#endif
+ odp.pszTemplate=MAKEINTRESOURCEA(IDD_OPT_SMARTAUTOAWAY);
+ odp.pszTitle=SECTIONNAME;
+ odp.pszGroup="Status";
+ odp.pfnDlgProc=DlgProcAutoAwayOpts;
+ odp.flags=ODPF_BOLDGROUPS;
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+ return 0;
+}
+
+static short int curIdleStatus = -1; //0: NotIdle, 1: Short Idle, 2: Long Idle, -1 Not init yet: Will be inited on AutoAwayEvent;
+int AutoAwayEvent(WPARAM wParam, LPARAM lParam)
+{
+// char str[MAXMODULELABELLENGTH];
+//#define IDF_ISIDLE 0x1 // idle has become active (if not set, inactive)
+//#define IDF_SHORT 0x2 // short idle mode
+//#define IDF_LONG 0x4 // long idle mode
+//#define IDF_PRIVACY 0x8 // if set, the information provided shouldn't be given to third parties.
+//#define IDF_ONFORCE 0x10 // screensaver/onstationlocked,etc cause instant idle
+
+ int j;
+
+#ifdef AALOG
+ {
+ char log[1024]="";
+ sprintf(log,"IdleEvent came: %sdle;%s%s%s%sorced.",
+ lParam & IDF_ISIDLE?"I":"Not i",
+ lParam & IDF_SHORT?" Short;":"",
+ lParam & IDF_LONG?" Long;":"",
+ lParam & IDF_PRIVACY?" Private;":"",
+ lParam & IDF_ONFORCE?" F":"Not f");
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+ {
+ MIRANDA_IDLE_INFO mii;
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ if (CallService(MS_IDLE_GETIDLEINFO, 0, (LPARAM)&mii)==0){
+ sprintf(log,"IdleInfo valid: IdleTime:%d; %srivate; Status: %s(%d); aaLock: %s.",
+ mii.idleTime,
+ mii.privacy?"P":"Not p",
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)mii.aaStatus, 0),
+ mii.aaStatus,
+ mii.aaLock?"Yes":"No");
+ } else {
+ sprintf(log,"IdleInfo Failed: Size: %d; IdleTime: %d.",mii.cbSize,mii.idleTime);
+ }
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+ }
+ }
+#endif
+ if ( lParam & IDF_ISIDLE ) { //going to sleep...
+ if ( lParam & IDF_LONG ) { //... deeply
+ if (curIdleStatus > 1) return 0; // we are already deeply sleeping...
+ curIdleStatus = 2;
+ } else { //... lite if IDF_LONG is not set
+ if (curIdleStatus > 0) return 0; // we are already sleeping...
+ curIdleStatus = 1;
+ }
+ } else { // we are going to awake
+ if (curIdleStatus == 0) return 0; // we are already awake...
+ curIdleStatus = 0;
+ }
+ if (!starting){
+ lastIdleEventTime = time(NULL)-secondsAfterLastActivity;
+ if ((idleOptsPerm&IdleSuppressAutoHere)!=0) {
+ DBWriteContactSettingByte(NULL,AA_MODULE,AA_LASTIDLESTATUS,(BYTE)curIdleStatus);
+ DBWriteContactSettingDword(NULL,AA_MODULE,AA_LASTIDLETIME,(DWORD)lastIdleEventTime);
+ } }
+ switch (curIdleStatus) {
+ case 0:
+ xModifyMenu(0,CMIF_CHECKED);
+ xModifyMenu(1,0);
+ xModifyMenu(2,0);
+ break;
+ case 1:
+ xModifyMenu(0,0);
+ xModifyMenu(1,CMIF_CHECKED);
+ xModifyMenu(2,0);
+ break;
+ case 2:
+ xModifyMenu(0,0);
+ xModifyMenu(1,CMIF_GRAYED);
+ xModifyMenu(2,CMIF_CHECKED);
+ break;
+ }
+
+ for (j = 0 ; j < protoCount ; j++) {
+ if ( proto[j]->type != PROTOTYPE_PROTOCOL ) continue;
+ { //status mode change
+ int newStatus = 0;
+ int reqStatusInd = numStatuses-StatusToProtoIndex(reqStatus[j],allprotomodes);
+ bool isStatusLocked = DBGetContactSettingByte( NULL, proto[j]->szName, , "LockMainStatus", 0 ) != 0;
+ if (isStatusLocked) newStatus = reqStatus[j];
+ else switch (curIdleStatus) {
+ case 1 : { //sleeping lite
+ if ( GetBits(awayStatusesPerm[j],maskIsShortAwayEnabled)){
+ int bits = 1<<(reqStatusInd);
+ BOOL permit = GetBits(onlyIfBitsPerm[j], bits);
+ if ( permit ) {
+ // get the index of the status we should use
+ newStatus = aa_Status[GetBits(awayStatusesPerm[j],maskShortAwayStatus)-1];
+ } else {
+#ifdef AALOG
+ {
+ char log[1024] ;
+ sprintf(log,"%s: Status Change to short idle was not permitted",proto[j]->szName,0);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+ }
+#endif
+ continue;
+ }
+
+ } else continue;
+ break;
+ }
+ case 2 : { //sleeping deeply
+ if ( GetBits(awayStatusesPerm[j],maskIsLongAwayEnabled) ) {
+ int bits = 1<<(reqStatusInd+16);
+ BOOL permit = GetBits(onlyIfBitsPerm[j], bits);
+ if ( permit ) {
+ // get the index of the status we should use
+ newStatus = aa_Status[GetBits(awayStatusesPerm[j],maskLongAwayStatus)-1];
+ } else {
+#ifdef AALOG
+ {
+ char log[1024] ;
+ sprintf(log,"%s: Status Change to long idle was not permitted",proto[j]->szName,0);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+ }
+#endif
+ continue;
+ }
+ } else continue;
+ break;
+ }
+ case 0: { //wakening up
+ newStatus = reqStatus[j];
+#ifdef AALOG
+ {
+ char str[256];
+ sprintf(str,"%s WakeningUp: %s",proto[j]->szName,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0));
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+ }
+#endif
+ break;
+ }
+ } // switch
+ if (newStatus){
+ courAwayStatus[j] = newStatus;
+ //FatalError? and "dontReconnectOnFatalError"? and we are not just awaken
+#ifdef AALOG
+ {
+ char str[1000];
+ sprintf(str,"%s: Reconnect conditions before change status to %s(%d) are: FatalError did%s happen; DontReconnectOnFatalError is %sabled and we are going to %s.",
+ proto[j]->szName,
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0),newStatus,
+ (protoStatus[j]&2)?"":"n't",
+ (reconnectOptsPerm[j]&aa_ReconnectNotFatalError)?"En":"Dis",
+ (curIdleStatus==1)?"take a short nap":((curIdleStatus==2)?"sleep":"awake"));
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+ }
+#endif
+ if ((protoStatus[j]&2)&&
+ (reconnectOptsPerm[j]&aa_ReconnectNotFatalError)&&
+ (curIdleStatus>0)) {
+ // do nothing :) but only the log, eventualy
+#ifdef AALOG
+ char str[1000];
+ sprintf(str,"%s: we will not change the status to %s(%d).",
+ proto[j]->szName,
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0),newStatus);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ } else {
+#ifdef AALOG
+ char str[1000];
+ sprintf(str,"%s: we will change the status to %s(%d).",
+ proto[j]->szName,
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0),newStatus);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ if ( CallProtoService(proto[j]->szName, PS_GETSTATUS, 0, 0) != newStatus ) {
+ //if (DBGetContactSettingByte( NULL, proto[j]->szName, , "LockMainStatus", 0 ))
+ // continue; //szName
+
+ CallProtoService(proto[j]->szName, PS_SETSTATUS, newStatus, 0);
+#ifdef AALOG
+ } else {
+ char str[256];
+ sprintf(str,"%s: %s already set",proto[j]->szName,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0));
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ }
+ }
+ if (isStatusLocked) {
+ // do nothing - log only
+#ifdef AALOG
+ char str[1000];
+ sprintf(str,"%s: Protocol Locked to %s(%d). Not touching StatusMessage",
+ proto[j]->szName,
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0),newStatus);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ } else if (messCaps[j] && !(lParam&IDF_PRIVACY)){//setting the statusMessage if protocol supports AND privacy is disabled
+ TCHAR * awayMsg=0;
+ int specificMsg = messCaps[j] & Proto_Status2Flag(newStatus);
+
+ switch (curIdleStatus) {
+ case 0 : specificMsg = (specificMsg > 0) && (GetBits(idleMessOpts[j],IdleMessOptsMaskUseHere)>0); break;
+ case 1 : specificMsg = (specificMsg > 0) && (GetBits(idleMessOpts[j],IdleMessOptsMaskUseShort)>0); break;
+ case 2 : specificMsg = (specificMsg > 0) && (GetBits(idleMessOpts[j],IdleMessOptsMaskUseLong)>0); break;
+ }
+ if (/*!starting &&*/ specificMsg){
+ awayMsg = (TCHAR *)mir_alloc((maxMessageLength+1)*sizeof(TCHAR));
+ //TCHAR temp[maxMessageLength+1];
+ switch (curIdleStatus) {
+ case 0 : ParseString(mesgHerePerm[j],awayMsg,maxMessageLength); break;
+ case 1 : ParseString(mesgShortPerm[j],awayMsg,maxMessageLength); break;
+ case 2 : ParseString(mesgLongPerm[j],awayMsg,maxMessageLength); break;
+ default: awayMsg[0]=0;
+ }
+ //my_u2a(temp, awayMsg, maxMessageLength);
+ } else {
+#ifdef UNICODE
+ if (HasAwayMessageW){
+ awayMsg = (TCHAR *) CallService(MS_AWAYMSG_GETSTATUSMSGW, (WPARAM) newStatus, 0);
+ } else {
+ char *temp=(char *)CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) newStatus, 0);
+ if ((int)temp == CALLSERVICE_NOTFOUND) awayMsg = 0;
+ else{
+ awayMsg = (TCHAR *)mir_alloc((maxMessageLength+1)*sizeof(TCHAR));
+ my_a2u(temp,awayMsg,maxMessageLength);
+ mir_free(temp);
+ }
+ }
+#else
+ char *temp=(char *)CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) newStatus, 0);
+ awayMsg=(char *)CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) newStatus, 0);
+ if ((int)temp == CALLSERVICE_NOTFOUND) awayMsg = 0;
+#endif
+ }
+#ifdef AALOG
+ {
+ char str[1000];
+ sprintf(str,"%s: Specific Status Message is %s",proto[j]->szName,
+ specificMsg?"Enabled":"Disabled");
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+ sprintf(str,"%s: Going to %s (%d); StatusMessage is: %s", proto[j]->szName,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, newStatus, 0),newStatus,
+ awayMsg ? awayMsg : "none or private");
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+ }
+#endif
+#ifdef UNICODE
+ if (protoHasAwayMessageW[j]) CallProtoService(proto[j]->szName, PS_SETAWAYMSGW, newStatus, (LPARAM) awayMsg);
+ else {
+ char temp[maxMessageLength+1];
+ my_u2a(awayMsg,temp,maxMessageLength);
+ CallProtoService(proto[j]->szName, PS_SETAWAYMSG, newStatus, (LPARAM) temp);
+ }
+#else
+ CallProtoService(proto[j]->szName, PS_SETAWAYMSG, newStatus, (LPARAM) awayMsg);
+#endif
+ if (awayMsg) {
+#ifdef AALOG
+ {char str[1000];
+ sprintf(str,"%s: Cleaning after MS_AWAYMSG_GETSTATUSMSG: %s",proto[j]->szName,awayMsg);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);}
+#endif
+ mir_free(awayMsg);
+ }
+ if ((curIdleStatus==0) && (GetBits(idleMessOpts[j],IdleMessOptsMaskRstHere)>0) && /*!starting &&*/ specificMsg){
+#ifdef AALOG
+ char str[1000];
+ sprintf(str,"%s: Scheduling \"ResetDefaultStatusMessage\" after %d seconds",proto[j]->szName,GetBits(idleMessOpts[j],IdleMessOptsMaskRstHereDelay));
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ isWaitingForRestoreStatusMessage[j] = GetBits(idleMessOpts[j],IdleMessOptsMaskRstHereDelay)/2+1;
+ }
+ }
+ }//if
+ } //StatusChange Was done
+ } //for
+ if (starting) {
+#ifdef AALOG
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"Clearing the \"starting\" flag...");
+#endif
+ starting = 0;
+ }
+ return 0;
+}
+
+
+
+extern int StatusModeChangeEvent(WPARAM wParam,LPARAM lParam)
+{
+ int j=0;
+ char str[256];
+
+#ifdef AALOG
+ {
+ char log[1024];
+ sprintf(log,"Status Mode change event: %s: %s\n\n",lParam,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, wParam, 0));
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+ }
+#endif
+ if (lParam){
+ for (j = 0 ; j < protoCount ; j++) {
+ if ( proto[j]->type != PROTOTYPE_PROTOCOL ) continue;
+ if (strcmp((char *)lParam,proto[j]->szName)==0) {
+ sprintf(str,AA_LASTREQUESTEDSTATUS,proto[j]->szName);
+ reqStatus[j] = wParam;
+ DBWriteContactSettingWord(NULL,AA_MODULE,str,(WORD)reqStatus[j]);
+ }
+ }
+ } else {
+ if (idleOptsPerm&KeepMainStatusOffline) {
+#ifdef AALOG
+ {
+ char log[1024];
+ sprintf(log,"Global Status Mode change event: %s. Keep it offline!",CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, wParam, 0));
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+ }
+#endif
+ DBWriteContactSettingWord(NULL,"CList","Status",(WORD)ID_STATUS_OFFLINE);
+ }
+ if (starting && (wParam == ID_STATUS_OFFLINE)){
+#ifdef AALOG
+ {
+ char log[1024];
+ sprintf(log,"Do not set last request status to %s. We are still starting.",CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, wParam, 0));
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+ }
+#endif
+ } else for (j = 0 ; j < protoCount ; j++) {
+ if ( proto[j]->type != PROTOTYPE_PROTOCOL ) continue;
+ sprintf(str,AA_LASTREQUESTEDSTATUS,proto[j]->szName);
+ reqStatus[j] = wParam;
+ DBWriteContactSettingWord(NULL,AA_MODULE,str,(WORD)reqStatus[j]);
+ }
+ }
+#ifdef AALOG
+ {
+ char log[1024] = {0};
+ for (j = 0 ; j < protoCount ; j++) {
+ sprintf(log,"%s%d:%s: %s\n",log,j,proto[j]->szName,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, reqStatus[j], 0));
+ }
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"Status Mode change event: done");
+ }
+#endif
+ if (idleOptsPerm&IdleHereOnStatusChange){
+ if (curIdleStatus){
+ if (wParam!=ID_STATUS_OFFLINE){
+#ifdef AALOG
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"New requested status. Forcing ""Not Idle"".");
+#endif
+ SimulateIdle(0);
+ }
+ }
+ }
+
+// CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"Keeping Last Requested statuses");
+ if (theDialog) SetDlgItems(theDialog, courProtocolSelection);
+ if (theDialogIdleMessages) SetDlgItemsIdleMessages(theDialogIdleMessages, courProtocolSelection);
+ return 0;
+}
+
+
+
+int ProtoAckEvent(WPARAM wParam,LPARAM lParam)
+{
+#ifdef AALOG
+ char log[2048];
+#endif
+ char str[1024];
+ int j = 0;
+ ACKDATA * ack = (ACKDATA*) lParam;
+ for (j = 0 ; j < protoCount ; j++) if (proto[j]->type==PROTOTYPE_PROTOCOL) if (strcmp(ack->szModule,proto[j]->szName)==0){
+ if (ack->type==ACKTYPE_STATUS) {
+// MessageBox( 0,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->lParam, 0),proto[j]->szName,0);
+ if (!(ack->hContact)) ProtocolsProc(j,ack);
+ if (ack->result==ACKRESULT_SUCCESS){
+ courStatus[j] = ack->lParam;
+ if (theDialog){
+ int coursel = SendDlgItemMessage(theDialog, IDC_AAPROTOCOL, CB_GETCURSEL, 0, 0);
+ SendDlgItemMessageA(theDialog,IDC_AAPROTOCOL,CB_GETLBTEXT,coursel,(LPARAM)str);
+ if (strcmp(ack->szModule,str)==0){
+ SetDlgItems(theDialog,GetCourSelProtocol(coursel));
+// SendDlgItemMessage(theDialog, IDC_COURSTATUSLABEL, WM_SETTEXT, 0,
+// (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courStatus[j], 0));
+ }
+ }
+ }
+ } else if (ack->type==ACKTYPE_LOGIN) {
+ if (!ack->hContact) LoginAck(j,ack);
+ }
+ }
+
+#ifdef AALOG
+// if (theDialog) SendDlgItemMessage(theDialog, 40201, WM_SETTEXT, 0,(LPARAM)ack->szModule);
+ sprintf(log,"ProtoAck: szModule: %s;",ack->szModule);
+ sprintf(str,"%s",ack->hContact?(char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)ack->hContact,0):"null");
+ sprintf(log,"%s hContact: %s;",log,str);
+// if (theDialog) SendDlgItemMessage(theDialog, 40202, WM_SETTEXT, 0,(LPARAM)str);
+ sprintf(str,"%d",ack->type);
+ sprintf(log,"%stype: %s;",log,str);
+// if (theDialog) SendDlgItemMessage(theDialog, 40203, WM_SETTEXT, 0,str);
+ sprintf(str,"%d",ack->result);
+ sprintf(log,"%s result: %s;",log,str);
+// if (theDialog) SendDlgItemMessage(theDialog, 40204, WM_SETTEXT, 0,str);
+ sprintf(str,"%d(%s)",ack->hProcess,
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->hProcess, 0));
+ sprintf(log,"%s hProcess: %s;",log,str);
+// if (theDialog) SendDlgItemMessage(theDialog, 40205, WM_SETTEXT, 0,str);
+ sprintf(str,"%d(%s)",ack->lParam,
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->lParam, 0));
+ sprintf(log,"%s lParam: %s;",log,str);
+// if (theDialog) SendDlgItemMessage(theDialog, 40206, WM_SETTEXT, 0,str);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+#endif
+ return 0;
+}
+
+
+int SimulateIdle(int idlstatus)
+{
+// MessageBox(theDialog,"ButtonPressed","Button",0);
+ int flags = IDF_ISIDLE;
+ switch (idlstatus)
+ {
+ case 0: {flags = 0;/*MessageBox(theDialog,"BeHere","Button Pressed",0);*/ break;}
+ case 1: {flags |= IDF_SHORT; /*MessageBox(theDialog,"BeAway","Button Pressed",0);*/ break;}
+ case 2: {flags |= IDF_LONG; /*MessageBox(theDialog,"BeNA","Button Pressed",0);*/ break;}
+ }
+ if (idleOptsPerm&IdleBitsPrivate) flags |= IDF_PRIVACY;
+ isCurrentlyIdle = idlstatus;
+ NotifyEventHooks( hIdleEvent, 0, flags );
+ return 0;
+}
+
+LRESULT SetDlgItemsAA(HWND hwndDlg, int coursel){
+ int status = awayStatuses[coursel];
+ long onlyif = onlyIfBits[coursel];
+ BOOL enabledShort = (status & maskIsShortAwayEnabled)>0;
+ BOOL enabledLong = (status & maskIsLongAwayEnabled)>0;
+ int i =0;
+ EnableWindow(GetDlgItem(hwndDlg, IDC_AASTATUS), enabledShort);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_AALONGSTATUS), enabledLong);
+ CheckDlgButton(hwndDlg, IDC_AASHORTIDLE, enabledShort?BST_CHECKED:BST_UNCHECKED );
+ CheckDlgButton(hwndDlg, IDC_AALONGIDLE, enabledLong?BST_CHECKED:BST_UNCHECKED );
+
+ SendDlgItemMessage(hwndDlg, IDC_AASTATUS, CB_RESETCONTENT, 0, 0);
+ SendDlgItemMessage(hwndDlg, IDC_AALONGSTATUS, CB_RESETCONTENT, 0, 0);
+ for (i=0;i<numStatuses;i++){
+ if (StatusToProtoIndex(aa_Status[i],protoModes[coursel])){
+ // short idle flags
+ SendDlgItemMessage(hwndDlg, IDC_AASTATUS, CB_ADDSTRING, 0, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)aa_Status[i], GCMDF_TCHAR) );
+ // long idle flags
+ SendDlgItemMessage(hwndDlg, IDC_AALONGSTATUS, CB_ADDSTRING, 0, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,(WPARAM)aa_Status[i], GCMDF_TCHAR) );
+ }
+ {
+ BOOL bits = IsStatusBitSet(aa_Status[i],onlyif)>0;
+ BOOL bitl = IsStatusBitSet(aa_Status[i],onlyif>>16)>0;
+ BOOL bita = IsStatusBitSet(aa_Status[i],protoModes[coursel])==0;
+ EnableWindow(GetDlgItem(hwndDlg, aa_Status[i]), enabledShort);
+ StrikeOut(hwndDlg,aa_Status[i],bita);
+ CheckDlgButton(hwndDlg, aa_Status[i], bits?BST_CHECKED:BST_UNCHECKED );
+ EnableWindow(GetDlgItem(hwndDlg, aa_Status[i]+0x10), enabledLong);
+ StrikeOut(hwndDlg,aa_Status[i]+0x10,bita);
+ CheckDlgButton(hwndDlg, aa_Status[i]+0x10, bitl?BST_CHECKED:BST_UNCHECKED );
+// ShowWindow(GetDlgItem(hwndDlg, aa_Status[i]), bita);
+// ShowWindow(GetDlgItem(hwndDlg, aa_Status[i]+0x10), bita);
+ }
+ }
+ {
+ int s = status & 0x000F;
+ int l = status & 0x00F0;
+ l = l>>4;
+ s = StatusToProtoIndex(aa_Status[s-1],protoModes[coursel]);
+ l = StatusToProtoIndex(aa_Status[l-1],protoModes[coursel]);
+ SendDlgItemMessage(hwndDlg, IDC_AASTATUS, CB_SETCURSEL, s-1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_AALONGSTATUS, CB_SETCURSEL, l-1, 0);
+ }
+ return TRUE;
+}
+
+BOOL CALLBACK DlgProcOptsAA(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ SetDlgItemsAA(hwndDlg, courProtocolSelection);
+ return TRUE;
+ case WM_USER+1:
+ {
+ awayStatuses[courProtocolSelection] = (short)SetBits(awayStatuses[courProtocolSelection],maskIsShortAwayEnabled,IsDlgButtonChecked(hwndDlg, IDC_AASHORTIDLE)==BST_CHECKED);
+ awayStatuses[courProtocolSelection] = (short)SetBits(awayStatuses[courProtocolSelection],maskIsLongAwayEnabled,IsDlgButtonChecked(hwndDlg, IDC_AALONGIDLE)==BST_CHECKED);
+ SetDlgItemsAA(hwndDlg, courProtocolSelection);
+ break;
+ }
+ case WM_USER+2:
+ {
+ int t = HIWORD(lParam)?16:0;
+ int thebit = numStatuses-StatusToProtoIndex(LOWORD(lParam),allprotomodes);
+ int value = IsDlgButtonChecked(hwndDlg, LOWORD(lParam)+t)==BST_CHECKED;
+ thebit = 1<<(thebit+t);
+ onlyIfBits[courProtocolSelection] =
+ SetBits(onlyIfBits[courProtocolSelection],
+ thebit,
+ value);
+ break;
+ }
+ case WM_USER+3:
+ {
+ int awStInd = SendDlgItemMessage(hwndDlg, lParam, CB_GETCURSEL, 0, 0);
+ awStInd = StatusByProtoIndex(protoModes[courProtocolSelection],awStInd+1);
+ awStInd = StatusToProtoIndex(awStInd,allprotomodes);
+ if (lParam == IDC_AASTATUS) {
+ awayStatuses[courProtocolSelection] = (short)SetBits(awayStatuses[courProtocolSelection],maskShortAwayStatus,awStInd);
+ } else if (lParam == IDC_AALONGSTATUS) {
+ awayStatuses[courProtocolSelection] = (short)SetBits(awayStatuses[courProtocolSelection],maskLongAwayStatus,awStInd);
+ }
+#ifdef _DEBUG
+ else MessageBoxA(hwndDlg,"Came From Long Place","WM_USER+3",0)
+#endif //_DEBUG
+ ;
+ SetDlgItemsIdleMessages(theDialogIdleMessages, courProtocolSelection);
+ break;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_AASHORTIDLE:
+ case IDC_AALONGIDLE:
+ {
+ SendMessage(hwndDlg, WM_USER+1,0,0);
+ break;
+ }
+ case ID_STATUS_AWAY:
+ case ID_STATUS_DND:
+ case ID_STATUS_NA:
+ case ID_STATUS_OCCUPIED:
+ case ID_STATUS_INVISIBLE:
+ case ID_STATUS_ONTHEPHONE:
+ case ID_STATUS_OUTTOLUNCH:
+ case ID_STATUS_ONLINE:
+ case ID_STATUS_FREECHAT:
+ case ID_STATUS_OFFLINE:
+ {
+ SendMessage(hwndDlg, WM_USER+2,0,wParam);
+ break;
+ }
+ case ID_STATUS_AWAY+16:
+ case ID_STATUS_DND+16:
+ case ID_STATUS_NA+16:
+ case ID_STATUS_OCCUPIED+16:
+ case ID_STATUS_INVISIBLE+16:
+ case ID_STATUS_ONTHEPHONE+16:
+ case ID_STATUS_OUTTOLUNCH+16:
+ case ID_STATUS_ONLINE+16:
+ case ID_STATUS_FREECHAT+16:
+ case ID_STATUS_OFFLINE+16:
+ {
+ SendMessage(hwndDlg, WM_USER+2,0,(wParam-16)|0x00010000);
+ break;
+ }
+ case IDC_AASTATUS:
+ case IDC_AALONGSTATUS:
+ {
+ if ( HIWORD(wParam) != CBN_SELCHANGE ) return TRUE;
+ SendMessage(hwndDlg, WM_USER+3,0,LOWORD(wParam));
+ break;
+ } //case
+ }
+ if ((HIWORD(wParam)==BN_CLICKED)||(HIWORD(wParam)==CBN_SELCHANGE))
+ {
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY: {
+ return TRUE;
+ }
+ }
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return FALSE;
+}
+
+
+
diff --git a/plugins/SmartAutoAway/dlgproc.cpp b/plugins/SmartAutoAway/dlgproc.cpp
new file mode 100644
index 0000000000..e37ce72ce9
--- /dev/null
+++ b/plugins/SmartAutoAway/dlgproc.cpp
@@ -0,0 +1,281 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "globals.h"
+
+BOOL CALLBACK DlgProcAutoAwayOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+// char str[MAXMODULELABELLENGTH];
+ static short int tabprotosel;
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ short int t,p,protoListed;
+ TCITEM tci;
+ RECT theTabSpace;
+ RECT rcClient;
+ {
+ RECT rcTab, rcDlg;
+ TabCtrl_GetItemRect(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB),0,&rcTab);
+ theTabSpace.top = rcTab.bottom; // the size of the tab
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB), &rcTab);
+ GetWindowRect(hwndDlg, &rcDlg);
+ theTabSpace.bottom = rcTab.bottom -rcTab.top -theTabSpace.top;
+ theTabSpace.top = rcTab.top -rcDlg.top +theTabSpace.top;
+ theTabSpace.left = rcTab.left - rcDlg.left;
+ theTabSpace.right = rcTab.right-rcTab.left;
+ }
+ theDialog = hwndDlg;
+ TranslateDialogDefault(hwndDlg);
+ protoListed = 0;
+ for (p = 0 ; p < protoCount ;p++) {
+ int caps=0;
+ if ( !isInterestingProto(p) ) continue;
+ caps = CallProtoService(proto[p]->szName, PS_GETCAPS, PFLAGNUM_2, 0);
+ PROTOACCOUNT* protoAccount=ProtoGetAccount(proto[p]->szName);
+ if ((int)protoAccount!=CALLSERVICE_NOTFOUND){
+ SendDlgItemMessage(hwndDlg, IDC_AAPROTOCOL, CB_ADDSTRING, 0, (LPARAM)protoAccount->tszAccountName );
+ } else SendDlgItemMessageA(hwndDlg, IDC_AAPROTOCOL, CB_ADDSTRING, 0, (LPARAM)proto[p]->szName );
+ protoListed++;
+ }
+ tabprotosel = DBGetContactSettingWord(NULL, AA_MODULE, AA_PROTOSELECTION, 0);
+ t = (tabprotosel&0x0F00) >> 8; if (t>3) t=3;
+ p = (tabprotosel&0x00FF);
+ if ((p>=protoListed)) p= protoListed-1;
+ SendDlgItemMessage(hwndDlg, IDC_AAPROTOCOL, CB_SETCURSEL, p, 0);
+ SetDlgItems(hwndDlg, courProtocolSelection = GetCourSelProtocol(p));
+
+ tci.mask = TCIF_PARAM|TCIF_TEXT;
+
+#ifdef SAA_PLUGIN
+ theDialogAA = CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_SAA_AA), hwndDlg, DlgProcOptsAA);
+#else
+ theDialogAA = CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_OPT_SAA_AA), hwndDlg, DlgProcOptsAA);
+#endif
+ tci.lParam = (LPARAM)theDialogAA;
+ tci.pszText = TranslateT("Statuses");
+ GetClientRect(theDialogAA,&rcClient);
+ SendMessage(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB), TCM_INSERTITEM, (WPARAM)0, (LPARAM)&tci);
+ MoveWindow((HWND)theDialogAA,theTabSpace.left+(theTabSpace.right-rcClient.right)/2,
+ theTabSpace.top+(theTabSpace.bottom-rcClient.bottom)/2,
+ rcClient.right,rcClient.bottom,1);
+ ShowWindow((HWND)tci.lParam, (t==0)?SW_SHOW:SW_HIDE);
+
+
+#ifdef SAA_PLUGIN
+ theDialogIdle = CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_SAA_IDLE), hwndDlg, DlgProcOptsIdle);
+#else
+ theDialogIdle = CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_OPT_SAA_IDLE), hwndDlg, DlgProcOptsIdle);
+#endif
+ tci.lParam = (LPARAM)theDialogIdle;
+ tci.pszText = TranslateT("Idle");
+ GetClientRect(theDialogIdle,&rcClient);
+ SendMessage(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB), TCM_INSERTITEM, (WPARAM)1, (LPARAM)&tci);
+ MoveWindow((HWND)theDialogIdle,theTabSpace.left+(theTabSpace.right-rcClient.right)/2,
+ theTabSpace.top+(theTabSpace.bottom-rcClient.bottom)/2,
+ rcClient.right,rcClient.bottom,1);
+ ShowWindow((HWND)tci.lParam, (t==1)?SW_SHOW:SW_HIDE);
+
+#ifdef SAA_PLUGIN
+ theDialogIdleMessages = CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_SAA_IDLEMESSAGES), hwndDlg, DlgProcOptsIdleMessages);
+#else
+ theDialogIdleMessages = CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_OPT_SAA_IDLEMESSAGES), hwndDlg, DlgProcOptsIdleMessages);
+#endif
+ tci.lParam = (LPARAM)theDialogIdleMessages;
+ tci.pszText = TranslateT("Status Messages");
+ GetClientRect(theDialogIdleMessages,&rcClient);
+ SendMessage(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB), TCM_INSERTITEM, (WPARAM)2, (LPARAM)&tci);
+ MoveWindow((HWND)theDialogIdleMessages,theTabSpace.left+(theTabSpace.right-rcClient.right)/2,
+ theTabSpace.top+(theTabSpace.bottom-rcClient.bottom)/2,
+ rcClient.right,rcClient.bottom,1);
+ ShowWindow((HWND)tci.lParam, (t==2)?SW_SHOW:SW_HIDE);
+
+#ifdef SAA_PLUGIN
+ theDialogReconnect = CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_OPT_SAA_RECONNECT), hwndDlg, DlgProcOptsReconnect);
+#else
+ theDialogReconnect = CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_OPT_SAA_RECONNECT), hwndDlg, DlgProcOptsReconnect);
+#endif
+ tci.lParam = (LPARAM)theDialogReconnect;
+ tci.pszText = TranslateT("Reconnect");
+ GetClientRect(theDialogReconnect,&rcClient);
+ SendMessage(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB), TCM_INSERTITEM, (WPARAM)3, (LPARAM)&tci);
+ MoveWindow((HWND)theDialogReconnect,theTabSpace.left+(theTabSpace.right-rcClient.right)/2,
+ theTabSpace.top+(theTabSpace.bottom-rcClient.bottom)/2,
+ rcClient.right,rcClient.bottom,1);
+ ShowWindow((HWND)tci.lParam, (t==3)?SW_SHOW:SW_HIDE);
+ TabCtrl_SetCurSel(GetDlgItem(hwndDlg, IDC_OPT_SAA_TAB),t);
+
+ if(enableThemeDialogTexture) {
+ enableThemeDialogTexture(theDialogAA, ETDT_ENABLETAB);
+ enableThemeDialogTexture(theDialogIdle, ETDT_ENABLETAB);
+ enableThemeDialogTexture(theDialogIdleMessages, ETDT_ENABLETAB);
+ enableThemeDialogTexture(theDialogReconnect, ETDT_ENABLETAB);
+ }
+ return TRUE;
+ }
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam)) {
+ case IDC_AAPROTOCOL:
+ {
+ int cour = SendDlgItemMessage(hwndDlg, IDC_AAPROTOCOL, CB_GETCURSEL, 0, 0);
+ courProtocolSelection = GetCourSelProtocol(cour);
+ if ( HIWORD(wParam) != CBN_SELCHANGE ) return TRUE;
+ DBWriteContactSettingWord(NULL, AA_MODULE, AA_PROTOSELECTION,
+ (unsigned short)(tabprotosel=courProtocolSelection|(tabprotosel&0xFF00)));
+ SetDlgItems(hwndDlg, courProtocolSelection);
+ SetDlgItemsReconnect(theDialogReconnect,courProtocolSelection);
+ SetDlgItemsAA(theDialogAA,courProtocolSelection);
+ SetDlgItemsIdleMessages(theDialogIdleMessages,courProtocolSelection);
+ break;
+ }
+ case IDC_APPLYTOALL:
+ {
+ int i;
+ for (i=0;i<protoCount;i++){
+ if (isInterestingProto(i)) {
+ awayStatuses[i]=awayStatuses[courProtocolSelection];
+ onlyIfBits[i]=onlyIfBits[courProtocolSelection];
+ reconnectOpts[i]=reconnectOpts[courProtocolSelection];
+ if (messCaps[i]) {
+ _tcscpy(mesgHere[i],mesgHerePerm[courProtocolSelection]);
+ _tcscpy(mesgShort[i],mesgShortPerm[courProtocolSelection]);
+ _tcscpy(mesgLong[i],mesgLongPerm[courProtocolSelection]);
+ }
+ }
+ }
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ }
+ } //switch
+ break;
+ }
+ case PSM_CHANGED:
+#ifdef _DEBUG
+ MessageBoxA(hwndDlg,"Child dialog changed","EventHapened",0);
+#endif
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, (unsigned int)hwndDlg, 0);
+ break;
+ case WM_NOTIFY:
+ {
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case 0: {
+ BOOL CommandApply;
+ if ( (CommandApply = lParam && ((LPNMHDR)lParam)->code == PSN_APPLY) || (lParam && ((LPNMHDR)lParam)->code == PSN_RESET) ) {
+ int j=0;
+#ifdef _DEBUG
+ //MessageBox(hwndDlg,CommandApply?"Apply":"Cancel","EventHapened",0);
+#endif
+ for (j = 0 ; j < protoCount ; j++) {
+ if ( isInterestingProto(j) ) {
+ char str[256];
+ if (CommandApply) {
+ onlyIfBitsPerm[j] = onlyIfBits[j];
+ awayStatusesPerm[j] = awayStatuses[j];
+ reconnectOptsPerm[j] = reconnectOpts[j];
+ sprintf(str,AA_BITSONLYIF,proto[j]->szName);
+ DBWriteContactSettingDword(NULL,AA_MODULE,str,onlyIfBitsPerm[j]);
+ sprintf(str,AA_AWAYSTATUSES,proto[j]->szName);
+ DBWriteContactSettingWord(NULL,AA_MODULE,str,awayStatusesPerm[j]);
+ sprintf(str,AA_RECONNECTOPTS,proto[j]->szName);
+ DBWriteContactSettingDword(NULL,AA_MODULE,str,reconnectOptsPerm[j]);
+ if (messCaps[j]) {
+ idleMessOptsPerm[j] = idleMessOpts[j];
+ sprintf(str,idleMsgOptionsName,proto[j]->szName);
+ DBWriteContactSettingDword(NULL,AA_MODULE,str,idleMessOptsPerm[j]);
+
+ sprintf(str,idleMsgOptionsTextHere,proto[j]->szName);
+ _tcscpy(mesgHerePerm[j],mesgHere[j]);
+ DBWriteContactSettingTString(NULL,AA_MODULE,str,mesgHerePerm[j]);
+
+ sprintf(str,idleMsgOptionsTextShort,proto[j]->szName);
+ _tcscpy(mesgShortPerm[j],mesgShort[j]);
+ DBWriteContactSettingTString(NULL,AA_MODULE,str,mesgShortPerm[j]);
+
+ sprintf(str,idleMsgOptionsTextLong,proto[j]->szName);
+ _tcscpy(mesgLongPerm[j],mesgLong[j]);
+ DBWriteContactSettingTString(NULL,AA_MODULE,str,mesgLongPerm[j]);
+ }
+ } else {
+ onlyIfBits[j] = onlyIfBitsPerm[j];
+ awayStatuses[j] = awayStatusesPerm[j];
+ reconnectOpts[j] = reconnectOptsPerm[j];
+ idleMessOpts[j] = idleMessOptsPerm[j];
+ if (messCaps[j]) {
+ _tcscpy(mesgHere[j],mesgHerePerm[j]);
+ _tcscpy(mesgShort[j],mesgShortPerm[j]);
+ _tcscpy(mesgLong[j],mesgLongPerm[j]);
+ }
+ }
+ }
+ }
+ if (CommandApply) {
+ idleOptsPerm = idleOpts;
+ DBWriteContactSettingDword(NULL,AA_MODULE,AA_IDLEOPTIONS,idleOptsPerm);
+ } else {
+ idleOpts = idleOptsPerm;
+ }
+ } //if PSN_APPLY
+ break;
+ case IDC_OPT_SAA_TAB:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case TCN_SELCHANGING:
+ {
+ TCITEM tci;
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(GetDlgItem(hwndDlg,IDC_OPT_SAA_TAB),TabCtrl_GetCurSel(GetDlgItem(hwndDlg,IDC_OPT_SAA_TAB)),&tci);
+ ShowWindow((HWND)tci.lParam,SW_HIDE);
+ }
+ break;
+ case TCN_SELCHANGE:
+ {
+ TCITEM tci;
+ short int t;
+ tci.mask = TCIF_PARAM;
+ t = TabCtrl_GetCurSel(GetDlgItem(hwndDlg,IDC_OPT_SAA_TAB));
+ TabCtrl_GetItem(GetDlgItem(hwndDlg,IDC_OPT_SAA_TAB),t,&tci);
+ DBWriteContactSettingWord(NULL, AA_MODULE, AA_PROTOSELECTION,
+ (unsigned short)(tabprotosel=(t<<8)|(tabprotosel&0xF0FF)));
+ ShowWindow((HWND)tci.lParam,SW_SHOW);
+ { BOOL enableW = (tci.lParam!=(long)theDialogIdle);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_AAPROTOCOL),enableW);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_APPLYTOALL),enableW);
+ }
+ }
+ break;
+ }
+ break;
+ }
+ }//end case(LPNMHDR)lParam)->idFrom
+
+ }
+//WTF??? if(wParam!=0x12345678) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ }
+ return FALSE;
+}
+
+
+
diff --git a/plugins/SmartAutoAway/globals.cpp b/plugins/SmartAutoAway/globals.cpp
new file mode 100644
index 0000000000..82f2087b3d
--- /dev/null
+++ b/plugins/SmartAutoAway/globals.cpp
@@ -0,0 +1,113 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "globals.h"
+
+HANDLE hIdleEvent = NULL;
+HANDLE hNetlib;
+UINT hIdleTimer = 0;
+
+BOOL starting=1; // this flag will be cleared later
+
+#ifdef UNICODE
+bool *protoHasAwayMessageW=0;
+bool HasAwayMessageW=0;
+#endif
+
+int *isWaitingForRestoreStatusMessage=0;
+
+ int *reqStatus=0;
+ int *courStatus=0;
+ int *courAwayStatus=0;
+
+ int *protoModes=0;
+
+ short int *awayStatusesPerm=0;
+ long *onlyIfBitsPerm=0;
+ short int *awayStatuses=0;
+ long *onlyIfBits=0;
+
+ int aa_Status[] = {
+ ID_STATUS_OFFLINE,
+ ID_STATUS_ONLINE,
+ ID_STATUS_AWAY,
+ ID_STATUS_NA,
+ ID_STATUS_OCCUPIED,
+ ID_STATUS_DND,
+ ID_STATUS_FREECHAT,
+ ID_STATUS_INVISIBLE,
+ ID_STATUS_ONTHEPHONE,
+ ID_STATUS_OUTTOLUNCH
+};
+
+ int numStatuses = sizeof(aa_Status)/sizeof(aa_Status[0]);
+
+HWND theDialog = 0;
+HWND theDialogReconnect=0;
+HWND theDialogIdle=0;
+HWND theDialogIdleMessages=0;
+HWND theDialogAA=0;
+
+
+PROTOCOLDESCRIPTOR **proto=0;
+int protoCount=0;
+int courProtocolSelection = 0;
+
+int localeID=0;
+int codePage=0;
+
+
+TCHAR *VariableList[][2]={
+ {NULL,LPGENT("Date")},
+ {_T("Y"),LPGENT("year (4 digits)")},
+ {_T("y"),LPGENT("year (2 digits)")},
+ {_T("m"),LPGENT("month")},
+ {_T("E"),LPGENT("name of month")},
+ {_T("e"),LPGENT("short name of month")},
+ {_T("d"),LPGENT("day")},
+ {_T("W"),LPGENT("weekday (full)")},
+ {_T("w"),LPGENT("weekday (abbreviated)")},
+ {_T("L"),LPGENT("Localized Date (Long)")},
+ {_T("l"),LPGENT("Localized Date (Short)")},
+ {NULL,LPGENT("Time")},
+ {_T("H"),LPGENT("hours (24)")},
+ {_T("h"),LPGENT("hours (12)")},
+ {_T("p"),LPGENT("AM/PM")},
+ {_T("M"),LPGENT("minutes")},
+ {_T("S"),LPGENT("seconds")},
+ {_T("K"),LPGENT("Localized Time (Long)")},
+ {_T("k"),LPGENT("Localized Time (no Seconds)")},
+ {NULL,LPGENT("Time Zone")},
+ {_T("z"),LPGENT("total bias")},
+ {_T("Z"),LPGENT("time zone name")},
+ {NULL,LPGENT("Format")},
+ {_T("t"),LPGENT("tabulator")},
+ {_T("b"),LPGENT("line break")},
+};
+
+HOTKEYDESC hotkeydescs[] = {
+ {sizeof(HOTKEYDESC), "saa_benotidle", "Not Idle", SECTIONNAME, AA_IDLE_BENOTIDLESERVICE, 0, 0},
+ {sizeof(HOTKEYDESC), "saa_beshortidle", "Short Idle", SECTIONNAME, AA_IDLE_BESHORTIDLESERVICE, 0, 0},
+ {sizeof(HOTKEYDESC), "saa_belongidle", "Long Idle", SECTIONNAME, AA_IDLE_BELONGIDLESERVICE, 0, 0},
+ {sizeof(HOTKEYDESC), "saa_reconnect", "Reconnect", SECTIONNAME, AA_IDLE_RECONNECTSERVICE, 0, 0},
+ };
+
diff --git a/plugins/SmartAutoAway/globals.h b/plugins/SmartAutoAway/globals.h
new file mode 100644
index 0000000000..788076a0c2
--- /dev/null
+++ b/plugins/SmartAutoAway/globals.h
@@ -0,0 +1,349 @@
+#ifdef UNICODE
+ #ifndef _UNICODE
+ #define _UNICODE
+ #endif
+#endif
+
+//#ifdef VCL_VC60
+#include "AggressiveOptimize.h"
+//#endif
+
+//#include <math.h>
+
+#ifdef _DEBUG
+#ifndef UNICODE
+ #define AALOG
+ #define AALOG1
+#endif
+#endif
+
+#define _WIN32_WINNT 0x0700
+#ifndef SAA_PLUGIN
+ #include "../../src/core/commonheaders.h"
+#else
+ #include <windows.h>
+ #include <commctrl.h>
+ #include <uxtheme.h>
+ #include <win2k.h>
+ #include <stdio.h>
+ #include "newpluginapi.h"
+ #include <m_system.h>
+ #include <m_langpack.h>
+ #include <m_database.h>
+ #include <m_clist.h>
+ #include <m_options.h>
+ #include <m_awaymsg.h>
+ #include <m_protosvc.h>
+ #include "m_idle.h"
+ #ifndef time
+ #include <time.h>
+ #endif
+ #define offsetof(s,m) (size_t)&(((s *)0)->m)
+ extern BOOL (WINAPI *enableThemeDialogTexture)(HANDLE, DWORD);
+#ifdef AALOG
+ #include <m_netlib.h>
+#endif
+#endif
+#include <m_hotkeys.h>
+
+
+//#ifdef SAA_PLUGIN
+// extern struct MM_INTERFACE memoryManagerInterface;
+// #define mir_alloc(n) memoryManagerInterface.mmi_malloc(n)
+// #define mir_free(ptr) memoryManagerInterface.mmi_free(ptr)
+// #define mir_realloc(ptr,size) memoryManagerInterface.mmi_realloc(ptr,size)
+//#endif
+
+#define SECTIONNAME "Smart Auto Away"
+
+ #include "resource.h"
+//#define IDF_ISIDLE 0x1 // idle has become active (if not set, inactive)
+#define IDF_SHORT 0x2 // short idle mode
+#define IDF_LONG 0x4 // long idle mode
+//#define IDF_PRIVACY 0x8 // if set, the information provided shouldn't be given to third parties.
+#define IDF_ONFORCE 0x10 // screensaver/onstationlocked,etc cause instant idle
+
+extern int FirstTick;
+
+#ifdef UNICODE
+extern bool *protoHasAwayMessageW;
+extern bool HasAwayMessageW;
+#endif
+
+extern HOTKEYDESC hotkeydescs[];
+
+//typedef struct {
+// int cbSize; // sizeof()
+// unsigned int idleTime; // idle in mins, if zero then disabled
+// int privacy; // user doesnt want other people seeing anything more than they are idle
+// int aaStatus; // status to go to when user is auto away
+//} MIRANDA_IDLE_INFO;
+//typedef struct {
+// int cbSize; // sizeof()
+// int enabled; // monitoring is going on
+// int idleShortTime; // short idle in mins, if zero then disabled
+// int idleLongTime; // long idle in mins, if zero then disabled
+// int privacy; // user doesnt want other people seeing anything more than they are idle
+//} MIRANDA_IDLE_INFO;
+
+//typedef struct{
+// int cbSize; //sizeof //5*sizeof(int) or 4*sizeof(int)
+// unsigned int fieldTime; //enabled or idleTime in minutes
+// int field1; //idleShortTime or privacy
+// int field2; //idleLongTime or aaStatus
+// // the "new structure ends here"
+// int field3; //privacy or none
+//} MYIDLEINFO;
+//#define MS_IDLE_GETIDLEINFO "Miranda/Idle/GetInfo"
+//#define ME_IDLE_CHANGED "Miranda/Idle/Changed"
+extern int isCurrentlyIdle;
+
+extern unsigned long idleOptsPerm; // CMHG SL S SM P L S --LONG-- --SHORT-
+extern unsigned long idleOpts; // C G L S tM P L S --LONG-- --SHORT-
+#define idleOptsDefault 0x95851E0A // 1001 0101 1000 0101 00011110 00001010
+#define IdleBitsTimeFirst 0x000000FF // ---- ---- ---- ---- -------- 11111111
+#define IdleBitsTimeSecond 0x0000FF00 // ---- ---- ---- ---- 11111111 --------
+#define IdleBitsCheck 0x80000000 // 1000 0000 0000 0000 00000000 00000000
+#define IdleBitsMethod 0x00400000 // 0000 0000 0100 0000 00000000 00000000
+#define IdleBitsFirstOn 0x00010000 // 0000 0000 0000 0001 00000000 00000000
+#define IdleBitsSecondOn 0x00040000 // 0000 0000 0000 0100 00000000 00000000
+#define IdleBitsOnSaver 0x01000000 // 0000 0001 0000 0000 00000000 00000000
+#define IdleBitsOnLock 0x04000000 // 0000 0100 0000 0000 00000000 00000000
+#define IdleBitsGLI 0x10000000 // 0001 0000 0000 0000 00000000 00000000
+#define IdleBitsPrivate 0x00100000 // 0000 0000 0001 0000 00000000 00000000
+#define IdleSuppressIdleMenu 0x40000000 // 0100 0000 0000 0000 00000000 00000000
+#define IdleSuppressAutoHere 0x20000000 // 0010 0000 0000 0000 00000000 00000000
+#define KeepMainStatusOffline 0x08000000 // 0000 1000 0000 0000 00000000 00000000
+#define IdleHereOnStatusChange 0x00800000// 0000 0000 1000 0000 00000000 00000000
+
+
+
+
+#ifdef SAA_PLUGIN
+ int __cdecl LoadAutoAwayModule(void);
+ extern HINSTANCE g_hInst;
+#endif
+
+
+#define MS_SYSTEM_GETIDLE "Miranda/GetIdle"
+#ifdef AALOG
+ extern HANDLE hNetlib;
+#endif
+static int InitVariables( WPARAM wParam, LPARAM lParam );
+
+extern HANDLE hIdleEvent;
+extern UINT hIdleTimer;
+
+extern BOOL CALLBACK DlgProcAutoAwayOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+extern BOOL CALLBACK DlgProcOptsIdle(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+
+int AutoAwayOptInitialise(WPARAM wParam,LPARAM lParam);
+//extern int AutoAwayShutdown(WPARAM wParam,LPARAM lParam);
+
+#define IDLEMODULE "Idle"
+// live settings
+//extern int idleCheckPerm;
+//extern int idleMethodPerm;
+//extern int idleTimeFirstPerm; // this is in mins
+//extern int idleTimeSecondPerm; //
+//extern int idleTimeFirstOnPerm;
+//extern int idleTimeSecondOnPerm;
+//extern int idleOnSaverPerm;
+//extern int idleOnLockPerm;
+//extern int idleGLIPerm;
+//extern int idlePrivatePerm;
+
+//We will not try to import previous Idle settings anymore
+// db settings keys
+//#define IDL_IDLECHECK "IdleCheck"
+//#define IDL_IDLEMETHOD "IdleMethod"
+//#define IDL_IDLEGLI "IdleGLI"
+//#define IDL_IDLETIME1ST "IdleTime1st"
+//#define IDL_IDLETIME2ND "IdleTime2nd"
+//#define IDL_IDLEONSAVER "IdleOnSaver"
+//#define IDL_IDLEONLOCK "IdleOnLock"
+//#define IDL_IDLETIME1STON "IdleTime1stOn"
+//#define IDL_IDLETIME2NDON "IdleTime2ndOn"
+//#define IDL_IDLEPRIVATE "IdlePrivate"
+
+extern BOOL (WINAPI * MyGetLastInputInfo)(PLASTINPUTINFO);
+extern int IdleGetInfo(WPARAM wParam, LPARAM lParam);
+
+VOID CALLBACK IdleTimer(HWND hwnd, UINT message, UINT idEvent, DWORD dwTime);
+BOOL InitDialogIdlePart(HWND hwndDlg);
+
+
+//AutoAway Module
+#define AA_IDLEOPTIONS "IdleOptions"
+#define AA_LASTIDLESTATUS "IdleLastStatus"
+#define AA_LASTIDLETIME "IdleLastTime"
+#define AA_OLDMODULE "AutoAway"
+#define AA_USESHORT "IsShortEnabled"
+#define AA_USELONG "IsLongEnabled"
+#define AA_SHORTSTATUS "ShortStatus"
+#define AA_LONGSTATUS "LongStatus"
+
+#define AA_MODULE "SmartAutoAway"
+
+#define AA_PROTOSELECTION "ProtoSelection"
+
+#define AA_AWAYSTATUSES "AwayStatuses_%s"
+#define AA_BITSONLYIF "BitsOnlyIf_%s"
+#define AA_LASTREQUESTEDSTATUS "LastRequestedStatus_%s"
+
+//#define AA_SIMULATEIDLESERVICE "SAA/SimulateIdle"
+#define AA_IDLE_BENOTIDLESERVICE "SAA/IdleBeNotIdle"
+MIRANDASERVICE idleServiceNotIdle(WPARAM w, LPARAM l);
+#define AA_IDLE_BESHORTIDLESERVICE "SAA/IdleBeShortIdle"
+MIRANDASERVICE idleServiceShortIdle(WPARAM w, LPARAM l);
+#define AA_IDLE_BELONGIDLESERVICE "SAA/IdleBeLongIdle"
+MIRANDASERVICE idleServiceLongIdle(WPARAM w, LPARAM l);
+#define AA_IDLE_RECONNECTSERVICE "SAA/ForceReconnect"
+MIRANDASERVICE reconnectService(WPARAM w, LPARAM l);
+
+//#define aa_AwayStatusesDefault ((StatusToProtoIndex(ID_STATUS_AWAY,allprotomodes)<<8)|StatusToProtoIndex(ID_STATUS_NA,allprotomodes)) | 0x8000
+ //K--- --21 LLLL SSSS
+#define maskIsShortAwayEnabled 0x0100
+#define maskIsLongAwayEnabled 0x0200
+#define maskShortAwayStatus 0x000F
+#define maskLongAwayStatus 0x00F0
+
+#define allprotomodes 0x03FF // 0000 0011 1111 1111;
+#define aa_OnlyIfBitsDefault 0x01BB01B8 //Short 0001 1011 1000;
+ //Long 0001 1011 1011
+
+
+extern HANDLE hStatusModeChangeEvent;
+
+extern int aa_Status[];
+extern int numStatuses;
+
+extern int *reqStatus;
+extern int *courStatus;
+extern int *courAwayStatus; //to be used in reconnect part
+
+extern int *protoModes;
+
+extern short int *awayStatusesPerm;
+extern long *onlyIfBitsPerm;
+extern short int *awayStatuses;
+extern long *onlyIfBits;
+
+
+extern HWND theDialog;
+extern HWND theDialogReconnect;
+extern HWND theDialogIdle;
+extern HWND theDialogAA;
+extern HWND theDialogIdleMessages;
+
+
+extern PROTOCOLDESCRIPTOR **proto;
+extern int protoCount;
+extern int courProtocolSelection;
+
+unsigned long GetBits (unsigned long source,unsigned long mask);
+unsigned long SetBits (unsigned long target,unsigned long mask,unsigned long value);
+BOOL IsStatusBitSet(int status, int bits);
+int StatusByProtoIndex(int modes, int index);
+int StatusToProtoIndex(int status, int modes);
+
+int OldIndexToStatus(int oldIndex);
+int StatusToOldIndex(int status);
+
+LRESULT SetDlgItems(HWND hwndDlg, int coursel);
+LRESULT SetDlgItemsReconnect(HWND hwndDlg, int coursel);
+LRESULT SetDlgItemsAA(HWND hwndDlg, int coursel);
+LRESULT SetDlgItemsIdleMessages(HWND hwndDlg, int coursel);
+
+int StatusToProtoIndex(int status, int modes);
+int GetCourSelProtocol(int sel);
+BOOL StrikeOut(HWND hWnd, int item, BOOL striked);
+
+int AutoAwayShutdown(WPARAM wParam,LPARAM lParam);
+int AutoAwayEvent(WPARAM wParam, LPARAM lParam);
+//extern int SimulateIdle(HWND theDialog, int button);
+int StatusModeChangeEvent(WPARAM wParam,LPARAM lParam);
+int ProtoAckEvent(WPARAM wParam,LPARAM lParam);
+int SimulateIdle(int idlstatus);
+
+
+//Reconnect Part
+int GetReconnectDelayFromSlider(int slide);
+BOOL GetStringFromDelay(TCHAR * str, int delay);
+int GetSliderFromReconnectDelay(int delay);
+void ProtocolsProc(int protoIndex, ACKDATA * ack);
+void LoginAck(int protoIndex, ACKDATA * ack);
+void TimerProc();
+extern BOOL CALLBACK DlgProcOptsReconnect(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+#define AA_RECONNECTOPTS "ReconnectOptions_%s"
+#define aa_ReconnectOptsDefault 0x003CC1AE
+//-----60 sec-------- 1100 0001 1010 1110
+//DDDD DDDD DDDD DDDD Rfxx xxFN ANOD FIPL
+#define aa_ReconnectBitsDelay 0xFFFF0000
+#define aa_ReconnectBitsEnabled 0x00008000
+#define aa_ReconnectNotFatalError 0x00004000
+
+extern BOOL CALLBACK DlgProcOptsAA(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+extern long *reconnectOpts;
+extern long *reconnectOptsPerm;
+extern unsigned int *protoOfflineTimes;
+extern int *protoStatus; //0:OK; :1:couning; 2:fatalError;
+
+//IdleMessage part
+extern BOOL starting;
+extern int *isWaitingForRestoreStatusMessage;
+extern unsigned long secondsAfterLastActivity;
+
+
+#define idleMsgOptionsTextHere "IdleMsgTextHere_%s"
+#define idleMsgOptionsTextShort "IdleMsgTextShort_%s"
+#define idleMsgOptionsTextLong "IdleMsgTextLong_%s"
+#define messHereDefaultOld _T("I am back")
+#define messShortDefaultOld _T("I am distracted")
+#define messLongDefaultOld _T("I am sleeping")
+#define messHereDefault _T("I came back on %H:%M:%S%b%Z (%z)")
+#define messShortDefault _T("I am distracted since %H:%M:%S%b%Z (%z)")
+#define messLongDefault _T("I fell asleep on %H:%M:%S %d %E %Y (%W)%b%Z (%z)")
+#define maxMessageLength 2047
+extern TCHAR **mesgHere;
+extern TCHAR **mesgShort;
+extern TCHAR **mesgLong;
+extern TCHAR **mesgHerePerm;
+extern TCHAR **mesgShortPerm;
+extern TCHAR **mesgLongPerm;
+
+#define idleMsgOptionsName "IdleMsgOpts_%s"
+#define idleMsgOptionsDefault 0x0111103C
+extern int *messCaps;
+
+extern BOOL CALLBACK DlgProcOptsIdleMessages(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+extern long *idleMessOptsPerm;
+extern long *idleMessOpts;
+ // xxxx xxxL xxxS xxxH xxxE xxx- RSTHERE-
+#define IdleMessOptsMaskRstHereDelay 0x000001FF // 0000 0000 0000 0000 0000 0001 11111111
+#define IdleMessOptsMaskRstHere 0x00001000 // 0000 0000 0000 0000 0001 0000 00000000
+#define IdleMessOptsMaskUseHere 0x00010000 // 0000 0000 0000 0001 0000 0000 00000000
+#define IdleMessOptsMaskUseShort 0x00100000 // 0000 0000 0001 0000 0000 0000 00000000
+#define IdleMessOptsMaskUseLong 0x01000000 // 0000 0001 0000 0000 0000 0000 00000000
+
+extern int localeID;
+extern int codePage;
+void my_u2a(const TCHAR* src, char * target, unsigned int max);
+void my_a2u(const char* src, TCHAR * target, unsigned int max);
+void GetLastActiveLocalTime(SYSTEMTIME * at, unsigned long miliSeconds);
+int GetTimeZone(TCHAR * name);
+UINT ParseString(TCHAR *szstring,TCHAR *sztemp, unsigned int MaxOutLen);
+
+//borrowed from "Last Seen Plugin"
+//#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%%z: \t %s\n%%Z: \t %s\n\n%s\n%%t: \t %s\n%%b: \t %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("-- Time Zone --"),Translate("total bias"),Translate("time zone name"),Translate("-- Format --"),Translate("tabulator"),Translate("line break")
+extern TCHAR *VariableList[][2];
+
+void AddIdleMenu();
+extern HANDLE hHookIconsChanged;
+void xModifyMenu(int menuInd,long flags);
+BOOL isInterestingProto(int j);
diff --git a/plugins/SmartAutoAway/here.ico b/plugins/SmartAutoAway/here.ico
new file mode 100644
index 0000000000..ab282fba52
--- /dev/null
+++ b/plugins/SmartAutoAway/here.ico
Binary files differ
diff --git a/plugins/SmartAutoAway/idle.cpp b/plugins/SmartAutoAway/idle.cpp
new file mode 100644
index 0000000000..9751bcf0e6
--- /dev/null
+++ b/plugins/SmartAutoAway/idle.cpp
@@ -0,0 +1,374 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "globals.h"
+//#include "../../miranda-IM/core/commonheaders.h"
+
+
+//int idleCheckPerm = 0;
+//int idleMethodPerm = 0;
+//int idleTimeFirstPerm = 5; // this is in mins
+//int idleTimeSecondPerm = 10; //
+//int idleTimeFirstOnPerm = 0;
+//int idleTimeSecondOnPerm = 0;
+//int idleOnSaverPerm = 0;
+//int idleOnLockPerm = 0;
+//int idleGLIPerm = 1;
+//int idlePrivatePerm = 0;
+BOOL (WINAPI * MyGetLastInputInfo)(PLASTINPUTINFO);
+unsigned long idleOptsPerm; // C G L S M P L S --LONG-- --SHORT-
+unsigned long idleOpts; // C G L S M P L S --LONG-- --SHORT-
+static BOOL idleDialogInInit = FALSE;
+ BOOL InitDialogIdlePart(HWND hwndDlg)
+{
+// TranslateDialogDefault(hwndDlg);
+ CheckDlgButton(hwndDlg, IDC_IDLECHECK, (idleOpts&IdleBitsCheck) ? BST_CHECKED : BST_UNCHECKED);
+ // check/uncheck options
+ CheckDlgButton(hwndDlg, IDC_IDLEONWINDOWS, (idleOpts&IdleBitsMethod) ? BST_UNCHECKED : BST_CHECKED);
+ CheckDlgButton(hwndDlg, IDC_IDLEONMIRANDA, (idleOpts&IdleBitsMethod) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_IDLEUSEGLI, (idleOpts&IdleBitsGLI) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_SCREENSAVER, (idleOpts&IdleBitsOnSaver) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_LOCKED, (idleOpts&IdleBitsOnLock) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_IDLESHORT, (idleOpts&IdleBitsFirstOn) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_IDLELONG, (idleOpts&IdleBitsSecondOn) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_IDLEPRIVATE, (idleOpts&IdleBitsPrivate) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_DISBABLEAUTOHERE, (idleOpts&IdleSuppressAutoHere) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_DISABLEIDLEMENU, (idleOpts&IdleSuppressIdleMenu) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwndDlg, IDC_HEREONSTATUSCHANGE, (idleOpts&IdleHereOnStatusChange)? BST_CHECKED : BST_UNCHECKED);
+ // set times
+ idleDialogInInit = TRUE;
+ SetDlgItemInt(hwndDlg, IDC_IDLE1STTIME, GetBits(idleOpts,IdleBitsTimeFirst), FALSE);
+ SetDlgItemInt(hwndDlg, IDC_IDLE2NDTIME, GetBits(idleOpts,IdleBitsTimeSecond), FALSE);
+ idleDialogInInit = FALSE;
+ // enable options
+ SendMessage(hwndDlg, WM_USER+4, (WPARAM)((idleOpts&IdleBitsCheck)!=0), 0);
+ return TRUE;
+}
+
+// delphi code here http://www.swissdelphicenter.ch/torry/printcode.php?id=2048
+ BOOL IsWorkstationLocked(void)
+{
+ BOOL rc=0;
+ HDESK hDesk = OpenDesktopA("default", 0, FALSE, DESKTOP_SWITCHDESKTOP);
+ if ( hDesk != 0 ) {
+ rc = SwitchDesktop(hDesk) == FALSE;
+ CloseDesktop(hDesk);
+ }
+ return rc;
+}
+
+// ticks every 2 seconds
+ int FirstTick;
+ unsigned long secondsAfterLastActivity;
+ unsigned long lastIdleEventTime = 0;
+ int isCurrentlyIdle=0; //0 notidle //1 short //2long
+ VOID CALLBACK IdleTimer(HWND hwnd, UINT message, UINT idEvent, DWORD dwTime)
+{
+ DWORD dwTick = GetTickCount();
+ int isIdle[3] = {0};
+ static int isEventFired[3] = {0};
+ int j;
+
+ if (FirstTick) {
+ FirstTick--;
+ if (FirstTick==0){
+ int flags = 0;
+ starting = 1;
+ switch (isCurrentlyIdle)
+ {
+ default : {flags = 0;/*MessageBox(theDialog,"BeHere","Button Pressed",0);*/ break;}
+ case 1: {flags = IDF_SHORT|IDF_ISIDLE; /*MessageBox(theDialog,"BeAway","Button Pressed",0);*/ break;}
+ case 2: {flags = IDF_LONG|IDF_ISIDLE; /*MessageBox(theDialog,"BeNA","Button Pressed",0);*/ break;}
+ }
+ if (isCurrentlyIdle) {
+ lastIdleEventTime = DBGetContactSettingDword(NULL,AA_MODULE,AA_LASTIDLETIME,(DWORD)time(NULL));
+ secondsAfterLastActivity = time(NULL) - lastIdleEventTime;
+
+ } else secondsAfterLastActivity = 0;
+ flags |= idleOpts&IdleBitsPrivate?IDF_PRIVACY:0;
+ NotifyEventHooks( hIdleEvent, 0, flags ); //Tell everyone we are here
+ return;
+ }
+ }
+
+ for (j = 0 ; j < protoCount ; j++) {
+ if ( !isInterestingProto(j) ) continue;
+ if (isWaitingForRestoreStatusMessage[j]) {
+ isWaitingForRestoreStatusMessage[j]--;
+ if (!(isWaitingForRestoreStatusMessage[j])) {
+#ifdef UNICODE
+ TCHAR *awayMsg=0;
+ if (HasAwayMessageW){
+ awayMsg = (TCHAR *) CallService(MS_AWAYMSG_GETSTATUSMSGW, (WPARAM) courAwayStatus[j], 0);
+ } else {
+ char *temp=(char *)CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) courAwayStatus[j], 0);
+ if ((int)temp == CALLSERVICE_NOTFOUND) awayMsg = 0;
+ else{
+ awayMsg = (TCHAR *)mir_alloc((maxMessageLength+1)*sizeof(TCHAR));
+ my_a2u(temp,awayMsg,maxMessageLength);
+ mir_free(temp);
+ }
+ }
+#else
+ char * awayMsg = (char *) CallService(MS_AWAYMSG_GETSTATUSMSG, (WPARAM) courAwayStatus[j], 0);
+ if ((int)awayMsg==CALLSERVICE_NOTFOUND) awayMsg = NULL;
+#endif
+
+#ifdef AALOG
+ {
+ char str[1000];
+ sprintf(str,"%s: Restoring the default \"StatusMessage\": %s",proto[j]->szName,awayMsg ? awayMsg : "none");
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+ }
+#endif
+#ifdef UNICODE
+ if (protoHasAwayMessageW[j]) CallProtoService(proto[j]->szName, PS_SETAWAYMSGW, courAwayStatus[j], (LPARAM) awayMsg);
+ else {
+ char temp[maxMessageLength+1];
+ my_u2a(awayMsg,temp,maxMessageLength);
+ CallProtoService(proto[j]->szName, PS_SETAWAYMSG, courAwayStatus[j], (LPARAM) temp);
+ }
+#else
+ CallProtoService(proto[j]->szName, PS_SETAWAYMSG, courAwayStatus[j], (LPARAM) awayMsg);
+#endif
+ if (awayMsg) {
+#ifdef AALOG
+ char str[1000];
+ sprintf(str,"%s: Cleaning after MS_AWAYMSG_GETSTATUSMSG: %s",proto[j]->szName,awayMsg);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ mir_free(awayMsg);
+ }
+
+ }
+ }
+ }
+
+ TimerProc(); //for the reconnect
+ secondsAfterLastActivity = 0;
+ isCurrentlyIdle = 0;
+ if ( (idleOptsPerm&IdleBitsCheck) == 0 ) return;
+
+ if ( (idleOptsPerm&IdleBitsMethod) == 0 ) {
+ // use windows idle time
+ if ( GetBits(idleOptsPerm,IdleBitsGLI) && (MyGetLastInputInfo != 0) ) {
+ LASTINPUTINFO ii;
+ memset(&ii,0,sizeof(ii));
+ ii.cbSize=sizeof(ii);
+ if ( MyGetLastInputInfo(&ii) ) dwTick = ii.dwTime;
+ } else {
+ // mouse check
+ static int mouseIdle = 0;
+ static POINT lastMousePos = {0};
+ POINT pt;
+ GetCursorPos(&pt);
+ if ( pt.x != lastMousePos.x || pt.y != lastMousePos.y )
+ {
+ mouseIdle=0;
+ lastMousePos=pt;
+ }
+ else mouseIdle += 2; // interval of timer
+ if ( mouseIdle ) dwTick = GetTickCount() - (mouseIdle * 1000);
+ }
+ } else {
+ // use miranda idle time
+ CallService(MS_SYSTEM_GETIDLE, 0, (LPARAM)&dwTick);
+ }
+ secondsAfterLastActivity = (GetTickCount() - dwTick)/1000;
+#ifdef AALOG
+ { char log[1024];
+ sprintf(log,"%d seconds after last activity",secondsAfterLastActivity);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);}
+#endif
+ // has the first idle elapsed? If not permited FirstIdle time:ignore
+ isIdle[0] = (idleOptsPerm&IdleBitsFirstOn)? (secondsAfterLastActivity >= (DWORD)( GetBits(idleOptsPerm,IdleBitsTimeFirst) * 60 )):0;
+ // and the second? if not permited the SecondIdleTime: idnore
+ isIdle[1] = (idleOptsPerm&IdleBitsSecondOn)?(secondsAfterLastActivity >= (DWORD)( GetBits(idleOptsPerm,IdleBitsTimeSecond) * 60 )):0;
+
+ isIdle[2] = FALSE;
+ if ( idleOptsPerm&IdleBitsOnSaver ) { // check saver
+ BOOL isScreenSaverRunning = FALSE;
+ SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &isScreenSaverRunning, FALSE);
+ isIdle[2] |= isScreenSaverRunning;
+ }
+
+ // check workstation?
+ if ( idleOptsPerm&IdleBitsOnLock ) { // check station locked?
+ isIdle[2] |= IsWorkstationLocked();
+ }
+ { //check if the new idle is more idle than the previous idle is idle ;)
+ int temp = isIdle[1]?2:((isIdle[0] || isIdle[2])?1:0);
+ if (temp>=isCurrentlyIdle) isCurrentlyIdle = temp;
+ else return; //if we are alredy idle then exit
+ }
+ for ( j = 0; j<3; j++ )
+ {
+ int flags = ( idleOptsPerm&IdleBitsPrivate ? IDF_PRIVACY:0 );
+ switch (j) {
+ case 0: flags |= IDF_SHORT; break;
+ case 1: flags |= IDF_LONG; break;
+ case 2: flags |= IDF_ONFORCE; break;
+ }
+ if ( isIdle[j]==1 && isEventFired[j] == 0 ) { // idle and no one knows
+ isEventFired[j]=1;
+ NotifyEventHooks( hIdleEvent, 0, IDF_ISIDLE | flags );
+ }
+ if ( isIdle[j]==0 && isEventFired[j] == 1 ) { // not idle, no one knows
+ isEventFired[j]=0;
+ if ( !(idleOptsPerm&IdleSuppressAutoHere) ) NotifyEventHooks( hIdleEvent, 0, flags );
+ }
+ }//for
+// {
+// int flags = ( idleOptsPerm&IdleBitsPrivate ? IDF_PRIVACY:0 );
+// if (isIdle[0]||isIdle[1]||isIdle[2]) flags |= IDF_ISIDLE;
+// if (isIdle[0]) flags |= IDF_SHORT;
+// if (isIdle[1]) flags |= IDF_LONG;
+// if (isIdle[2]) flags |= IDF_ONFORCE;
+// NotifyEventHooks( hIdleEvent, 0, flags );
+// }
+}
+
+ int IdleGetInfo(WPARAM wParam, LPARAM lParam)
+{
+ MIRANDA_IDLE_INFO * mii = (MIRANDA_IDLE_INFO *) lParam;
+ if (mii) {
+ int minutesAfterLastActivity = (time(NULL)-lastIdleEventTime)/60;
+#ifdef AALOG
+ char log[1024];
+ sprintf(log,"\"%s\": %d came.",
+ MS_IDLE_GETIDLEINFO,
+ mii->cbSize/sizeof(mii->cbSize));
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+#endif
+ if (minutesAfterLastActivity<=0) minutesAfterLastActivity = 1;
+ //this is the only field with similar meaning in "old" and "new miranda";
+ if (mii->cbSize/sizeof(mii->cbSize)>=2) mii->idleTime = isCurrentlyIdle?minutesAfterLastActivity:0;
+ if (mii->cbSize/sizeof(mii->cbSize)>=3) mii->privacy = (idleOptsPerm&IdleBitsPrivate) !=0;
+ if (mii->cbSize/sizeof(mii->cbSize)>=4) mii->aaStatus = isCurrentlyIdle==1?ID_STATUS_AWAY:(isCurrentlyIdle>1?ID_STATUS_NA:ID_STATUS_ONLINE); //dont know what to with that
+ if (mii->cbSize/sizeof(mii->cbSize)>=5) mii->aaLock = (idleOptsPerm&IdleSuppressAutoHere) !=0;
+ if (mii->cbSize/sizeof(mii->cbSize)>=6) mii->idleType = isCurrentlyIdle?1:0;
+ return 0;
+ } else return 1;
+}
+
+BOOL CALLBACK DlgProcOptsIdle(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ InitDialogIdlePart(hwndDlg);
+ return TRUE;
+ case WM_USER+4:
+ {
+ DWORD nID[] = { IDC_IDLEONWINDOWS,
+ IDC_IDLEUSEGLI,
+ IDC_IDLEONMIRANDA,
+ IDC_SCREENSAVER,
+ IDC_LOCKED,
+ IDC_IDLESHORT,
+ IDC_IDLE1STTIME,
+ IDC_IDLELONG,
+ IDC_IDLE2NDTIME//,IDC_IDLEPRIVATE
+ };
+ int j;
+ // enable/disable all sub controls,
+ for (j = 0; j < sizeof(nID) / sizeof(nID[0]); j++) {
+ int nEnable = wParam;
+ switch ( nID[j] ) {
+ case IDC_IDLEUSEGLI: nEnable &= IsDlgButtonChecked(hwndDlg, IDC_IDLEONWINDOWS) == BST_CHECKED ? 1 : 0; break;
+ case IDC_IDLE1STTIME: nEnable &= IsDlgButtonChecked(hwndDlg, IDC_IDLESHORT) == BST_CHECKED ? 1 : 0; break;
+ case IDC_IDLE2NDTIME: nEnable &= IsDlgButtonChecked(hwndDlg, IDC_IDLELONG) == BST_CHECKED ? 1 : 0; break;
+ }
+ EnableWindow(GetDlgItem(hwndDlg, nID[j]), nEnable);
+ }
+
+ idleOpts=SetBits(idleOpts,IdleBitsCheck, IsDlgButtonChecked(hwndDlg, IDC_IDLECHECK) == BST_CHECKED);
+ idleOpts=SetBits(idleOpts,IdleBitsMethod, IsDlgButtonChecked(hwndDlg, IDC_IDLEONMIRANDA) == BST_CHECKED);
+ idleOpts=SetBits(idleOpts,IdleBitsFirstOn, IsDlgButtonChecked(hwndDlg, IDC_IDLESHORT) == BST_CHECKED);
+ idleOpts=SetBits(idleOpts,IdleBitsSecondOn, IsDlgButtonChecked(hwndDlg, IDC_IDLELONG) == BST_CHECKED);
+ idleOpts=SetBits(idleOpts,IdleBitsGLI, IsDlgButtonChecked(hwndDlg, IDC_IDLEUSEGLI) == BST_CHECKED);
+ idleOpts=SetBits(idleOpts,IdleBitsOnSaver, IsDlgButtonChecked(hwndDlg, IDC_SCREENSAVER) == BST_CHECKED);
+ idleOpts=SetBits(idleOpts,IdleBitsOnLock, IsDlgButtonChecked(hwndDlg, IDC_LOCKED) == BST_CHECKED);
+ idleOpts=SetBits(idleOpts,IdleBitsPrivate, IsDlgButtonChecked(hwndDlg, IDC_IDLEPRIVATE) == BST_CHECKED);
+ idleOpts=SetBits(idleOpts,IdleSuppressAutoHere, IsDlgButtonChecked(hwndDlg, IDC_DISBABLEAUTOHERE) == BST_CHECKED);
+ idleOpts=SetBits(idleOpts,IdleSuppressIdleMenu, IsDlgButtonChecked(hwndDlg, IDC_DISABLEIDLEMENU) == BST_CHECKED);
+ idleOpts=SetBits(idleOpts,IdleHereOnStatusChange, IsDlgButtonChecked(hwndDlg, IDC_HEREONSTATUSCHANGE) == BST_CHECKED);
+ break;
+ }
+ case WM_USER+8:
+ {
+ if (wParam == IDC_IDLE1STTIME) idleOpts = SetBits(idleOpts,IdleBitsTimeFirst,GetDlgItemInt(hwndDlg, wParam, NULL, FALSE));
+ if (wParam == IDC_IDLE2NDTIME) idleOpts = SetBits(idleOpts,IdleBitsTimeSecond,GetDlgItemInt(hwndDlg, wParam, NULL, FALSE));
+ break;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_IDLEBUTTON:
+ case IDC_IDLEBUTTON+1:
+ case IDC_IDLEBUTTON+2:SimulateIdle(LOWORD(wParam)-IDC_IDLEBUTTON); break;
+ case IDC_IDLECHECK:
+ case IDC_IDLEONWINDOWS:
+ case IDC_IDLEONMIRANDA:
+ case IDC_IDLESHORT:
+ case IDC_IDLELONG:
+ case IDC_IDLEUSEGLI:
+ case IDC_SCREENSAVER:
+ case IDC_LOCKED:
+ case IDC_IDLEPRIVATE:
+ case IDC_DISBABLEAUTOHERE:
+ case IDC_HEREONSTATUSCHANGE:
+ case IDC_DISABLEIDLEMENU:
+ {
+ SendMessage(hwndDlg, WM_USER+4, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_IDLECHECK) == BST_CHECKED, 0);
+ break;
+ }
+ case IDC_IDLE1STTIME:
+ case IDC_IDLE2NDTIME:
+ {
+ if ( HIWORD(wParam) != EN_CHANGE ) return TRUE;
+ SendMessage(hwndDlg, WM_USER+8, LOWORD(wParam), 0);
+ break;
+ }
+ }
+ if (!idleDialogInInit) if ((HIWORD(wParam)==BN_CLICKED)||(HIWORD(wParam)==EN_CHANGE))
+ {
+ if ((LOWORD(wParam)!=IDC_IDLEBUTTON)&&(LOWORD(wParam)!=IDC_IDLEBUTTON+1)&&(LOWORD(wParam)!=IDC_IDLEBUTTON+2))
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY: {
+ return TRUE;
+ }
+ }
+ break;
+ }
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return FALSE;
+}
+
diff --git a/plugins/SmartAutoAway/idleMenu.cpp b/plugins/SmartAutoAway/idleMenu.cpp
new file mode 100644
index 0000000000..bc5ad2a255
--- /dev/null
+++ b/plugins/SmartAutoAway/idleMenu.cpp
@@ -0,0 +1,147 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "globals.h"
+#ifdef SAA_PLUGIN
+# include "m_icolib.h"
+#endif
+
+HANDLE hIdleMenu[4] = {NULL,NULL,NULL,NULL};
+HANDLE hHookIconsChanged = NULL;
+static char *iconDescs[4]={"Not Idle","Short Idle","Long Idle","Reconnect"};
+static int iconInd[4]={IDI_IDLE_HERE,IDI_IDLE_SHORT,IDI_IDLE_LONG,IDI_RECONNECT};
+static char *IdleServices[4]={AA_IDLE_BENOTIDLESERVICE,AA_IDLE_BESHORTIDLESERVICE,AA_IDLE_BELONGIDLESERVICE,AA_IDLE_RECONNECTSERVICE};
+
+void xModifyMenu(int menuInd,long flags)
+{ if (hIdleMenu[menuInd]){
+ CLISTMENUITEM mi = {0};
+
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_FLAGS;
+ mi.flags |= flags;
+ CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hIdleMenu[menuInd],(LPARAM)&mi);
+} }
+
+static int hasIcoLib = 0;
+
+static void CListSetMenuItemIcon(HANDLE hMenuItem, HICON hIcon)
+{
+ CLISTMENUITEM mi = {0};
+
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_FLAGS | CMIM_ICON;
+
+ mi.hIcon = hIcon;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuItem, (LPARAM)&mi);
+}
+
+static int IconLibIconsChanged(WPARAM wParam, LPARAM lParam)
+{
+ int i;
+ for (i=0;i<4;i++)
+ {
+ HICON hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)IdleServices[i]);
+ CListSetMenuItemIcon(hIdleMenu[i], hIcon);
+ CallService(MS_SKIN2_RELEASEICON, 0, (LPARAM)IdleServices[i]);
+ }
+ return 0;
+}
+
+void AddIdleMenu(){
+ CLISTMENUITEM mi;
+ int i;
+ if (ServiceExists(MS_SKIN2_GETICON)){
+ SKINICONDESC sid = {0};
+ hHookIconsChanged = HookEvent(ME_SKIN2_ICONSCHANGED, IconLibIconsChanged);
+ hasIcoLib = 1;
+ sid.cbSize = SKINICONDESC_SIZE_V2;
+ sid.pszSection = SECTIONNAME;
+ sid.pszDefaultFile = NULL;
+ sid.iDefaultIndex = 0;
+ for (i=0;i<4;i++){
+ sid.pszDescription = iconDescs[i];
+ sid.pszName = IdleServices[i];
+ sid.iDefaultIndex = iconInd[i];
+ sid.hDefaultIcon = (HICON)LoadImage(
+ #ifdef SAA_PLUGIN
+ g_hInst,
+ #else
+ GetModuleHandle(NULL),
+ #endif
+ MAKEINTRESOURCE( iconInd[i] ), IMAGE_ICON, 0, 0, 0);
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+ DestroyIcon(sid.hDefaultIcon);
+ }
+ }
+
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize=sizeof(mi);
+ mi.pszPopupName="&Idle";
+ mi.popupPosition=1000090000;
+ for (i=0;i<4;i++)
+ {
+ if (hasIcoLib)
+ mi.hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)IdleServices[i]);
+ else
+ mi.hIcon = (HICON)LoadImage(
+ #ifdef SAA_PLUGIN
+ g_hInst,
+ #else
+ GetModuleHandle(NULL),
+ #endif
+ MAKEINTRESOURCE(iconInd[i]), IMAGE_ICON, 0, 0, 0);
+
+ mi.position=i+1;
+ mi.pszName=iconDescs[i];
+ mi.pszService=IdleServices[i];
+ if (i==3) mi.position=1000000;
+ hIdleMenu[i]=(HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
+
+ if (hasIcoLib)
+ CallService(MS_SKIN2_RELEASEICON, 0, (LPARAM)IdleServices[i]);
+ else
+ DestroyIcon(mi.hIcon);
+ }
+// return 0;
+}
+
+MIRANDASERVICE idleServiceNotIdle(WPARAM w, LPARAM l){
+ SimulateIdle(0);
+ return 0;
+};
+MIRANDASERVICE idleServiceShortIdle(WPARAM w, LPARAM l){
+ SimulateIdle(1);
+ return 0;
+};
+MIRANDASERVICE idleServiceLongIdle(WPARAM w, LPARAM l){
+ SimulateIdle(2);
+ return 0;
+};
+MIRANDASERVICE reconnectService(WPARAM w, LPARAM l){
+ int i;
+ for (i=0;i<protoCount;i++){
+ if (isInterestingProto(i)){
+ protoStatus[i]|=4;
+ }
+ }
+ return 0;
+};
diff --git a/plugins/SmartAutoAway/idleMessages.cpp b/plugins/SmartAutoAway/idleMessages.cpp
new file mode 100644
index 0000000000..3d712b0a6a
--- /dev/null
+++ b/plugins/SmartAutoAway/idleMessages.cpp
@@ -0,0 +1,282 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "globals.h"
+
+
+long *idleMessOptsPerm;
+long *idleMessOpts;
+ // xxxx xxxL xxxS xxxH xxxE xxx- RSTHERE-
+int *messCaps=0;
+
+ TCHAR **mesgHere;
+ TCHAR **mesgShort;
+ TCHAR **mesgLong;
+ TCHAR **mesgHerePerm;
+ TCHAR **mesgShortPerm;
+ TCHAR **mesgLongPerm;
+
+BOOL InitDialogIdleMessagePart(HWND hwndDlg)
+{
+ return TRUE;
+}
+
+void GetStringFromDelayMsg(char * str, int delay)
+{
+ int min,sec;
+ min = (int)delay/60;
+ sec = delay-min*60;
+ sprintf(str,"Set the default status message after ");
+ if (min) sprintf(str,"%s%d min ",str,min);
+ if (sec) sprintf(str,"%s%d sec",str,sec);
+// if (!min) sprintf(str,"%s (Too fast!)",str);
+}
+
+
+void moveScrollBarRestoreMsgEvent(HWND hwndDlg){
+ char str[256];
+ int slide = SendDlgItemMessage(hwndDlg,IDC_RESTOREMSGSLIDER,TBM_GETPOS,0,0);
+ int delay = GetReconnectDelayFromSlider(slide)/6;
+ GetStringFromDelayMsg(str,delay);
+ SetDlgItemTextA(hwndDlg,IDC_ENABLERESTOREMSG,str);
+ idleMessOpts[courProtocolSelection] = SetBits(idleMessOpts[courProtocolSelection],IdleMessOptsMaskRstHereDelay,delay);
+}
+
+
+static BOOL idleDialogInInit = FALSE;
+
+LRESULT SetDlgItemsIdleMessages(HWND hwndDlg, int coursel){
+ int i,t;
+ TCHAR str[64];
+ BOOL statusAvail[3];
+ for (i=0;i<3;i++) {
+ switch (i) {
+ case 0 : t = reqStatus[coursel]; break;
+ case 1 : t = aa_Status[GetBits(awayStatuses[coursel],maskShortAwayStatus)-1]; break;
+ case 2 : t = aa_Status[GetBits(awayStatuses[coursel],maskLongAwayStatus)-1]; break;
+ default: t = 0;
+ }
+ statusAvail[i] = messCaps[coursel] & Proto_Status2Flag(t);
+ _sntprintf(str,63,_T("%s"),CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, t, GCMDF_TCHAR));
+ switch (i) {
+ case 0 : _sntprintf(str,63,_T("%s: %s"),TranslateT("I am here"),CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, t, GCMDF_TCHAR));t = IDC_IDLEGROUP_HERE; break;
+ case 1 : _sntprintf(str,63,_T("%s: %s"),TranslateT("Short Idle"),CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, t, GCMDF_TCHAR));t = IDC_IDLEGROUP_SHORT; break;
+ case 2 : _sntprintf(str,63,_T("%s: %s"),TranslateT("Long Idle"),CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, t, GCMDF_TCHAR));t = IDC_IDLEGROUP_LONG; break;
+ default: t = 0;
+ }
+ SetDlgItemText(hwndDlg,t,str);
+ }
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEGROUP_HERE), messCaps[coursel]?1:0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEMSGHERE_THIS), statusAvail[0]?1:0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEMSGHERE), (statusAvail[0] && GetBits(idleMessOpts[coursel],IdleMessOptsMaskUseHere))?1:0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLERESTOREMSG), (statusAvail[0] && GetBits(idleMessOpts[coursel],IdleMessOptsMaskUseHere))?1:0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_RESTOREMSGSLIDER), (statusAvail[0] && GetBits(idleMessOpts[coursel],IdleMessOptsMaskUseHere) && GetBits(idleMessOpts[coursel],IdleMessOptsMaskRstHere))?1:0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEGROUP_SHORT), messCaps[coursel]?1:0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEMSGSHORT_THIS), statusAvail[1]?1:0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEMSGSHORT), (statusAvail[1] && GetBits(idleMessOpts[coursel],IdleMessOptsMaskUseShort))?1:0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEGROUP_LONG), messCaps[coursel]?1:0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEMSGLONG_THIS), statusAvail[2]?1:0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEMSGLONG), (statusAvail[2] && GetBits(idleMessOpts[coursel],IdleMessOptsMaskUseLong))?1:0);
+
+ CheckDlgButton(hwndDlg, IDC_IDLEMSGHERE_THIS, (statusAvail[0] && GetBits(idleMessOpts[coursel],IdleMessOptsMaskUseHere))?BST_CHECKED:BST_UNCHECKED );
+ CheckDlgButton(hwndDlg, IDC_ENABLERESTOREMSG, (
+ statusAvail[0] &&
+ GetBits(idleMessOpts[coursel],IdleMessOptsMaskUseHere) &&
+ GetBits(idleMessOpts[coursel],IdleMessOptsMaskRstHere))?BST_CHECKED:BST_UNCHECKED );
+ CheckDlgButton(hwndDlg, IDC_IDLEMSGSHORT_THIS, (statusAvail[1] && GetBits(idleMessOpts[coursel],IdleMessOptsMaskUseShort))?BST_CHECKED:BST_UNCHECKED );
+ CheckDlgButton(hwndDlg, IDC_IDLEMSGLONG_THIS, (statusAvail[2] && GetBits(idleMessOpts[coursel],IdleMessOptsMaskUseLong))?BST_CHECKED:BST_UNCHECKED );
+
+ SendDlgItemMessage(hwndDlg,IDC_RESTOREMSGSLIDER,TBM_SETPOS,TRUE,GetSliderFromReconnectDelay(GetBits(idleMessOpts[coursel],IdleMessOptsMaskRstHereDelay)*6));
+ moveScrollBarRestoreMsgEvent(hwndDlg);
+ idleDialogInInit = TRUE;
+ SetDlgItemText(hwndDlg,IDC_IDLEMSGHERE,mesgHere[coursel]);
+ SetDlgItemText(hwndDlg,IDC_IDLEMSGSHORT,mesgShort[coursel]);
+ SetDlgItemText(hwndDlg,IDC_IDLEMSGLONG,mesgLong[coursel]);
+ if (messCaps[coursel]) {
+ SetDlgItemTextA(hwndDlg,IDC_PROTODONOTSUPPORT,"");
+ } else {
+ _sntprintf(str,63,_T("%S cannot set status messages"),proto[coursel]->szName);
+ SetDlgItemText(hwndDlg,IDC_PROTODONOTSUPPORT,str);
+ }
+ idleDialogInInit = FALSE;
+ EnableWindow(GetDlgItem(hwndDlg, IDC_VARIABLES), (messCaps[coursel]));
+// CheckDlgButton(hwndDlg, IDC_ENABLERECONNECT, enabledReconnect?BST_CHECKED:BST_UNCHECKED );
+// CheckDlgButton(hwndDlg, IDC_NOTFATALERROR, dontReconnectOnFatalError?BST_CHECKED:BST_UNCHECKED );
+// EnableWindow(GetDlgItem(hwndDlg, IDC_RECONNECTSLIDER), enabledReconnect);
+// EnableWindow(GetDlgItem(hwndDlg, IDC_NOTFATALERROR), enabledReconnect);
+ return TRUE;
+}
+
+
+
+BOOL CALLBACK DlgProcOptsIdleMessages(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ SetDlgItemsIdleMessages(hwndDlg, courProtocolSelection);
+ return TRUE;
+ case WM_USER+1:
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_RESTOREMSGSLIDER), wParam);
+ idleMessOpts[courProtocolSelection] = SetBits(idleMessOpts[courProtocolSelection],IdleMessOptsMaskRstHere,wParam);
+ break;
+ }
+ case WM_USER+2:
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEMSGHERE), wParam);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_RESTOREMSGSLIDER), wParam);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLERESTOREMSG), wParam);
+ idleMessOpts[courProtocolSelection] = SetBits(idleMessOpts[courProtocolSelection],IdleMessOptsMaskUseHere,wParam);
+ break;
+ }
+ case WM_USER+3:
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEMSGSHORT), wParam);
+ idleMessOpts[courProtocolSelection] = SetBits(idleMessOpts[courProtocolSelection],IdleMessOptsMaskUseShort,wParam);
+ break;
+ }
+ case WM_USER+4:
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IDLEMSGLONG), wParam);
+ idleMessOpts[courProtocolSelection] = SetBits(idleMessOpts[courProtocolSelection],IdleMessOptsMaskUseLong,wParam);
+ break;
+ }
+ case WM_USER+8:
+ {
+ TCHAR temp[maxMessageLength+1];
+ ParseString((TCHAR *)lParam,temp,maxMessageLength);
+#ifdef UNICODE
+ if(!protoHasAwayMessageW[courProtocolSelection]) {
+ char tempa[maxMessageLength+1];
+ my_u2a(temp, tempa, maxMessageLength);
+ my_a2u(tempa,temp,maxMessageLength);
+ }
+#endif
+ SetDlgItemText(hwndDlg,IDC_PROTODONOTSUPPORT,temp);
+ break;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case IDC_ENABLERESTOREMSG:
+ {
+ SendMessage(hwndDlg, WM_USER+1, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_ENABLERESTOREMSG) == BST_CHECKED, 0);
+ break;
+ }
+ case IDC_IDLEMSGHERE_THIS:
+ {
+ SendMessage(hwndDlg,WM_USER+2, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_IDLEMSGHERE_THIS) == BST_CHECKED, 0);
+ break;
+ }
+ case IDC_IDLEMSGSHORT_THIS:
+ {
+ SendMessage(hwndDlg,WM_USER+3, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_IDLEMSGSHORT_THIS) == BST_CHECKED, 0);
+ break;
+ }
+ case IDC_IDLEMSGLONG_THIS:
+ {
+ SendMessage(hwndDlg,WM_USER+4, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_IDLEMSGLONG_THIS) == BST_CHECKED, 0);
+ break;
+ }
+ case IDC_IDLEMSGHERE:
+ {
+ if (HIWORD(wParam)==EN_CHANGE || HIWORD(wParam)==EN_SETFOCUS){
+ TCHAR str[maxMessageLength+1];
+ GetDlgItemText(hwndDlg,IDC_IDLEMSGHERE,str,maxMessageLength+1);
+ SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)str);
+ } else if (HIWORD(wParam)==EN_KILLFOCUS) {
+ GetDlgItemText(hwndDlg,IDC_IDLEMSGHERE,mesgHere[courProtocolSelection],maxMessageLength+1);
+ SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)"");
+ }
+ break;
+ }
+ case IDC_IDLEMSGSHORT:
+ {
+ if (HIWORD(wParam)==EN_CHANGE || HIWORD(wParam)==EN_SETFOCUS){
+ TCHAR str[maxMessageLength+1];
+ GetDlgItemText(hwndDlg,IDC_IDLEMSGSHORT,str,maxMessageLength+1);
+ SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)str);
+ } else if (HIWORD(wParam)==EN_KILLFOCUS) {
+ GetDlgItemText(hwndDlg,IDC_IDLEMSGSHORT,mesgShort[courProtocolSelection],maxMessageLength+1);
+ SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)"");
+ }
+ break;
+ }
+ case IDC_IDLEMSGLONG:
+ {
+ if (HIWORD(wParam)==EN_CHANGE || HIWORD(wParam)==EN_SETFOCUS){
+ TCHAR str[maxMessageLength+1];
+ GetDlgItemText(hwndDlg,IDC_IDLEMSGLONG,str,maxMessageLength+1);
+ SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)str);
+ } else if (HIWORD(wParam)==EN_KILLFOCUS) {
+ GetDlgItemText(hwndDlg,IDC_IDLEMSGLONG,mesgLong[courProtocolSelection],maxMessageLength+1);
+ SendMessage(hwndDlg,WM_USER+8, 0, (LPARAM)"");
+ }
+ break;
+ }
+ case IDC_VARIABLES:
+ {
+ TCHAR szout[2048]=_T("");
+ UINT pos=0;
+ for (int i=0;i<25;i++){
+ if (VariableList[i][0]){
+ pos+=_sntprintf(&szout[pos],2048-pos,_T("%%%s \t %s\n"),VariableList[i][0],TranslateTS(VariableList[i][1]));
+ } else {
+ pos+=_sntprintf(&szout[pos],2048-pos,_T("-- %s --\n"),TranslateTS(VariableList[i][1]));
+ }
+ }
+ //sprintf(szout,VARIABLE_LIST);
+ MessageBox(NULL,szout,TranslateT("Variables to use"),MB_OK|MB_TOPMOST);
+ break;
+ }
+
+ break; //case WM_COMMAND
+ }
+ if (!idleDialogInInit) if ((HIWORD(wParam)==BN_CLICKED)||(HIWORD(wParam)==EN_CHANGE))
+ {
+ if (LOWORD(wParam)!=IDC_VARIABLES)
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY: {
+ return TRUE;
+ }
+ }
+ break;
+ }
+ break;
+ case WM_HSCROLL:
+ if((HWND)lParam == GetDlgItem(hwndDlg, IDC_RESTOREMSGSLIDER)) {
+ moveScrollBarRestoreMsgEvent(hwndDlg);
+ if (LOWORD(wParam) == SB_ENDSCROLL) SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return FALSE;
+}
diff --git a/plugins/SmartAutoAway/long.ico b/plugins/SmartAutoAway/long.ico
new file mode 100644
index 0000000000..37845ebbb0
--- /dev/null
+++ b/plugins/SmartAutoAway/long.ico
Binary files differ
diff --git a/plugins/SmartAutoAway/reconnect.cpp b/plugins/SmartAutoAway/reconnect.cpp
new file mode 100644
index 0000000000..aad175c2f8
--- /dev/null
+++ b/plugins/SmartAutoAway/reconnect.cpp
@@ -0,0 +1,328 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "globals.h"
+
+long *reconnectOptsPerm=0;
+long *reconnectOpts=0;
+
+unsigned int *protoOfflineTimes=0;
+int *protoStatus=0; //0:OK; :1:couning; 2:fatalError; 4:reconnectForced
+
+
+void LoginAck(int protoIndex, ACKDATA * ack)
+{
+#ifdef AALOG
+ char log[1024];
+ sprintf(log,"LoginAck: %s: result: %d; hProcess: %d; lParam: %d;" ,
+ proto[protoIndex]->szName,
+ ack->result,ack->hProcess,ack->lParam
+// CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->hProcess, 0),
+// CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->lParam, 0)
+ );
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+#endif
+ if (ack->result == ACKRESULT_FAILED) switch (ack->lParam){
+ case LOGINERR_WRONGPASSWORD:
+ case LOGINERR_BADUSERID:
+ case LOGINERR_WRONGPROTOCOL:
+ case LOGINERR_OTHERLOCATION:
+ {
+#ifdef AALOG
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"LoginAck: FatalError occured");
+#endif
+ protoStatus[protoIndex]|=2;
+ protoOfflineTimes[protoIndex]=0;
+ return;
+ break;
+ }
+ }
+}
+
+
+void ProtocolsProc(int protoIndex, ACKDATA * ack)
+//ProtoProc: ICQ-AUX: result: 0; hProcess: Online; lParam: Offline;
+{
+#ifdef AALOG
+ char log[1024];
+ sprintf(log,"ProtoProc: %s: result: %d; hProcess: %s; lParam: %s; RequestedStatus: %s; AutoAwayStatus: %s" ,
+ proto[protoIndex]->szName,
+ ack->result,
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->hProcess, 0),
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)ack->lParam, 0),
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)reqStatus[protoIndex], 0),
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courAwayStatus[protoIndex], 0)
+ );
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+#endif
+ protoOfflineTimes[protoIndex]=0;
+ if (ack->lParam==ID_STATUS_OFFLINE) protoStatus[protoIndex]|=1; //will be counting, keeping eventual "FatalError" Flag
+ else protoStatus[protoIndex] = 0; //We are not offline or are connecting -> clear counting and "FatalError"
+#ifdef AALOG
+ sprintf(log,"ProtoProc: %s: Result: ProtoStatus: %d",
+ proto[protoIndex]->szName,protoStatus[protoIndex]);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+#endif
+
+}
+
+#ifdef AALOG
+#define AALOG2
+#endif
+int IsReconnectForbidden(int protoIndex){ //0 if it permitted
+#ifdef AALOG2
+ char str[256];
+#endif
+ if (!(protoStatus[protoIndex]&1)) return 1; //Proto is not counting or is not offline
+ protoOfflineTimes[protoIndex] += 2; //the timer ticks every 2 seconds
+ if (protoStatus[protoIndex]&4) { // Reconnect is forced
+#ifdef AALOG2
+ sprintf(str,"ReconnForbiddden: %s reconnection is forced.",proto[protoIndex]->szName);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ return 0;
+ }
+#ifdef AALOG2
+ sprintf(str,"ReconnForbiddden: %s is Offline and counting: %d to %d",proto[protoIndex]->szName,protoOfflineTimes[protoIndex],HIWORD(reconnectOptsPerm[protoIndex]));
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ if (protoOfflineTimes[protoIndex] <= HIWORD(reconnectOptsPerm[protoIndex])) return 2; // not yet
+ if (!(reconnectOptsPerm[protoIndex]&aa_ReconnectBitsEnabled)) return 3; //reconnect is disabled
+#ifdef AALOG2
+ sprintf(str,"ReconnForbiddden: %s has ReconnectEnabled",proto[protoIndex]->szName);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ if (protoStatus[protoIndex]&2) { //FatalError?
+#ifdef AALOG2
+ sprintf(str,"ReconnForbiddden: %s has FatalError; ProtoStatus: %d",proto[protoIndex]->szName,protoStatus[protoIndex]);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ if (reconnectOptsPerm[protoIndex]&aa_ReconnectNotFatalError) {
+#ifdef AALOG2
+ sprintf(str,"ReconnForbiddden: %s has DontReconnectOnFatalError",proto[protoIndex]->szName);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ return 4; //exit if "dontReconnectOnFatalError" enabled
+#ifdef AALOG2
+ } else {
+ sprintf(str,"ReconnForbiddden: %s has FatalError but DontReconnectOnFatalError disabled",proto[protoIndex]->szName);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ }
+ } //if FatalError
+ if (IsStatusBitSet(courAwayStatus[protoIndex],LOWORD(reconnectOptsPerm[protoIndex]))){ //is reconnect permited on this lastonline status?
+ //reconnecting...
+#ifdef AALOG2
+ sprintf(str,"ReconnForbiddden: %s Reconnect permitted",proto[protoIndex]->szName);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ return 0; // reconnect is permitted
+#ifdef AALOG2
+ } else {
+ sprintf(str,"ReconnForbiddden: %s Reconnecting to %s(%d) was not permited by %d",
+ proto[protoIndex]->szName,
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courAwayStatus[protoIndex], 0),
+ courAwayStatus[protoIndex],
+ reconnectOptsPerm[protoIndex]);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ }
+ return 5; // forbidden because current status is disabled
+}
+#undef AALOG2
+void TimerProc()
+{
+#ifdef AALOG
+ char str[256];
+#endif
+ int i;
+ for (i=0;i<protoCount;i++){
+ if (isInterestingProto(i)){
+#ifdef AALOG1
+ sprintf(str,"TimerProc: %s is a proto",proto[i]->szName);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ if (protoStatus[i]&1) {
+#ifdef AALOG1
+ sprintf(str,"TimerProc: %s is Counting: AwayStatus: %s; reqStatus: %s;",
+ proto[i]->szName,
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courAwayStatus[i], 0),
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)reqStatus[i], 0)
+ );
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ if ((courAwayStatus[i]==ID_STATUS_OFFLINE)||(reqStatus[i]==ID_STATUS_OFFLINE)){
+ protoStatus[i]&=2; //keeping fatalerror if any
+#ifdef AALOG
+ sprintf(str,"TimerProc: %s Counting Cancelled: AwayStatus: %s; reqStatus: %s;",
+ proto[i]->szName,
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)courAwayStatus[i], 0),
+ CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)reqStatus[i], 0)
+ );
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ }
+ }
+ switch (IsReconnectForbidden(i)) {
+#ifdef AALOG1
+ case 1 : sprintf(str,"IsReconnectForbidden: %s is not counting or is not offline",proto[i]->szName); break;
+ case 2 : sprintf(str,"IsReconnectForbidden: %s it is too early to reconnect",proto[i]->szName); break;
+ case 3 : sprintf(str,"IsReconnectForbidden: %s has reconnect disabled",proto[i]->szName); break;
+ case 4 : sprintf(str,"IsReconnectForbidden: %s fatal error and DontReconnect enabled",proto[i]->szName); break;
+ case 5 : sprintf(str,"IsReconnectForbidden: %s current AAStatus should not be reconnected",proto[i]->szName); break;
+#endif
+ case 0 :
+#ifdef AALOG
+ sprintf(str,"IsReconnectForbidden: %s is permited to reconnect",proto[i]->szName);
+#endif
+ CallProtoService(proto[i]->szName, PS_SETSTATUS, courAwayStatus[i], 0);
+ break;
+ default :
+#ifdef AALOG
+ sprintf(str,"IsReconnectForbidden: %s Surprising answer",proto[i]->szName);
+#endif
+ break;
+ }
+#ifdef AALOG1
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+#endif
+ }//protoType protocol
+ }//for
+}
+void moveScrollBarEvent(HWND hwndDlg){
+ TCHAR str[256];
+ int slide = SendDlgItemMessage(hwndDlg,IDC_RECONNECTSLIDER,TBM_GETPOS,0,0);
+ int delay = GetReconnectDelayFromSlider(slide);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_RECONNECTWARNING),GetStringFromDelay(str, delay)?SW_SHOW:SW_HIDE);
+ SetDlgItemText(hwndDlg,IDC_ENABLERECONNECT,str);
+ reconnectOpts[courProtocolSelection] = SetBits(reconnectOpts[courProtocolSelection],aa_ReconnectBitsDelay,delay);
+}
+
+LRESULT SetDlgItemsReconnect(HWND hwndDlg, int coursel){
+ BOOL enabledReconnect = GetBits(reconnectOpts[coursel],aa_ReconnectBitsEnabled);
+ BOOL dontReconnectOnFatalError = GetBits(reconnectOpts[coursel],aa_ReconnectNotFatalError);
+ int i =0;
+
+ for (i=0;i<numStatuses;i++){
+ BOOL bita = IsStatusBitSet(aa_Status[i],protoModes[coursel])==0;
+ BOOL bitr = IsStatusBitSet(aa_Status[i],reconnectOpts[coursel])>0;
+ EnableWindow(GetDlgItem(hwndDlg, aa_Status[i]+0x20), enabledReconnect);
+ StrikeOut(hwndDlg,aa_Status[i]+0x20,bita);
+ CheckDlgButton(hwndDlg, aa_Status[i]+0x20, bitr?BST_CHECKED:BST_UNCHECKED );
+ }
+ SendDlgItemMessage(hwndDlg,IDC_RECONNECTSLIDER,TBM_SETPOS,TRUE,GetSliderFromReconnectDelay(GetBits(reconnectOpts[coursel],aa_ReconnectBitsDelay)));
+ moveScrollBarEvent(hwndDlg);
+ CheckDlgButton(hwndDlg, IDC_ENABLERECONNECT, enabledReconnect?BST_CHECKED:BST_UNCHECKED );
+ CheckDlgButton(hwndDlg, IDC_NOTFATALERROR, dontReconnectOnFatalError?BST_CHECKED:BST_UNCHECKED );
+ EnableWindow(GetDlgItem(hwndDlg, IDC_RECONNECTSLIDER), enabledReconnect);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_NOTFATALERROR), enabledReconnect);
+ CheckDlgButton(hwndDlg, IDC_KEEPMAINSTATUSOFFLINE, (idleOpts&KeepMainStatusOffline)? BST_CHECKED : BST_UNCHECKED);
+ return TRUE;
+}
+
+
+BOOL CALLBACK DlgProcOptsReconnect(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ SetDlgItemsReconnect(hwndDlg, courProtocolSelection);
+ return TRUE;
+ case WM_USER+5:
+ {
+ int thebit = numStatuses-StatusToProtoIndex(LOWORD(lParam),allprotomodes);
+ int value = IsDlgButtonChecked(hwndDlg, LOWORD(lParam)+32)==BST_CHECKED;
+ thebit = 1<<thebit;
+ reconnectOpts[courProtocolSelection] =
+ SetBits(reconnectOpts[courProtocolSelection],
+ thebit,
+ value);
+ break;
+ }
+ case WM_USER+6:
+ {
+ reconnectOpts[courProtocolSelection] = SetBits(reconnectOpts[courProtocolSelection],aa_ReconnectBitsEnabled,wParam);
+ SetDlgItemsReconnect(hwndDlg,courProtocolSelection);
+ break;
+ }
+ case WM_USER+7:
+ {
+ reconnectOpts[courProtocolSelection] = SetBits(reconnectOpts[courProtocolSelection],aa_ReconnectNotFatalError,wParam);
+ SetDlgItemsReconnect(hwndDlg,courProtocolSelection);
+ break;
+ }
+ case WM_USER+8:
+ {
+ idleOpts = SetBits(idleOpts,KeepMainStatusOffline,wParam);
+ break;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam)) {
+ case ID_STATUS_AWAY+32:
+ case ID_STATUS_DND+32:
+ case ID_STATUS_NA+32:
+ case ID_STATUS_OCCUPIED+32:
+ case ID_STATUS_INVISIBLE+32:
+ case ID_STATUS_ONTHEPHONE+32:
+ case ID_STATUS_OUTTOLUNCH+32:
+ case ID_STATUS_ONLINE+32:
+ case ID_STATUS_FREECHAT+32:
+ case ID_STATUS_OFFLINE+32:
+ SendMessage(hwndDlg, WM_USER+5,0,(wParam-32)|0x00100000);
+ break;
+ case IDC_ENABLERECONNECT:
+ SendMessage(hwndDlg, WM_USER+6, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_ENABLERECONNECT) == BST_CHECKED, 0);
+ break;
+ case IDC_NOTFATALERROR:
+ SendMessage(hwndDlg, WM_USER+7, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_NOTFATALERROR) == BST_CHECKED, 0);
+ break;
+ case IDC_KEEPMAINSTATUSOFFLINE:
+ SendMessage(hwndDlg, WM_USER+8, (WPARAM)IsDlgButtonChecked(hwndDlg, IDC_KEEPMAINSTATUSOFFLINE) == BST_CHECKED, 0);
+ break;
+ }
+ if (HIWORD(wParam)==BN_CLICKED)
+ {
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, (unsigned int)hwndDlg, 0);
+ }
+ break;
+ case WM_NOTIFY:
+ switch (((LPNMHDR) lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR) lParam)->code) {
+ case PSN_APPLY: {
+ return TRUE;
+ }
+ }
+ break;
+ }
+ break;
+ case WM_HSCROLL:
+ if((HWND)lParam == GetDlgItem(hwndDlg, IDC_RECONNECTSLIDER)) {
+ moveScrollBarEvent(hwndDlg);
+ if (LOWORD(wParam) == SB_ENDSCROLL) SendMessage(GetParent(hwndDlg), PSM_CHANGED, (unsigned int)hwndDlg, 0);
+ }
+ break;
+ case WM_DESTROY:
+ break;
+ }
+ return FALSE;
+}
diff --git a/plugins/SmartAutoAway/reconnect.ico b/plugins/SmartAutoAway/reconnect.ico
new file mode 100644
index 0000000000..ee4092e593
--- /dev/null
+++ b/plugins/SmartAutoAway/reconnect.ico
Binary files differ
diff --git a/plugins/SmartAutoAway/resource.h b/plugins/SmartAutoAway/resource.h
new file mode 100644
index 0000000000..5473b9529e
--- /dev/null
+++ b/plugins/SmartAutoAway/resource.h
@@ -0,0 +1,77 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by saa-res.rc
+//
+#define IDR_MENUIDLE 101
+#define IDD_OPT_SAA_AA 301
+#define IDD_OPT_SAA_RECONNECT 302
+#define IDD_OPT_SAA_IDLE 303
+#define IDD_OPT_SAA_IDLEMESSAGES 304
+#define IDD_OPT_SMARTAUTOAWAY 202
+#define IDC_OPT_SAA_TAB 1000
+#define IDC_IDLEGROUP_HERE 1001
+#define IDC_IDLEGROUP_SHORT 1002
+#define IDC_IDLEGROUP_LONG 1003
+#define IDC_IDLEMSGHERE_THIS 1004
+#define IDC_IDLEMSGSHORT_THIS 1006
+#define IDC_IDLEMSGHERE 1007
+#define IDC_IDLEMSGSHORT 1008
+#define IDC_IDLEMSGLONG 1009
+#define IDC_IDLEMSGLONG_THIS 1011
+#define IDC_ENABLERESTOREMSG 1012
+#define IDC_RESTOREMSGSLIDER 1013
+#define IDC_PROTODONOTSUPPORT 1014
+#define IDC_VARIABLES 1015
+#define IDC_IDLEBUTTON 1500
+#define IDC_IDLECHECK 1636
+#define IDC_IDLEONWINDOWS 1637
+#define IDC_IDLEONMIRANDA 1638
+#define IDC_IDLEUSEGLI 1639
+#define IDC_DISBABLEAUTOHERE 1640
+#define IDC_SCREENSAVER 1642
+#define IDC_LOCKED 1643
+#define IDC_IDLESHORT 1644
+#define IDC_IDLELONG 1645
+#define IDC_IDLE1STTIME 1646
+#define IDC_IDLE2NDTIME 1647
+#define IDC_IDLEPRIVATE 1649
+#define IDC_AASTATUS 1650
+#define IDC_AASHORTIDLE 1651
+#define IDC_AALONGSTATUS 1652
+#define IDC_AAPROTOCOL 1653
+#define IDC_AALONGIDLE 1656
+#define IDC_COURSTATUSLABEL 1657
+#define IDC_REQSTATUSLABEL 1658
+#define IDC_ENABLERECONNECT 1660
+#define IDC_RECONNECTSLIDER 1663
+#define IDC_NOTFATALERROR 1664
+#define IDC_RECONNECTWARNING 1665
+#define IDC_APPLYTOALL 1667
+#define IDC_KEEPMAINSTATUSOFFLINE 1671
+#define IDC_DISABLEIDLEMENU 1672
+#define IDC_HEREONSTATUSCHANGE 1673
+#define IDI_IDLE_HERE 10101
+#define IDI_IDLE_SHORT 10102
+#define IDI_IDLE_LONG 10103
+#define IDI_RECONNECT 10104
+#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
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 10104
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1016
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/SmartAutoAway/saa-res.rc b/plugins/SmartAutoAway/saa-res.rc
new file mode 100644
index 0000000000..98549fa59b
--- /dev/null
+++ b/plugins/SmartAutoAway/saa-res.rc
@@ -0,0 +1,238 @@
+//Microsoft Developer Studio generated resource script.
+//
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "resource.h"
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#pragma code_page(1251)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_OPT_SMARTAUTOAWAY DIALOGEX 0, 0, 313, 247
+STYLE DS_FIXEDSYS | DS_CENTER | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CTEXT "Static",IDC_REQSTATUSLABEL,246,1,66,9,0,WS_EX_STATICEDGE
+ RTEXT "Requested Status:",IDC_STATIC,164,1,80,8
+ CTEXT "Static",IDC_COURSTATUSLABEL,246,11,66,9,0,WS_EX_STATICEDGE
+ RTEXT "Current Status:",IDC_STATIC,181,12,63,8
+ COMBOBOX IDC_AAPROTOCOL,8,1,65,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CONTROL "",IDC_OPT_SAA_TAB,"SysTabControl32",0x0,20,23,273,216,0//WS_EX_ACCEPTFILES
+ PUSHBUTTON "Apply to all protocols",IDC_APPLYTOALL,76,1,81,12
+END
+
+IDD_OPT_SAA_AA DIALOGEX 0, 0, 256, 191
+STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Short Idle",IDC_STATIC,0,0,256,93,BS_CENTER
+ CONTROL "Change my status mode to:",IDC_AASHORTIDLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,14,116,11
+ COMBOBOX IDC_AASTATUS,132,13,75,12,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Only if my requested status is:",IDC_STATIC,0,32,256,61
+ CONTROL "Online",ID_STATUS_ONLINE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,47,65,10
+ CONTROL "Away",ID_STATUS_AWAY,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,60,65,10
+ CONTROL "N/A",ID_STATUS_NA,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,72,65,10
+ CONTROL "Invisible",ID_STATUS_INVISIBLE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,47,65,10
+ CONTROL "Occupied",ID_STATUS_OCCUPIED,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,60,65,10
+ CONTROL "DND",ID_STATUS_DND,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,72,65,13
+ CONTROL "On the phone",ID_STATUS_ONTHEPHONE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,39,65,10
+ CONTROL "Out to lunch",ID_STATUS_OUTTOLUNCH,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,52,65,10
+ CONTROL "Free for chat",ID_STATUS_FREECHAT,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,66,65,10
+ CONTROL "Offline",ID_STATUS_OFFLINE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,78,65,10
+ GROUPBOX "Long Idle",IDC_STATIC,0,98,256,93,BS_CENTER
+ CONTROL "Change my status mode to:",IDC_AALONGIDLE,"Button",BS_AUTOCHECKBOX | BS_RIGHT | WS_TABSTOP,9,110,101,11
+ COMBOBOX IDC_AALONGSTATUS,132,109,75,16,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Only if my requested status is:",IDC_STATIC,0,130,256,61
+ CONTROL "Online",40088,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,145,65,10
+ CONTROL "Away",40089,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,158,65,10
+ CONTROL "N/A",40091,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,171,65,10
+ CONTROL "Invisible",40094,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,145,65,10
+ CONTROL "Occupied",40092,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,158,65,10
+ CONTROL "DND",40090,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,172,65,10
+ CONTROL "On the phone",40095,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,137,65,10
+ CONTROL "Out to lunch",40096,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,150,65,10
+ CONTROL "Free for chat",40093,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,163,65,10
+ CONTROL "Offline",40087,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,176,65,10
+END
+
+IDD_OPT_SAA_RECONNECT DIALOGEX 0, 0, 256, 164
+STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "",IDC_STATIC,0,0,256,114,BS_CENTER
+ CONTROL "reconnect after",IDC_ENABLERECONNECT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,9,150,10
+ CONTROL "Slider2",IDC_RECONNECTSLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,1,22,253,10
+ GROUPBOX "If my current status is:",IDC_STATIC,0,37,256,52,BS_CENTER
+ RTEXT "Too Fast!",IDC_RECONNECTWARNING,160,10,91,8,NOT WS_VISIBLE
+ CONTROL "Online",40104,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,47,65,10
+ CONTROL "Away",40105,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,60,65,10
+ CONTROL "N/A",40107,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,74,65,10
+ CONTROL "Invisible",40110,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,47,65,10
+ CONTROL "Occupied",40108,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,60,65,10
+ CONTROL "DND",40106,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,84,74,65,10
+ CONTROL "On the phone",40111,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,47,65,10
+ CONTROL "Out to lunch",40112,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,60,65,10
+ CONTROL "Free for chat",40109,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,169,74,65,10
+ CONTROL "Do not reconnect after fatal error",IDC_NOTFATALERROR,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,9,96,133,10
+ GROUPBOX "",IDC_STATIC,0,126,254,38
+ CONTROL "Keep main status offline*",IDC_KEEPMAINSTATUSOFFLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,138,133,10
+ LTEXT "* Setting this option may confuse other plugins",IDC_STATIC,9,150,200,8
+END
+
+IDD_OPT_SAA_IDLE DIALOGEX 0, 0, 256, 196
+STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Idle",IDC_STATIC,0,0,255,142,BS_CENTER
+ CONTROL "Enable",IDC_IDLECHECK,"Button",BS_AUTOCHECKBOX |WS_TABSTOP,8,12,43,11
+ CONTROL "If Windows is inactive",IDC_IDLEONWINDOWS,"Button",BS_AUTORADIOBUTTON,62,13,110,9
+ CONTROL "If Miranda is inactive",IDC_IDLEONMIRANDA,"Button",BS_AUTORADIOBUTTON,62,37,104,9
+ CONTROL "Use GetLastInputInfo()",IDC_IDLEUSEGLI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,75,24,87,9
+ GROUPBOX "Force short idle if:",IDC_STATIC,0,54,129,38
+ CONTROL "Screen Saver is running",IDC_SCREENSAVER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,65,111,9
+ CONTROL "Workstation is Locked (2K/XP)",IDC_LOCKED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,78,113,9
+ GROUPBOX "Inactivity times:",IDC_STATIC,128,54,127,38
+ CONTROL "Short idle after",IDC_IDLESHORT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,137,65,59,9
+ EDITTEXT IDC_IDLE1STTIME,206,63,16,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "Long idle after",IDC_IDLELONG,"Button",BS_AUTOCHECKBOX |WS_TABSTOP,137,78,59,9
+ EDITTEXT IDC_IDLE2NDTIME,206,76,16,12,ES_AUTOHSCROLL | ES_NUMBER
+ LTEXT "min.",IDC_STATIC,223,65,24,9
+ LTEXT "min.",IDC_STATIC,223,78,23,9
+ CONTROL "Do not share my idle info.",IDC_IDLEPRIVATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,63,97,151,10
+ CONTROL "Do not set ""Not Idle"" automaticaly",IDC_DISBABLEAUTOHERE,"Button",BS_AUTOCHECKBOX |WS_TABSTOP,63,111,158,10
+ CONTROL "Set ""Not Idle"" on manual status change",IDC_HEREONSTATUSCHANGE,"Button",BS_AUTOCHECKBOX |WS_TABSTOP,63,125,158,10
+ GROUPBOX "Simulate Idle",IDC_STATIC,0,146,255,50
+ PUSHBUTTON "Be Not Idle",IDC_IDLEBUTTON,29,162,55,12
+ PUSHBUTTON "Be Short Idle",IDC_IDLEBUTTON+1,95,162,55,12
+ PUSHBUTTON "Be Long Idle",IDC_IDLEBUTTON+2,161,162,55,12
+ CONTROL "Disable Idle menu. (restart is required)",IDC_DISABLEIDLEMENU,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,63,179,158,10
+END
+
+IDD_OPT_SAA_IDLEMESSAGES DIALOGEX 0, 0, 251, 166
+STYLE DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "",IDC_IDLEGROUP_HERE,6,3,239,63
+ CONTROL "Use:",IDC_IDLEMSGHERE_THIS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,14,31,10
+ EDITTEXT IDC_IDLEMSGHERE,70,14,169,21,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL
+ CONTROL "",IDC_ENABLERESTOREMSG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,39,230,10
+ CONTROL "Slider2",IDC_RESTOREMSGSLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,8,51,236,10
+ GROUPBOX "",IDC_IDLEGROUP_SHORT,6,68,239,36
+ CONTROL "Use:",IDC_IDLEMSGSHORT_THIS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,80,31,10
+ EDITTEXT IDC_IDLEMSGSHORT,70,79,169,21,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL
+ GROUPBOX "",IDC_IDLEGROUP_LONG,6,108,239,36
+ CONTROL "Use:",IDC_IDLEMSGLONG_THIS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,119,31,10
+ EDITTEXT IDC_IDLEMSGLONG,70,119,169,21,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL
+ LTEXT "",IDC_PROTODONOTSUPPORT,12,148,204,18
+ PUSHBUTTON "?",IDC_VARIABLES,223,149,22,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO MOVEABLE PURE
+BEGIN
+ IDD_OPT_SMARTAUTOAWAY, DIALOG
+ BEGIN
+ BOTTOMMARGIN, 246
+ END
+
+ IDD_OPT_SAA_AA, DIALOG
+ BEGIN
+ VERTGUIDE, 9
+ VERTGUIDE, 84
+ VERTGUIDE, 169
+ HORZGUIDE, 19
+ HORZGUIDE, 32
+ HORZGUIDE, 39
+ HORZGUIDE, 52
+ HORZGUIDE, 65
+ HORZGUIDE, 78
+ HORZGUIDE, 93
+ HORZGUIDE, 98
+ HORZGUIDE, 115
+ HORZGUIDE, 130
+ HORZGUIDE, 137
+ HORZGUIDE, 150
+ HORZGUIDE, 163
+ HORZGUIDE, 176
+ END
+
+ IDD_OPT_SAA_RECONNECT, DIALOG
+ BEGIN
+ VERTGUIDE, 9
+ VERTGUIDE, 84
+ VERTGUIDE, 169
+ HORZGUIDE, 14
+ HORZGUIDE, 37
+ HORZGUIDE, 52
+ HORZGUIDE, 65
+ HORZGUIDE, 79
+ END
+
+ IDD_OPT_SAA_IDLE, DIALOG
+ BEGIN
+ VERTGUIDE, 8
+ HORZGUIDE, 17
+ HORZGUIDE, 54
+ HORZGUIDE, 67
+ END
+
+ IDD_OPT_SAA_IDLEMESSAGES, DIALOG
+ BEGIN
+ VERTGUIDE, 6
+ VERTGUIDE, 12
+ VERTGUIDE, 70
+ VERTGUIDE, 245
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_IDLE_HERE ICON DISCARDABLE "here.ico"
+IDI_IDLE_SHORT ICON DISCARDABLE "short.ico"
+IDI_IDLE_LONG ICON DISCARDABLE "long.ico"
+IDI_RECONNECT ICON DISCARDABLE "reconnect.ico"
+#endif // Neutral resources
+/////////////////////////////////////////////////////////////////////////////
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/SmartAutoAway/saa.cpp b/plugins/SmartAutoAway/saa.cpp
new file mode 100644
index 0000000000..b48b474faa
--- /dev/null
+++ b/plugins/SmartAutoAway/saa.cpp
@@ -0,0 +1,130 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "saa.h"
+
+int InitVariables( WPARAM wParam, LPARAM lParam );
+
+
+PLUGINLINK *pluginLink;
+HINSTANCE g_hInst;
+
+PLUGININFOEX pluginInfo = {
+ sizeof(PLUGININFOEX),
+#ifdef AALOG
+ SECTIONNAME " - Debug",
+#else
+ SECTIONNAME,
+#endif
+#include "version.txt"
+ UNICODE_AWARE,
+ DEFMOD_RNDAUTOAWAY, // replace internal version (if any)
+#if defined( _UNICODE )
+ {0xec29e895,0x9f97,0x4cb1,{0xac, 0x9b, 0xb1, 0xae, 0x88, 0x25, 0x8b, 0x4a} /* EC29E895-9F97-4cb1-AC9B-B1AE88258B4A */}
+#else
+ {0x19c5be89,0xf7e3,0x4632,{0xa1, 0x25, 0x15, 0xf3, 0x84, 0xcd, 0x0c, 0xd3} /* 19c5be89-f7e3-4632-a125-15f384cd0cd3 */}
+#endif
+};
+
+static HMODULE hUxTheme = 0;
+BOOL (WINAPI *enableThemeDialogTexture)(HANDLE, DWORD) = 0;
+
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ g_hInst = hinstDLL;
+ return TRUE;
+}
+static char description[1023];
+
+#ifdef AALOG
+ static BOOL warningShown = 0;
+#endif
+static bool isNewMiranda = false;
+extern "C" __declspec(dllexport) PLUGININFOEX *MirandaPluginInfo(DWORD mirandaVersion)
+{
+
+ sprintf(description,"Highly configurable AutoAway/Idle/Reconnect system");
+#ifdef AALOG
+ sprintf(description,"%s\r\nThis is the debug version. It will make a lot of noise through Netlib log",description);
+ if (!warningShown) {
+ MessageBoxA(0,description,pluginInfo.shortName,MB_ICONINFORMATION);
+ warningShown = 1;
+ }
+#endif
+ if ((mirandaVersion>=0x00030400) && (!isNewMiranda)) {
+ sprintf(description,"%s\r\n%s",description,"Miranda %d.%d.%d.%d has build-in \"Idle\" support and it is highly advisable to suppress it by putting SAANI.dll in plugins directory.");
+ sprintf(description,description, // Yes, I realize this is strange approach...
+ mirandaVersion>>24&0xFF,
+ mirandaVersion>>16&0xFF,
+ mirandaVersion>>8&0xFF,
+ mirandaVersion&0xFF
+ );
+ };
+ sprintf(description,"%s\r\n[Build %s %s]",description, __DATE__,__TIME__);
+ pluginInfo.description = description;
+ if ( mirandaVersion < PLUGIN_MAKE_VERSION( 0,7,0,17 )) pluginInfo.cbSize = sizeof( PLUGININFO );
+ return &pluginInfo;
+}
+
+extern "C" __declspec(dllexport) PLUGININFOEX * MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ isNewMiranda=true;
+ return MirandaPluginInfo(mirandaVersion);
+}
+
+static const MUUID interfaces[] = {MIID_AUTOAWAY, MIID_IDLE, MIID_LAST};
+extern "C" __declspec(dllexport) const MUUID * MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+extern "C" int __declspec(dllexport) Load(PLUGINLINK * link)
+{
+ pluginLink = link;
+ LoadAutoAwayModule();
+ hUxTheme = GetModuleHandle(_T("uxtheme.dll"));
+ if(hUxTheme)
+ enableThemeDialogTexture = (BOOL (WINAPI *)(HANDLE, DWORD))GetProcAddress(hUxTheme, "EnableThemeDialogTexture");
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Unload(void)
+{
+// AutoAwayShutdown(0,0);
+//#ifdef AALOG
+// CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"Killing Timer");
+//#endif
+// KillTimer(NULL, hIdleTimer);
+//#ifdef AALOG
+// CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"DestroyHookableEvent(hIdleEvent)");
+//#endif
+// DestroyHookableEvent(hIdleEvent);
+
+ if(hUxTheme != 0)
+ FreeLibrary(hUxTheme);
+
+ return 1; //if 1 we dont want to shutdown because we have hooked ME_SYSTEM_SHUTDOWN
+}
+
+
diff --git a/plugins/SmartAutoAway/saa.dsp b/plugins/SmartAutoAway/saa.dsp
new file mode 100644
index 0000000000..949d67f78f
--- /dev/null
+++ b/plugins/SmartAutoAway/saa.dsp
@@ -0,0 +1,291 @@
+# Microsoft Developer Studio Project File - Name="saa" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=saa - Win32 Debug Unicode
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "saa.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "saa.mak" CFG="saa - Win32 Debug Unicode"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "saa - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "saa - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "saa - Win32 Logging" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "saa - Win32 Debug Unicode" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "saa - Win32 Release Unicode" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "saa - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleasePlugin"
+# PROP Intermediate_Dir "ReleasePlugin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SAA_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x402 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/release/plugins/saa.dll" /FILEALIGN:0x200
+# SUBTRACT LINK32 /pdb:none
+# Begin Special Build Tool
+SOURCE="$(InputPath)"
+PostBuild_Cmds=upx --best --lzma --force ../../bin/release/plugins/saa.dll
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "saa - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "saa___Win32_Debug"
+# PROP BASE Intermediate_Dir "saa___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugPlugin"
+# PROP Intermediate_Dir "DebugPlugin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SAA_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x402 /d "_DEBUG"
+# ADD RSC /l 0x417 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /debug /machine:I386 /out:"../../Bin/debug/Plugins/saa.dll" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "saa - Win32 Logging"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "saa___Win32_Logging"
+# PROP BASE Intermediate_Dir "saa___Win32_Logging"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Logging"
+# PROP Intermediate_Dir "Logging"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O1 /D "SAA_PLUGIN" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O1 /I "../../include" /D "SAA_PLUGIN" /D "AALOG" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x402 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/release/plugins/saa.dll"
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/logging/plugins/saa.dll"
+# Begin Special Build Tool
+SOURCE="$(InputPath)"
+PostBuild_Cmds=upx --best --lzma --force ../../bin/logging/plugins/saa.dll
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "saa - Win32 Debug Unicode"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "saa___Win32_Debug_Unicode"
+# PROP BASE Intermediate_Dir "saa___Win32_Debug_Unicode"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug_Unicode"
+# PROP Intermediate_Dir "Debug_Unicode"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "UNICODE" /D "_USRDLL" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x417 /d "_DEBUG"
+# ADD RSC /l 0x417 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /debug /machine:I386 /out:"../../Bin/debug/Plugins/saa.dll" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /debug /machine:I386 /out:"../../Bin/debug Unicode/Plugins/saa.dll" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "saa - Win32 Release Unicode"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "saa___Win32_Release_Unicode"
+# PROP BASE Intermediate_Dir "saa___Win32_Release_Unicode"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_Unicode"
+# PROP Intermediate_Dir "Release_Unicode"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /c
+# ADD CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /I "../../include" /D "SAA_PLUGIN" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "UNICODE" /D "_USRDLL" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x417 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/release/plugins/saa.dll" /FILEALIGN:0x200
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/Release Unicode/plugins/saa.dll" /FILEALIGN:0x200
+# SUBTRACT LINK32 /pdb:none
+# Begin Special Build Tool
+SOURCE="$(InputPath)"
+PostBuild_Cmds=upx --best --force ../../bin/"Release Unicode"/plugins/saa.dll
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "saa - Win32 Release"
+# Name "saa - Win32 Debug"
+# Name "saa - Win32 Logging"
+# Name "saa - Win32 Debug Unicode"
+# Name "saa - Win32 Release Unicode"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\aa_utils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\autoaway.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\dlgproc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\globals.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\idle.cpp
+
+!IF "$(CFG)" == "saa - Win32 Release"
+
+!ELSEIF "$(CFG)" == "saa - Win32 Debug"
+
+# SUBTRACT CPP /YX
+
+!ELSEIF "$(CFG)" == "saa - Win32 Logging"
+
+!ELSEIF "$(CFG)" == "saa - Win32 Debug Unicode"
+
+# SUBTRACT BASE CPP /YX
+# SUBTRACT CPP /YX
+
+!ELSEIF "$(CFG)" == "saa - Win32 Release Unicode"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\idleMenu.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\idleMessages.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\reconnect.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\saa.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\saamain.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\globals.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\here.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\long.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\reconnect.ico
+# End Source File
+# Begin Source File
+
+SOURCE=".\saa-res.rc"
+# End Source File
+# Begin Source File
+
+SOURCE=.\short.ico
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/plugins/SmartAutoAway/saa.dsw b/plugins/SmartAutoAway/saa.dsw
new file mode 100644
index 0000000000..d39bc38701
--- /dev/null
+++ b/plugins/SmartAutoAway/saa.dsw
@@ -0,0 +1,41 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "saa"=".\saa.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "saani"=".\saani.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/plugins/SmartAutoAway/saa.h b/plugins/SmartAutoAway/saa.h
new file mode 100644
index 0000000000..b59f155202
--- /dev/null
+++ b/plugins/SmartAutoAway/saa.h
@@ -0,0 +1 @@
+#include "globals.h"
diff --git a/plugins/SmartAutoAway/saamain.cpp b/plugins/SmartAutoAway/saamain.cpp
new file mode 100644
index 0000000000..0dee323c28
--- /dev/null
+++ b/plugins/SmartAutoAway/saamain.cpp
@@ -0,0 +1,415 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+#include "globals.h"
+
+#ifdef SAA_PLUGIN
+ struct MM_INTERFACE memoryManagerInterface;
+#endif
+
+HANDLE hService[5];
+HANDLE hHooks[6];
+
+#ifndef SAA_PLUGIN
+ int LoadIdleModule(void){return 0;}
+ int UnloadIdleModule(void){return 0;}
+#endif
+
+int LoadAutoAwayModule(void)
+{
+
+#ifdef SAA_PLUGIN
+ memset(&memoryManagerInterface, 0, sizeof(memoryManagerInterface));
+ memoryManagerInterface.cbSize = sizeof(memoryManagerInterface);
+ CallService(MS_SYSTEM_GET_MMI, 0, (LPARAM) &memoryManagerInterface);
+#endif
+
+ hHooks[0] = HookEvent(ME_SYSTEM_MODULESLOADED,InitVariables);
+ hIdleEvent = CreateHookableEvent(ME_IDLE_CHANGED);
+ hHooks[1] = HookEvent(ME_OPT_INITIALISE,AutoAwayOptInitialise);
+ MyGetLastInputInfo=(BOOL (WINAPI *)(PLASTINPUTINFO)) GetProcAddress( GetModuleHandleA("user32"),"GetLastInputInfo" );
+ // load settings into live ones
+ idleOpts = idleOptsPerm=DBGetContactSettingDword(NULL, AA_MODULE,AA_IDLEOPTIONS,idleOptsDefault);
+// if ((idleOptsPerm&IdleSuppressIdleMenu)==0) AddIdleMenu();
+// idleCheckPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLECHECK, 0);
+// idleMethodPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLEMETHOD, 0);
+// idleGLIPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLEGLI, 1);
+// idleTimeFirstPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLETIME1ST, 10);
+// idleTimeSecondPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLETIME2ND, 30);
+// idleTimeFirstOnPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLETIME1STON, 0);
+// idleTimeSecondOnPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLETIME2NDON, 0);
+// idleOnSaverPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLEONSAVER, 0);
+// idleOnLockPerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLEONLOCK, 0);
+// idlePrivatePerm = DBGetContactSettingByte(NULL, IDLEMODULE, IDL_IDLEPRIVATE, 0);
+ hService[0] = CreateServiceFunction(MS_IDLE_GETIDLEINFO, IdleGetInfo);
+
+ hHooks[2] = HookEvent(ME_SYSTEM_SHUTDOWN,AutoAwayShutdown);
+ hHooks[3] = HookEvent(ME_IDLE_CHANGED, AutoAwayEvent);
+ hHooks[4] = HookEvent(ME_CLIST_STATUSMODECHANGE,StatusModeChangeEvent);
+ hHooks[5] = HookEvent(ME_PROTO_ACK, ProtoAckEvent);
+
+ hService[1] = CreateServiceFunction(AA_IDLE_BENOTIDLESERVICE,(MIRANDASERVICE)idleServiceNotIdle);
+ hService[2] = CreateServiceFunction(AA_IDLE_BESHORTIDLESERVICE,(MIRANDASERVICE)idleServiceShortIdle);
+ hService[3] = CreateServiceFunction(AA_IDLE_BELONGIDLESERVICE,(MIRANDASERVICE)idleServiceLongIdle);
+ hService[4] = CreateServiceFunction(AA_IDLE_RECONNECTSERVICE,(MIRANDASERVICE)reconnectService);
+ return 0;
+}
+
+int InitVariables( WPARAM wParam, LPARAM lParam )
+{
+ int j=0;
+ int i=0;
+ localeID = CallService(MS_LANGPACK_GETLOCALE,0,0);
+ if (localeID==CALLSERVICE_NOTFOUND) localeID=LOCALE_USER_DEFAULT;
+ codePage = CallService(MS_LANGPACK_GETCODEPAGE,0,0);
+ if (codePage==CALLSERVICE_NOTFOUND) codePage=CP_ACP;
+#ifdef UNICODE
+ HasAwayMessageW = (ServiceExists(MS_AWAYMSG_GETSTATUSMSGW)!=0);
+#endif
+ if (ServiceExists(MS_HOTKEY_REGISTER)){
+ for (i=0;i<4;i++) {
+ CallService(MS_HOTKEY_REGISTER, 0, (LPARAM) &hotkeydescs[i]);
+ }
+ }
+
+
+#ifdef AALOG
+ {
+ NETLIBUSER nlu = { 0 };
+ nlu.cbSize = sizeof(nlu);
+ nlu.szSettingsModule = "SAA";
+ nlu.flags=NUF_NOOPTIONS | NUF_NOHTTPSOPTION;
+ nlu.szDescriptiveName = Translate(SECTIONNAME " Module");
+ hNetlib = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) & nlu);
+ }
+ {
+ SYSTEMTIME st={0};
+ int drift;
+ char str[32];
+ char log[1024];
+ char target[1024];
+ drift = GetTimeZone(str);
+ GetLastActiveLocalTime(&st,0);
+ sprintf(log,"Now is %02d/%02d/%02d %02d:%02d:%02d %s (%02d:%02d)",
+ st.wYear, st.wMonth, st.wDay,
+ st.wHour, st.wMinute, st.wSecond,str,
+ div(drift,60).quot,drift<0?-div(drift,60).rem:div(drift,60).rem);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+ GetLastActiveLocalTime(&st,24*60*60*1000);
+ sprintf(log,"1 day ago was %02d/%02d/%02d %02d:%02d:%02d %s (%02d:%02d)",
+ st.wYear, st.wMonth, st.wDay,
+ st.wHour, st.wMinute, st.wSecond,str,
+ div(drift,60).quot,drift<0?-div(drift,60).rem:div(drift,60).rem);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+ ParseString("%Y-%m-%d %H:%M:%S",target,1023);
+ sprintf(log,"Testing ParseString: %s",target);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+ ParseString("%E/%d/%y %W %h:%M:%S %p",target,1023);
+ sprintf(log,"Testing ParseString: %s",target);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+ ParseString("%w %% %Z (%z)%n%L%b%l%b%K%b%k",target,1023);
+ sprintf(log,"Testing ParseString: %s",target);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+ }
+#endif
+
+ CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM)&protoCount,(LPARAM)&proto);
+ reqStatus = (int *)mir_alloc((protoCount)*sizeof(reqStatus[0]));
+ courStatus = (int *)mir_alloc((protoCount)*sizeof(courStatus[0]));
+ courAwayStatus = (int *)mir_alloc((protoCount)*sizeof(courStatus[0]));
+ protoModes = (int *)mir_alloc((protoCount)*sizeof(protoModes[0]));
+ messCaps = (int *)mir_alloc((protoCount)*sizeof(messCaps[0]));
+
+ awayStatuses=(short int *)mir_alloc((protoCount)*sizeof(awayStatuses[0]));
+ onlyIfBits=(long int *)mir_alloc((protoCount)*sizeof(onlyIfBits[0]));
+ awayStatusesPerm=(short int *)mir_alloc((protoCount)*sizeof(awayStatuses[0]));
+ onlyIfBitsPerm=(long int *)mir_alloc((protoCount)*sizeof(onlyIfBits[0]));
+
+ reconnectOpts=(long int *)mir_alloc((protoCount)*sizeof(reconnectOpts[0]));
+ reconnectOptsPerm=(long int *)mir_alloc((protoCount)*sizeof(reconnectOptsPerm[0]));
+ protoOfflineTimes=(unsigned int *)mir_alloc((protoCount)*sizeof(protoOfflineTimes[0]));
+ protoStatus=(int *)mir_alloc((protoCount)*sizeof(protoStatus[0]));
+
+ idleMessOpts=(long int *)mir_alloc((protoCount)*sizeof(idleMessOpts[0]));
+ idleMessOptsPerm=(long int *)mir_alloc((protoCount)*sizeof(idleMessOptsPerm[0]));
+
+ mesgHere = (TCHAR**)mir_alloc(protoCount * sizeof(mesgHere[0]));
+ mesgHerePerm = (TCHAR**)mir_alloc(protoCount * sizeof(mesgHerePerm[0]));
+ mesgShort = (TCHAR**)mir_alloc(protoCount * sizeof(mesgShort[0]));
+ mesgShortPerm = (TCHAR**)mir_alloc(protoCount * sizeof(mesgShortPerm[0]));
+ mesgLong = (TCHAR**)mir_alloc(protoCount * sizeof(mesgLong[0]));
+ mesgLongPerm = (TCHAR**)mir_alloc(protoCount * sizeof(mesgLongPerm[0]));
+
+ #ifdef UNICODE
+ protoHasAwayMessageW=(bool *)mir_alloc(protoCount * sizeof(protoHasAwayMessageW[0]));
+ #endif
+
+ isWaitingForRestoreStatusMessage = (int *)mir_alloc((protoCount)*sizeof(isWaitingForRestoreStatusMessage[0]));
+
+ for (j = 0 ; j < protoCount ; j++) {
+ int caps=0;
+#ifdef AALOG
+ {
+ char log[1024];
+ sprintf(log,"Checking protocol index %d out of %d...",j+1,protoCount);
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+ }
+#endif
+ reqStatus[j] = 0;
+ courStatus[j] = ID_STATUS_OFFLINE;
+ protoModes[j] =0;
+ isWaitingForRestoreStatusMessage[j] = 0;
+ caps = CallProtoService(proto[j]->szName, PS_GETCAPS, PFLAGNUM_2, 0);
+ messCaps[j] = (CallProtoService(proto[j]->szName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)?
+ CallProtoService(proto[j]->szName, PS_GETCAPS, PFLAGNUM_3, 0):0;
+#ifdef AALOG
+ {
+ char log[1024];
+ if (messCaps[j]){
+ int i;
+ sprintf(log,"StatusMessages Caps for %s:",
+ proto[j]->szName
+ );
+ for (i=0;i<10;i++){
+ int statusFlag = Proto_Status2Flag(aa_Status[i]);
+ if (statusFlag & messCaps[j]){
+ sprintf(log,"%s %s",log,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, aa_Status[i], 0));
+ }
+ }
+ } else {
+ sprintf(log,"%s cannot set StatusMessage",
+ proto[j]->szName);
+ }
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)log);
+ }
+#endif
+ for (i = 0; i<numStatuses; i++){
+ protoModes[j] <<= 1;
+ protoModes[j] |= (Proto_Status2Flag(aa_Status[i]) & caps)?1:0;
+ protoModes[j] |= (aa_Status[i] == ID_STATUS_OFFLINE);
+ }
+ if ( isInterestingProto(j) ) {
+ char str[256];
+ sprintf(str,AA_BITSONLYIF,proto[j]->szName);
+// MessageBox( 0,str,proto[j]->szName,0);
+ onlyIfBits[j]= DBGetContactSettingDword(NULL,AA_MODULE,str,-1);
+ if (onlyIfBits[j]==-1){
+// onlyIfBits[j] = (((protoModes[j]<<16)|(protoModes[j])) & aa_OnlyIfBitsDefault);
+ onlyIfBits[j] = aa_OnlyIfBitsDefault;
+ DBWriteContactSettingDword(NULL,AA_MODULE,str,onlyIfBits[j]);
+ }
+ onlyIfBitsPerm[j]=onlyIfBits[j];
+#ifdef UNICODE
+ sprintf(str,"%s%s",proto[j]->szName,PS_SETAWAYMSGW);
+ protoHasAwayMessageW[j]=(ServiceExists(str)!=0);
+#endif
+// sprintf(str,AA_BITSLONGONLYIF,proto[j]->szName);
+//// MessageBox( 0,str,proto[j]->szName,0);
+// if (!DBGetContactSettingWord(NULL,AA_MODULE,str,0))
+// DBWriteContactSettingWord(NULL,AA_MODULE,str,(protoModes[j] & aa_OnlyIfBitsDefault)|known);
+ sprintf(str,AA_AWAYSTATUSES,proto[j]->szName);
+// MessageBox( 0,str,proto[j]->szName,0);
+ awayStatuses[j] = DBGetContactSettingWord(NULL,AA_MODULE,str,-1);
+ if (awayStatuses[j] ==-1){
+ int old = DBGetContactSettingWord(NULL,AA_OLDMODULE,AA_SHORTSTATUS,-1);
+ int s = StatusToProtoIndex(((old==-1)?ID_STATUS_AWAY:OldIndexToStatus(old)),protoModes[j]);
+ int l = 0;
+ int comb = 0;
+ old = DBGetContactSettingWord(NULL,AA_OLDMODULE,AA_LONGSTATUS,-1);
+ l = StatusToProtoIndex(((old==-1)?ID_STATUS_NA:OldIndexToStatus(old)),protoModes[j]);
+ comb = (l<<4)|s;
+ old = DBGetContactSettingByte(NULL,AA_OLDMODULE,AA_USESHORT,-1);
+ if (s) comb |= ((old==-1)?1<<8:(old==1)<<8);
+ old = DBGetContactSettingByte(NULL,AA_OLDMODULE,AA_USELONG,-1);
+ if (l) comb |= ((old==-1)?1<<9:(old==1)<<9);
+// comb |= (1<<15);
+ awayStatuses[j]=comb;
+ DBWriteContactSettingWord(NULL,AA_MODULE,str,(WORD)awayStatuses[j]);
+ }
+ awayStatusesPerm[j] = awayStatuses[j];
+
+ sprintf(str,AA_LASTREQUESTEDSTATUS,proto[j]->szName); //get last requested status
+ reqStatus[j] = DBGetContactSettingWord(NULL,AA_MODULE,str,ID_STATUS_ONLINE); //default: online
+
+ sprintf(str,AA_RECONNECTOPTS,proto[j]->szName); //get reconnect options status
+ reconnectOpts[j] = DBGetContactSettingDword(NULL,AA_MODULE,str,aa_ReconnectOptsDefault);
+ reconnectOptsPerm[j] = reconnectOpts[j];
+ protoStatus[j] = 0;
+ protoOfflineTimes[j] = 0;
+ mesgHere[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1));
+ mesgHerePerm[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1));
+ mesgShort[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1));
+ mesgShortPerm[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1));
+ mesgLong[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1));
+ mesgLongPerm[j]=(TCHAR *)mir_alloc(sizeof(TCHAR)*(maxMessageLength+1));
+
+ if (messCaps[j]){
+ DBVARIANT dbv;
+ sprintf(str,idleMsgOptionsName,proto[j]->szName);
+ idleMessOptsPerm[j] = idleMessOpts[j] = DBGetContactSettingDword(NULL,AA_MODULE,str,idleMsgOptionsDefault);
+
+ sprintf(str,idleMsgOptionsTextHere,proto[j]->szName);
+ if(DBGetContactSettingTString(NULL,AA_MODULE,str,&dbv)==0) {
+ _tcsncpy(mesgHere[j],dbv.ptszVal,maxMessageLength);
+ mesgHere[j][maxMessageLength]=0;
+ DBFreeVariant(&dbv);
+ } else _tcscpy(mesgHere[j],messHereDefault);
+ if(!_tcscmp(mesgHere[j],messHereDefaultOld)) _tcscpy(mesgHere[j],messHereDefault);
+ _tcscpy(mesgHerePerm[j],mesgHere[j]);
+
+ sprintf(str,idleMsgOptionsTextShort,proto[j]->szName);
+ if(DBGetContactSettingTString(NULL,AA_MODULE,str,&dbv)==0) {
+ _tcsncpy(mesgShort[j],dbv.ptszVal,maxMessageLength);
+ mesgShort[j][maxMessageLength]=0;
+ DBFreeVariant(&dbv);
+ } else _tcscpy(mesgShort[j],messShortDefault);
+ if(!_tcscmp(mesgShort[j],messShortDefaultOld)) _tcscpy(mesgShort[j],messShortDefault);
+ _tcscpy(mesgShortPerm[j],mesgShort[j]);
+
+ sprintf(str,idleMsgOptionsTextLong,proto[j]->szName);
+ if(DBGetContactSettingTString(NULL,AA_MODULE,str,&dbv)==0) {
+ _tcsncpy(mesgLong[j],dbv.ptszVal,maxMessageLength);
+ mesgLong[j][maxMessageLength]=0;
+ DBFreeVariant(&dbv);
+ } else _tcscpy(mesgLong[j],messLongDefault);
+ if(!_tcscmp(mesgLong[j],messLongDefaultOld)) _tcsncpy(mesgLong[j],messLongDefault,maxMessageLength);
+ _tcsncpy(mesgLongPerm[j],mesgLong[j],maxMessageLength);
+// sprintf(mesgHere[j],"%d: %s: %s",j,proto[j]->szName,"Test text");
+ } else {
+ idleMessOptsPerm[j] = idleMessOpts[j] = 0;
+ mesgHerePerm[j] = mesgHere[j] = mesgShortPerm[j] = mesgShort[j] = mesgLongPerm[j] = mesgLong[j] = NULL;
+ }
+ }
+ }
+#ifdef AALOG
+ {
+ char str[1024]="";
+ for (j = 0 ; j < protoCount ; j++) {
+ int status;
+ sprintf(str,"%s\n%s Type:%d\nLastReqStatus: %s\n",str,proto[j]->szName,proto[j]->type,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)reqStatus[j], 0));
+ i=1;
+ while(status=StatusByProtoIndex(protoModes[j],i)){
+ sprintf(str,"%s %d. %s\n",str,i,CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)status, 0));
+ i++;
+ }
+// IsStatusBitSet(aa_Status[i],protoModes[j])?"":"not",
+// CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)aa_Status[i], 0),
+// IsStatusBitSet(aa_Status[i],aa_OnlyIfBitsDefault)?"n":"ff"
+// );
+
+ }
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+ }
+#endif
+//something is hapaning here on startup, if main status is not offline
+//will move Notify hIdleEvent for later in the IdleTimer
+// NotifyEventHooks( hIdleEvent, 0, idleOpts&IdleBitsPrivate?IDF_PRIVACY:0 ); //Tell everyone we are here
+ FirstTick = 1; //we will wait 1 ticks of the timer before Forcing Awake
+// FirstTick = 10; //we will wait 20 seconds before Forcing Awake
+ hIdleTimer=SetTimer(NULL, 0, 2000, IdleTimer);
+// {
+// char str[20000]="";
+// for (i=0;i<=101;i++){
+// char str1[128];
+// GetStringFromDelay(str1,GetReconnectDelayFromSlider(i));
+// sprintf(str,"%d\t%d\t%s",GetReconnectDelayFromSlider(i),i,str1);
+// CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)str);
+// }
+// }
+ if ((idleOptsPerm&IdleSuppressIdleMenu)==0) AddIdleMenu();
+ if ((idleOptsPerm&IdleSuppressAutoHere)!=0) isCurrentlyIdle=DBGetContactSettingByte(NULL,AA_MODULE,AA_LASTIDLESTATUS,0);;
+ return 0;
+}
+
+//#ifndef SAA_PLUGIN
+int AutoAwayShutdown(WPARAM wParam,LPARAM lParam)
+{
+ int i;
+
+#ifdef AALOG
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"Killing Timer");
+#endif
+ KillTimer(NULL, hIdleTimer);
+ if (hHookIconsChanged){
+ #ifdef AALOG
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"UnHooking hHookIconsChanged");
+ #endif
+ UnhookEvent(hHookIconsChanged);
+ }
+#ifdef AALOG
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"DestroyHookableEvent(hIdleEvent)");
+#endif
+ for (i=0; i<sizeof(hHooks)/sizeof(HANDLE); ++i)
+ UnhookEvent(hHooks[i]);
+ for (i=0; i<sizeof(hService)/sizeof(HANDLE); ++i)
+ DestroyServiceFunction(hService[i]);
+ DestroyHookableEvent(hIdleEvent);
+#ifdef AALOG
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"UnHooking Event "ME_SYSTEM_SHUTDOWN"");
+#endif
+// UnhookEvent(ME_SYSTEM_SHUTDOWN);
+#ifdef AALOG
+ CallService("Netlib/Log" ,(WPARAM)hNetlib ,(LPARAM)"Done");
+
+ if (hNetlib) {
+ Netlib_CloseHandle(hNetlib);
+ hNetlib = NULL;
+ }
+
+#endif
+
+ mir_free(reqStatus);
+ mir_free(courStatus);
+ mir_free(courAwayStatus);
+ mir_free(protoModes);
+ mir_free(awayStatusesPerm);
+ mir_free(awayStatuses);
+ mir_free(onlyIfBitsPerm);
+ mir_free(onlyIfBits);
+ mir_free(reconnectOptsPerm);
+ mir_free(reconnectOpts);
+ mir_free(protoOfflineTimes);
+ mir_free(protoStatus);
+ mir_free(idleMessOpts);
+ mir_free(idleMessOptsPerm);
+ mir_free(isWaitingForRestoreStatusMessage);
+
+ for (i=0; i<protoCount; ++i) if (messCaps[i]){
+ mir_free(mesgHere[i]);
+ mir_free(mesgHerePerm[i]);
+ mir_free(mesgShort[i]);
+ mir_free(mesgShortPerm[i]);
+ mir_free(mesgLong[i]);
+ mir_free(mesgLongPerm[i]);
+ }
+
+ mir_free(messCaps);
+ mir_free(mesgHere);
+ mir_free(mesgHerePerm);
+ mir_free(mesgShort);
+ mir_free(mesgShortPerm);
+ mir_free(mesgLong);
+ mir_free(mesgLongPerm);
+
+ return 0;
+}
+//#endif
diff --git a/plugins/SmartAutoAway/saani.c b/plugins/SmartAutoAway/saani.c
new file mode 100644
index 0000000000..3241786c35
--- /dev/null
+++ b/plugins/SmartAutoAway/saani.c
@@ -0,0 +1,85 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2006 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+*/
+
+//#ifdef VCL_VC60
+#include "AggressiveOptimize.h"
+//#endif
+#include <windows.h>
+#include <newpluginapi.h>
+
+PLUGININFOEX pluginInfo = {
+ sizeof(PLUGININFO),
+ "Smart Auto Away NI",
+#include "version.txt"
+ 0,
+ DEFMOD_RNDIDLE, // replace internal version (if any)
+ { 0x91bb7ad7,0x7ed8,0x40b9,{0xb1, 0x50, 0x3f, 0x37, 0x6b, 0x6b, 0x67, 0xfe}/* 91bb7ad7-7ed8-40b9-b150-3f376b6b67fe */}
+};
+
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ return TRUE;
+}
+static char description[1023];
+sprintf(char *, const char *, ...);
+__declspec(dllexport) PLUGININFOEX *MirandaPluginInfo(DWORD mirandaVersion)
+{
+ sprintf(description,"%s","Just to suppress the build-in \"Idle\" module");
+ if (mirandaVersion<0x00030400) {
+ sprintf(description,"%s\r\n%s",description,"Miranda %d.%d.%d.%d has no build-in \"Idle\" support and this plugin is useless");
+ sprintf(description,description, // Yes, I realize this is strange approach...
+ mirandaVersion>>24&0xFF,
+ mirandaVersion>>16&0xFF,
+ mirandaVersion>>8&0xFF,
+ mirandaVersion&0xFF
+ );
+ }
+ sprintf(description,"%s\r\n[Build %s %s]",description, __DATE__,__TIME__);
+ pluginInfo.description = description;
+ return &pluginInfo;
+}
+__declspec(dllexport) PLUGININFOEX * MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ //return 0;
+ pluginInfo.cbSize = sizeof( PLUGININFOEX );
+ return MirandaPluginInfo(mirandaVersion);
+}
+
+static const MUUID interfaces[] = {MIID_IDLE, MIID_LAST};
+__declspec(dllexport) const MUUID * MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+int __declspec(dllexport) Load(PLUGINLINK * link)
+{
+ return 0;
+}
+
+int __declspec(dllexport) Unload(void)
+{
+// AutoAwayShutdown(0,0);
+ return 0; //if 1 we dont want to shutdown because we have hooked ME_SYSTEM_SHUTDOWN
+}
+
diff --git a/plugins/SmartAutoAway/saani.dsp b/plugins/SmartAutoAway/saani.dsp
new file mode 100644
index 0000000000..f36ee7738f
--- /dev/null
+++ b/plugins/SmartAutoAway/saani.dsp
@@ -0,0 +1,107 @@
+# Microsoft Developer Studio Project File - Name="saani" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=saani - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "saani.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "saani.mak" CFG="saani - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "saani - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "saani - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "saani - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleasePlugin"
+# PROP BASE Intermediate_Dir "ReleasePlugin"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleasePlugin"
+# PROP Intermediate_Dir "ReleasePlugin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SAANI_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AALOG" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x402 /d "NDEBUG"
+# ADD RSC /l 0x402 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"../../bin/release/plugins/saani.dll"
+
+!ELSEIF "$(CFG)" == "saani - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "DebugPlugin"
+# PROP BASE Intermediate_Dir "DebugPlugin"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugPlugin"
+# PROP Intermediate_Dir "DebugPlugin"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SAANI_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "SAANI_EXPORTS" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x402 /d "_DEBUG"
+# ADD RSC /l 0x402 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"../../Bin/debug/Plugins/saani.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "saani - Win32 Release"
+# Name "saani - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\saani.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/plugins/SmartAutoAway/short.ico b/plugins/SmartAutoAway/short.ico
new file mode 100644
index 0000000000..32817713fa
--- /dev/null
+++ b/plugins/SmartAutoAway/short.ico
Binary files differ
diff --git a/plugins/SmartAutoAway/version.txt b/plugins/SmartAutoAway/version.txt
new file mode 100644
index 0000000000..ddbd1c8713
--- /dev/null
+++ b/plugins/SmartAutoAway/version.txt
@@ -0,0 +1,7 @@
+ PLUGIN_MAKE_VERSION(0, 0, 3, 3),
+ "",
+ "YB",
+ "y_b" /* these */ "@" /* fucking spammers */ "saaplugin.no-ip.info" /* gather everything */,
+ "© 2005-2009 YB; 2000-2006 Miranda-IM",
+ "http://saaplugin.no-ip.info/",
+