summaryrefslogtreecommitdiff
path: root/plugins/WhenWasIt/services.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/WhenWasIt/services.cpp')
-rw-r--r--plugins/WhenWasIt/services.cpp423
1 files changed, 423 insertions, 0 deletions
diff --git a/plugins/WhenWasIt/services.cpp b/plugins/WhenWasIt/services.cpp
new file mode 100644
index 0000000000..303866bffa
--- /dev/null
+++ b/plugins/WhenWasIt/services.cpp
@@ -0,0 +1,423 @@
+/*
+WhenWasIt (birthday reminder) plugin for Miranda IM
+
+Copyright © 2006 Cristian Libotean
+
+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 "services.h"
+
+#define COMMENT_CHAR '#'
+
+HANDLE hsCheckBirthdays;
+HANDLE hsShowList;
+HANDLE hsAddBirthday;
+HANDLE hsRefreshUserDetails;
+HANDLE hsImportBirthdays;
+HANDLE hsExportBirthdays;
+
+int bShouldCheckBirthdays = 0;
+int bBirthdayFound = 0;
+
+int InitServices()
+{
+ Log("%s", "Entering function " __FUNCTION__);
+
+ commonData.foreground = DBGetContactSettingDword(NULL, ModuleName, "Foreground", FOREGROUND_COLOR);
+ commonData.background = DBGetContactSettingDword(NULL, ModuleName, "Background", BACKGROUND_COLOR);
+ commonData.checkInterval = DBGetContactSettingWord(NULL, ModuleName, "CheckInterval", CHECK_INTERVAL);
+ commonData.daysInAdvance = DBGetContactSettingWord(NULL, ModuleName, "DaysInAdvance", DAYS_TO_NOTIFY);
+ commonData.daysAfter = DBGetContactSettingWord(NULL, ModuleName, "DaysAfter", DAYS_TO_NOTIFY_AFTER);
+ commonData.popupTimeout = DBGetContactSettingWord(NULL, ModuleName, "PopupTimeout", POPUP_TIMEOUT);
+ commonData.popupTimeoutToday = DBGetContactSettingWord(NULL, ModuleName, "PopupTimeoutToday", commonData.popupTimeout);
+ commonData.bUsePopups = DBGetContactSettingByte(NULL, ModuleName, "UsePopups", TRUE);
+ commonData.bUseClistIcon = DBGetContactSettingByte(NULL, ModuleName, "UseClistIcon", TRUE);
+ commonData.bUseDialog = DBGetContactSettingByte(NULL, ModuleName, "UseDialog", TRUE);
+ commonData.clistIcon= DBGetContactSettingByte(NULL, ModuleName, "AdvancedIcon", CLIST_ICON);
+ commonData.bIgnoreSubcontacts = DBGetContactSettingByte(NULL, ModuleName, "IgnoreSubcontacts", FALSE);
+ commonData.cShowAgeMode = DBGetContactSettingByte(NULL, ModuleName, "ShowCurrentAge", FALSE);
+ commonData.bNoBirthdaysPopup = DBGetContactSettingByte(NULL, ModuleName, "NoBirthdaysPopup", FALSE);
+ commonData.bOpenInBackground = DBGetContactSettingByte(NULL, ModuleName, "OpenInBackground", FALSE);
+ commonData.cSoundNearDays = DBGetContactSettingByte(NULL, ModuleName, "SoundNearDays", BIRTHDAY_NEAR_DEFAULT_DAYS);
+ commonData.cDefaultModule = DBGetContactSettingByte(NULL, ModuleName, "DefaultModule", 0);
+ commonData.lPopupClick = DBGetContactSettingByte(NULL, ModuleName, "PopupLeftClick", 2);
+ commonData.rPopupClick = DBGetContactSettingByte(NULL, ModuleName, "PopupRightClick", 1);
+ commonData.bOncePerDay = DBGetContactSettingByte(NULL, ModuleName, "OncePerDay", 0);
+ commonData.cDlgTimeout = DBGetContactSettingWord(NULL, ModuleName, "DlgTimeout", POPUP_TIMEOUT);
+ commonData.notifyFor = DBGetContactSettingByte(NULL, ModuleName, "NotifyFor", 0);
+
+ hsCheckBirthdays = CreateServiceFunction(MS_WWI_CHECK_BIRTHDAYS, CheckBirthdaysService);
+ hsShowList = CreateServiceFunction(MS_WWI_LIST_SHOW, ShowListService);
+ hsAddBirthday = CreateServiceFunction(MS_WWI_ADD_BIRTHDAY, AddBirthdayService);
+ hsRefreshUserDetails = CreateServiceFunction(MS_WWI_REFRESH_USERDETAILS, RefreshUserDetailsService);
+ hsImportBirthdays = CreateServiceFunction(MS_WWI_IMPORT_BIRTHDAYS, ImportBirthdaysService);
+ hsExportBirthdays = CreateServiceFunction(MS_WWI_EXPORT_BIRTHDAYS, ExportBirthdaysService);
+
+ Log("%s", "Leaving function " __FUNCTION__);
+ return 0;
+}
+
+int DestroyServices()
+{
+ Log("%s", "Entering function " __FUNCTION__);
+
+ DestroyServiceFunction(hsCheckBirthdays);
+ DestroyServiceFunction(hsShowList);
+ DestroyServiceFunction(hsAddBirthday);
+ DestroyServiceFunction(hsRefreshUserDetails);
+ DestroyServiceFunction(hsImportBirthdays);
+ DestroyServiceFunction(hsExportBirthdays);
+
+ Log("%s", "Leaving function " __FUNCTION__);
+ return 0;
+}
+
+/*
+returns -1 if notify is not necesarry
+returns daysToBirthday if it should notify
+*/
+int NotifyContactBirthday(HANDLE hContact, time_t now, int daysInAdvance)
+{
+ int year, month, day;
+ GetContactDOB(hContact, year, month, day);
+ int daysToBirthday = DaysToBirthday(now, year, month, day);
+ if (daysInAdvance >= daysToBirthday)
+ {
+ return daysToBirthday;
+ }
+ return -1;
+}
+
+// returns -1 if notify is not necessary
+// returns daysAfterBirthday if it should notify
+int NotifyMissedContactBirthday(HANDLE hContact, time_t now, int daysAfter)
+{
+ if (daysAfter > 0)
+ {
+ int year, month, day;
+ GetContactDOB(hContact, year, month, day);
+ int daysAfterBirthday = DaysAfterBirthday(now, year, month, day);
+ if ((daysAfterBirthday >= 0) && (daysAfter >= daysAfterBirthday))
+ {
+ return daysAfterBirthday;
+ }
+ }
+
+ return -1;
+}
+
+//the timer functions call this service with lParam = 1
+//lParam = 0 - force check, lParam - 1 do not force it.
+INT_PTR CheckBirthdaysService(WPARAM wParam, LPARAM lParam)
+{
+ bBirthdayFound = 0; //no birthdays have been found in the given interval
+ //int bNoBirthdaysPopup = DBGetContactSettingByte(NULL, ModuleName, "NoBirthdaysPopup", FALSE);
+
+ SYSTEMTIME today;
+ GetLocalTime(&today);
+
+ DWORD lastChecked = DBGetContactSettingDword(NULL, ModuleName, "LastChecked", 0); //get last checked date
+ int lcDay = LOBYTE(LOWORD(lastChecked));
+ int lcMonth = HIBYTE(LOWORD(lastChecked));
+ int lcYear = HIWORD(lastChecked);
+
+ int daysAfter = DaysAfterBirthday(Today(), lcYear, lcMonth, lcDay); //get difference between last checked date and today
+ int savedDaysAfter = 0;
+
+ savedDaysAfter = commonData.daysAfter; //save value
+
+ if ((daysAfter > commonData.daysAfter) && (commonData.daysAfter > 0))//check for passed birthdays
+ {
+ commonData.daysAfter = daysAfter; //bigger values of the two
+ }
+
+ if ((lParam) && (commonData.bOncePerDay)) //if force check then we don't take OncePerDay into account
+ {
+ if ((lcDay == today.wDay) && (lcMonth == today.wMonth) && (lcYear == today.wYear))
+ {
+ return 0; //already checked today
+ }
+ }
+
+ bShouldCheckBirthdays = 1;
+ RefreshAllContactListIcons();
+ if ((!bBirthdayFound) && (commonData.bNoBirthdaysPopup))
+ {
+ PopupNotifyNoBirthdays();
+ }
+ bShouldCheckBirthdays = 0;
+
+ commonData.daysAfter = savedDaysAfter; //restore previous value
+
+ if (lParam) //if not forced - i.e. timer check
+ {
+ DBWriteContactSettingDword(NULL, ModuleName, "LastChecked", MAKELONG(MAKEWORD(today.wDay, today.wMonth), today.wYear)); //write the value in DB so we don't check again today
+ }
+
+ return 0;
+}
+
+INT_PTR ShowListService(WPARAM wParam, LPARAM lParam)
+{
+ if (!hBirthdaysDlg)
+ {
+ hBirthdaysDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_BIRTHDAYS), NULL, DlgProcBirthdays);
+ }
+ ShowWindow(hBirthdaysDlg, SW_SHOW);
+ return 0;
+}
+
+INT_PTR AddBirthdayService(WPARAM wParam, LPARAM lParam)
+{
+ HWND hWnd = WindowList_Find(hAddBirthdayWndsList, (HANDLE) wParam);
+ if (!hWnd)
+ {
+ hWnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_ADD_BIRTHDAY), NULL, DlgProcAddBirthday);
+ if (hWnd == NULL)
+ {
+ TCHAR buffer[1024];
+ _stprintf(buffer, _T("Error #%d while trying to create add birthday dialog"), GetLastError());
+ MessageBox(0, buffer, _T("Error"), MB_OK);
+ }
+ WindowList_Add(hAddBirthdayWndsList, hWnd, (HANDLE) wParam);
+ SetWindowLongPtr(hWnd, GWLP_USERDATA, wParam);
+ }
+ return ShowWindow(hWnd, SW_SHOW);
+}
+
+void ShowPopupMessage(TCHAR *title, TCHAR *message, HICON icon)
+{
+ POPUPDATAT pd = {0};
+ pd.lchIcon = icon;
+ _tcscpy(pd.lptzContactName, title);
+ _tcscpy(pd.lptzText, message);
+ pd.colorText = commonData.foreground;
+ pd.colorBack = commonData.background;
+
+ PUAddPopUpT(&pd);
+}
+
+DWORD WINAPI RefreshUserDetailsWorkerThread(LPVOID param)
+{
+ //MessageBox(0, "Inside worker thread", "Info", MB_OK);
+ //POPUPDATA pd = {0};
+ //pd.lchIcon = hiRefreshUserDetails;
+ //strcpy(pd.lpzContactName, Translate("WhenWasIt"));
+ //strcpy(pd.lpzText, Translate("Starting to refresh user details"));
+ //PUAddPopUp(&pd);
+ ShowPopupMessage(TranslateT("WhenWasIt"), TranslateT("Starting to refresh user details"), hiRefreshUserDetails);
+ int delay = DBGetContactSettingWord(NULL, ModuleName, "UpdateDelay", REFRESH_DETAILS_DELAY);
+ HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ int res;
+ while (hContact != NULL)
+ {
+ res = CallContactService(hContact, PSS_GETINFO, 0, 0);
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ if (hContact)
+ {
+ Sleep(delay); //sleep for a few seconds between requests
+ }
+ }
+ //strcpy(pd.lpzText, Translate("Done refreshing user details"));
+ //PUAddPopUp(&pd);
+ ShowPopupMessage(TranslateT("WhenWasIt"), TranslateT("Done refreshing user details"), hiRefreshUserDetails);
+ //MessageBox(0, "Leaving worker thread", "Info", MB_OK);
+ return 0;
+}
+
+INT_PTR RefreshUserDetailsService(WPARAM wParam, LPARAM lParam)
+{
+ DWORD threadID;
+ //MessageBox(0, "Before CreateThread()", "Info", MB_OK);
+ HANDLE result = CreateThread(NULL, 0, RefreshUserDetailsWorkerThread, NULL, 0, &threadID);
+ //MessageBox(0, "After CreateThread()", "Info", MB_OK);
+ if (!result)
+ {
+ TCHAR buffer[1024];
+ _stprintf(buffer, _T("Could not create worker thread. Error#%d - threadID %d"), GetLastError(), threadID);
+ MessageBox(0, buffer, _T("Error"), MB_OK | MB_ICONERROR);
+ }
+ if ((result != NULL) && (result != INVALID_HANDLE_VALUE))
+ {
+ CloseHandle(result);
+ }
+
+ return 0;
+}
+
+INT_PTR ImportBirthdaysService(WPARAM wParam, LPARAM lParam)
+{
+ TCHAR fileName[1024] = {0};
+ OPENFILENAME of = {0};
+ of.lStructSize = sizeof(OPENFILENAME);
+ //of.hInstance = hInstance;
+ TCHAR filter[MAX_PATH];
+ mir_sntprintf(filter, SIZEOF(filter), _T("%s (*") _T(BIRTHDAY_EXTENSION) _T(")%c*") _T(BIRTHDAY_EXTENSION) _T("%c"), TranslateT("Birthdays files"), 0, 0);
+ of.lpstrFilter = filter;
+ of.lpstrFile = fileName;
+ of.nMaxFile = 1024;
+ of.lpstrTitle = TranslateT("Please select a file to import birthdays from ...");
+ of.Flags = OFN_FILEMUSTEXIST;
+
+ if (GetOpenFileName(&of))
+ {
+ TCHAR buffer[2048];
+ mir_sntprintf(buffer, SIZEOF(buffer), TranslateT("Importing birthdays from file: %s"), fileName);
+ ShowPopupMessage(TranslateT("WhenWasIt"), buffer, hiImportBirthdays);
+ DoImport(fileName);
+ ShowPopupMessage(TranslateT("WhenWasIt"), TranslateT("Done importing birthdays"), hiImportBirthdays);
+ }
+
+ return 0;
+}
+
+INT_PTR ExportBirthdaysService(WPARAM wParam, LPARAM lParam)
+{
+ TCHAR fileName[1024]= {0};
+ OPENFILENAME of = {0};
+ of.lStructSize = sizeof(OPENFILENAME);
+ //of.hInstance = hInstance;
+ TCHAR filter[MAX_PATH];
+ mir_sntprintf(filter, SIZEOF(filter), _T("%s (*") _T(BIRTHDAY_EXTENSION) _T(")%c*") _T(BIRTHDAY_EXTENSION) _T("%c%s (*.*)%c*.*%c"), TranslateT("Birthdays files"), 0, 0, TranslateT("All Files"), 0, 0);
+ of.lpstrFilter = filter;
+ of.lpstrFile = fileName;
+ of.nMaxFile = 1024;
+ of.lpstrTitle = TranslateT("Please select a file to export birthdays to ...");
+ //of.Flags = OFN_ENABLESIZING | OFN_EXPLORER;
+
+ if (GetSaveFileName(&of))
+ {
+ TCHAR buffer[2048];
+ TCHAR *fn = _tcsrchr(fileName, _T('\\')) + 1;
+ if (!_tcschr(fn, _T('.')))
+ {
+ _tcscat(fileName, _T(BIRTHDAY_EXTENSION));
+ }
+ _stprintf(buffer, TranslateT("Exporting birthdays to file: %s"), fileName);
+ ShowPopupMessage(TranslateT("WhenWasIt"), buffer, hiExportBirthdays);
+ DoExport(fileName);
+ ShowPopupMessage(TranslateT("WhenWasIt"), TranslateT("Done exporting birthdays"), hiExportBirthdays);
+ }
+
+ return 0;
+}
+
+int DoImport(TCHAR *fileName)
+{
+ FILE *fin = _tfopen(fileName, _T("rt"));
+ if (!fin)
+ {
+ MessageBox(0, _T("Could not open file to import birthdays"), _T("Error"), MB_OK | MB_ICONERROR);
+ return 1;
+ }
+
+ HANDLE hContact;
+ int year, month, day;
+ TCHAR *szHandle;
+ TCHAR *szProto;
+ const int maxSize = 4096;
+ TCHAR buffer[maxSize];
+ int tmp, tmp2;
+ int mode = commonData.cDefaultModule; //DBGetContactSettingByte(NULL, ModuleName, "DefaultModule", 0);
+ TCHAR *delAccount, *delProto;
+
+ while (!feof(fin))
+ {
+ _fgetts(buffer, maxSize, fin);
+ if (buffer[0] == _T(COMMENT_CHAR))
+ {
+ continue;
+ }
+
+ delAccount = _tcsstr(buffer, _T(" : "));
+ if (delAccount)
+ {
+ tmp = delAccount[0];
+ delAccount[0] = _T('\0');
+ delProto = _tcsrchr(buffer, _T('@'));
+ if (delProto)
+ {
+ tmp2 = delProto[0];
+ delProto[0] = _T('\0');
+
+ szHandle = buffer;
+ szProto = delProto + 1;
+ hContact = GetContactFromID(szHandle, szProto);
+ if (hContact)
+ {
+ delProto[0] = tmp;
+ delAccount[0] = tmp;
+ _stscanf(delAccount, _T(" : %02d/%02d/%04d"), &day, &month, &year);
+ SaveBirthday(hContact, year, month, day, mode);
+ }
+ else{
+ TCHAR tmp[2048];
+ _stprintf(tmp, TranslateT(NOTFOUND_FORMAT), szHandle, szProto);
+ ShowPopupMessage(TranslateT("Warning"), tmp, hiImportBirthdays);
+ }
+ }
+ }
+ }
+
+ fclose(fin);
+
+ return 0;
+}
+
+int DoExport(TCHAR *fileName)
+{
+ FILE *fout = _tfopen(fileName, _T("wt"));
+ if (!fout)
+ {
+ MessageBox(0, _T("Could not open file to export birthdays"), _T("Error"), MB_OK | MB_ICONERROR);
+ return 1;
+ }
+ _ftprintf(fout, _T("%c%s"), _T(COMMENT_CHAR), _T("Please do not edit this file by hand. Use the export function of WhenWasIt plugin.\n"));
+ _ftprintf(fout, _T("%c%s"), _T(COMMENT_CHAR), _T("Warning! Please do not mix Unicode and Ansi exported birthday files. You should use the same version (Ansi/Unicode) of WhenWasIt that was used to export the info.\n"));
+#ifdef _UNICODE
+ _ftprintf(fout, _T("%c%s"), _T(COMMENT_CHAR), _T("This file was exported with a Unicode version of WhenWasIt. Please only use a Unicode version of the plugin to import the birthdays.\n"));
+#else
+ _ftprintf(fout, _T("%c%s"), _T(COMMENT_CHAR), _T("This file was exported with an Ansi version of WhenWasIt. Please only use an Ansi version of the plugin to import the birthdays.\n"));
+#endif
+ HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ int year, month, day;
+ TCHAR *szHandle;
+ char szProto[256];
+
+ while (hContact)
+ {
+ GetContactDOB(hContact, year, month, day);
+ if (IsDOBValid(year, month, day))
+ {
+ szProto[0] = '\0';
+ GetContactProtocol(hContact, szProto, sizeof(szProto));
+ szHandle = GetContactID(hContact, szProto);
+
+ if ((szHandle) && (strlen(szProto) > 0))
+ {
+ _ftprintf(fout, _T(BIRTHDAYS_EXPORT_FORMAT), szHandle, szProto, day, month, year);
+ }
+
+ if (szHandle) free(szHandle);
+ }
+
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+
+ fclose(fout);
+
+ return 0;
+} \ No newline at end of file