diff options
author | Vadim Dashevskiy <watcherhd@gmail.com> | 2012-07-05 11:51:00 +0000 |
---|---|---|
committer | Vadim Dashevskiy <watcherhd@gmail.com> | 2012-07-05 11:51:00 +0000 |
commit | fd5bbf93523a1168559d002757ae977a25ada405 (patch) | |
tree | 658d2dc274943f951f01de61aa3ae56b331ed139 /plugins/AvatarHistory/src | |
parent | f4ca33472b18027cdcf38c2569e1efbb116bd2a1 (diff) |
AvatarHistory: folder structure change
git-svn-id: http://svn.miranda-ng.org/main/trunk@768 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/AvatarHistory/src')
-rw-r--r-- | plugins/AvatarHistory/src/AvatarDlg.cpp | 621 | ||||
-rw-r--r-- | plugins/AvatarHistory/src/AvatarHistory.cpp | 964 | ||||
-rw-r--r-- | plugins/AvatarHistory/src/AvatarHistory.h | 108 | ||||
-rw-r--r-- | plugins/AvatarHistory/src/icolib.cpp | 135 | ||||
-rw-r--r-- | plugins/AvatarHistory/src/options.cpp | 234 | ||||
-rw-r--r-- | plugins/AvatarHistory/src/popup.cpp | 279 | ||||
-rw-r--r-- | plugins/AvatarHistory/src/popup.h | 53 | ||||
-rw-r--r-- | plugins/AvatarHistory/src/resource.h | 88 |
8 files changed, 2482 insertions, 0 deletions
diff --git a/plugins/AvatarHistory/src/AvatarDlg.cpp b/plugins/AvatarHistory/src/AvatarDlg.cpp new file mode 100644 index 0000000000..0e829b4d9c --- /dev/null +++ b/plugins/AvatarHistory/src/AvatarDlg.cpp @@ -0,0 +1,621 @@ +/*
+Avatar History Plugin
+ Copyright (C) 2006 Matthew Wild - Email: mwild1@gmail.com
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include "AvatarHistory.h"
+
+extern HINSTANCE hInst;
+HANDLE hMenu = NULL;
+DWORD WINAPI AvatarDialogThread(LPVOID param);
+static INT_PTR CALLBACK AvatarDlgProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
+int ShowSaveDialog(HWND hwnd, TCHAR* fn,HANDLE hContact = NULL);
+
+BOOL ProtocolEnabled(const char *proto);
+int FillAvatarListFromDB(HWND list, HANDLE hContact);
+int FillAvatarListFromFolder(HWND list, HANDLE hContact);
+int CleanupAvatarPic(HWND hwnd);
+BOOL UpdateAvatarPic(HWND hwnd);
+TCHAR* GetCurrentSelFile(HWND list);
+TCHAR * GetContactFolder(TCHAR *fn, HANDLE hContact);
+BOOL ResolveShortcut(TCHAR *shortcut, TCHAR *file);
+
+static INT_PTR ShowDialogSvc(WPARAM wParam, LPARAM lParam);
+extern HANDLE hServices[];
+extern HANDLE hHooks[];
+
+struct AvatarDialogData
+{
+ HANDLE hContact;
+ TCHAR fn[MAX_PATH];
+ HWND parent;
+};
+
+
+class ListEntry
+{
+public:
+ ListEntry()
+ {
+ dbe = NULL;
+ filename = NULL;
+ filelink = NULL;
+ }
+
+ ~ListEntry()
+ {
+ mir_free(filename);
+ mir_free(filelink);
+ }
+
+ HANDLE dbe;
+ TCHAR *filename;
+ TCHAR *filelink;
+};
+
+int OpenAvatarDialog(HANDLE hContact, char* fn)
+{
+ HWND hAvatarWindow = WindowList_Find(hAvatarWindowsList, hContact);
+ if (hAvatarWindow)
+ {
+ SetForegroundWindow(hAvatarWindow);
+ SetFocus(hAvatarWindow);
+ return 0;
+ }
+
+ DWORD dwId;
+ struct AvatarDialogData *avdlg = (struct AvatarDialogData*)malloc(sizeof(struct AvatarDialogData));
+ ZeroMemory(avdlg, sizeof(struct AvatarDialogData));
+ avdlg->hContact = hContact;
+ if (fn == NULL)
+ {
+ avdlg->fn[0] = _T('\0');
+ }
+ else
+ {
+#ifdef _UNICODE
+ MultiByteToWideChar(CP_ACP, 0, fn, -1, avdlg->fn, MAX_REGS(avdlg->fn));
+#else
+ lstrcpyn(avdlg->fn, fn, sizeof(avdlg->fn));
+#endif
+ }
+
+ CloseHandle(CreateThread(NULL, 0, AvatarDialogThread, (LPVOID)avdlg, 0, &dwId));
+ return 0;
+}
+
+DWORD WINAPI AvatarDialogThread(LPVOID param)
+{
+ struct AvatarDialogData* data = (struct AvatarDialogData*)param;
+ DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_AVATARDLG), data->parent, AvatarDlgProc, (LPARAM)param);
+ return 0;
+}
+
+void EnableDisableControls(HWND hwnd)
+{
+ HWND list = GetDlgItem(hwnd, IDC_AVATARLIST);
+
+ int cursel = SendMessage(list, LB_GETCURSEL, 0, 0);
+ int count = SendMessage(list, LB_GETCOUNT, 0, 0);
+
+ if (cursel == LB_ERR)
+ {
+ EnableWindow(GetDlgItem(hwnd, IDC_BACK), count > 0);
+ EnableWindow(GetDlgItem(hwnd, IDC_NEXT), count > 0);
+ }
+ else
+ {
+ EnableWindow(GetDlgItem(hwnd, IDC_BACK), cursel > 0);
+ EnableWindow(GetDlgItem(hwnd, IDC_NEXT), cursel < count-1);
+ }
+}
+
+static INT_PTR CALLBACK AvatarDlgProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
+{
+ switch(uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ AvatarDialogData *data = (struct AvatarDialogData*) lParam;
+ SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) createDefaultOverlayedIcon(TRUE));
+ SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) createDefaultOverlayedIcon(FALSE));
+ if (db_byte_get(NULL, MODULE_NAME, "LogToHistory", AVH_DEF_LOGTOHISTORY))
+ FillAvatarListFromDB(GetDlgItem(hwnd, IDC_AVATARLIST), data->hContact);
+ else if (opts.log_per_contact_folders)
+ FillAvatarListFromFolder(GetDlgItem(hwnd, IDC_AVATARLIST), data->hContact);
+ TCHAR *displayName = (TCHAR*) CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM) data->hContact,GCDNF_TCHAR);
+ if(displayName)
+ {
+ TCHAR title[MAX_PATH];
+ mir_sntprintf(title,MAX_PATH,TranslateT("Avatar History for %s"),displayName);
+ SetWindowText(hwnd,title);
+ }
+
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (ULONG_PTR)data->hContact);
+ UpdateAvatarPic(hwnd);
+ CheckDlgButton(hwnd, IDC_LOGUSER, (UINT)db_byte_get(data->hContact, MODULE_NAME, "LogToDisk", BST_INDETERMINATE));
+ CheckDlgButton(hwnd, IDC_POPUPUSER, (UINT)db_byte_get(data->hContact, MODULE_NAME, "AvatarPopups", BST_INDETERMINATE));
+ CheckDlgButton(hwnd, IDC_HISTORYUSER, (UINT)db_byte_get(data->hContact, MODULE_NAME, "LogToHistory", BST_INDETERMINATE));
+ ShowWindow(GetDlgItem(hwnd, IDC_OPENFOLDER), opts.log_per_contact_folders ? SW_SHOW : SW_HIDE);
+ Utils_RestoreWindowPositionNoSize(hwnd,NULL,MODULE_NAME,"AvatarHistoryDialog");
+ WindowList_Add(hAvatarWindowsList,hwnd,data->hContact);
+ TranslateDialogDefault(hwnd);
+ EnableDisableControls(hwnd);
+ free(data);
+ data = NULL;
+ break;
+ }
+ case WM_CLOSE:
+ {
+ CleanupAvatarPic(hwnd);
+ EndDialog(hwnd, 0);
+ return TRUE;
+ }
+ case WM_DESTROY:
+ {
+ Utils_SaveWindowPosition(hwnd,NULL,MODULE_NAME,"AvatarHistoryDialog");
+ WindowList_Remove(hAvatarWindowsList,hwnd);
+ DestroyIcon((HICON)SendMessage(hwnd, WM_SETICON, ICON_BIG, 0));
+ DestroyIcon((HICON)SendMessage(hwnd, WM_SETICON, ICON_SMALL, 0));
+ HWND list = GetDlgItem(hwnd, IDC_AVATARLIST);
+ int count = SendMessage(list, LB_GETCOUNT, 0, 0);
+ for(int i = 0; i < count; i++)
+ delete (ListEntry *) SendMessage(list, LB_GETITEMDATA, i, 0);
+ break;
+ }
+ case WM_CONTEXTMENU:
+ {
+ HWND list = GetDlgItem(hwnd, IDC_AVATARLIST);
+ HWND pic = GetDlgItem(hwnd, IDC_AVATAR);
+ int pos;
+
+ if ((HANDLE) wParam == list)
+ {
+ POINT p;
+ p.x = LOWORD(lParam);
+ p.y = HIWORD(lParam);
+
+ ScreenToClient(list, &p);
+
+ pos = SendMessage(list, LB_ITEMFROMPOINT, 0, MAKELONG(p.x, p.y));
+ if (HIWORD(pos))
+ break;
+ pos = LOWORD(pos);
+
+ int count = SendMessage(list, LB_GETCOUNT, 0, 0);
+ if (pos >= count)
+ break;
+
+ SendMessage(list, LB_SETCURSEL, pos, 0);
+ EnableDisableControls(hwnd);
+ }
+ else if ((HANDLE) wParam == pic)
+ {
+ pos = SendMessage(list, LB_GETCURSEL, 0, 0);
+ if (pos == LB_ERR)
+ break;
+ }
+ else
+ break;
+
+ HMENU menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1));
+ HMENU submenu = GetSubMenu(menu, 0);
+ TranslateMenu(submenu);
+
+ if (!UpdateAvatarPic(hwnd))
+ {
+ RemoveMenu(submenu, 2, MF_BYPOSITION);
+ RemoveMenu(submenu, 0, MF_BYPOSITION);
+ }
+
+ POINT p;
+ p.x = LOWORD(lParam);
+ p.y = HIWORD(lParam);
+ int ret = TrackPopupMenu(submenu, TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD, p.x, p.y, 0, list, NULL);
+ DestroyMenu(menu);
+
+ switch(ret)
+ {
+ case ID_AVATARLISTPOPUP_SAVEAS:
+ {
+ HANDLE hContact = (HANDLE) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ ListEntry *le = (ListEntry*) SendMessage(list, LB_GETITEMDATA, pos, 0);
+ ShowSaveDialog(hwnd, le->filename, hContact);
+ break;
+ }
+ case ID_AVATARLISTPOPUP_DELETE:
+ {
+ ListEntry *le = (ListEntry*) SendMessage(list, LB_GETITEMDATA, pos, 0);
+
+ BOOL blDelete;
+
+ if(le->dbe)
+ blDelete = MessageBox(hwnd, TranslateT("Are you sure you wish to delete this history entry?\nOnly the entry in history will be deleted, bitmap file will be kept!"),
+ TranslateT("Delete avatar log?"), MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2|MB_SETFOREGROUND|MB_TOPMOST) == IDYES;
+ else
+ blDelete = MessageBox(hwnd, TranslateT("Are you sure you wish to delete this avatar shortcut?\nOnly shortcut will be deleted, bitmap file will be kept!"),
+ TranslateT("Delete avatar log?"), MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2|MB_SETFOREGROUND|MB_TOPMOST) == IDYES;
+
+ if (blDelete)
+ {
+ HANDLE hContact = (HANDLE) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+
+ if(le->dbe)
+ CallService(MS_DB_EVENT_DELETE, (WPARAM) hContact, (LPARAM) le->dbe);
+ else
+ DeleteFile(le->filelink);
+
+ delete le;
+
+ SendMessage(list, LB_DELETESTRING, pos, 0);
+
+ int count = SendMessage(list, LB_GETCOUNT, 0, 0);
+ if (count > 0)
+ {
+ if (pos >= count)
+ pos = count -1;
+ SendMessage(list, LB_SETCURSEL, pos, 0);
+ }
+
+ UpdateAvatarPic(hwnd);
+ EnableDisableControls(hwnd);
+ }
+ break;
+ }
+ case ID_AVATARLISTPOPUP_DELETE_BOTH:
+ {
+ ListEntry *le = (ListEntry*) SendMessage(list, LB_GETITEMDATA, pos, 0);
+
+ BOOL blDelete;
+
+ if(le->dbe)
+ blDelete = MessageBox(hwnd, TranslateT("Are you sure you wish to delete this archived avatar?\nThis will delete the history entry and the bitmap file.\nWARNING:This can affect more than one entry in history!"),
+ TranslateT("Delete avatar?"), MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2|MB_SETFOREGROUND|MB_TOPMOST) == IDYES;
+ else
+ blDelete = MessageBox(hwnd, TranslateT("Are you sure you wish to delete this archived avatar?\nThis will delete the shortcut and the bitmap file.\nWARNING:This can affect more than one shortcut!"),
+ TranslateT("Delete avatar?"), MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2|MB_SETFOREGROUND|MB_TOPMOST) == IDYES;
+
+ if (blDelete)
+ {
+ HANDLE hContact = (HANDLE) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+
+ DeleteFile(le->filename);
+
+ if(le->dbe)
+ CallService(MS_DB_EVENT_DELETE, (WPARAM) hContact, (LPARAM) le->dbe);
+ else
+ DeleteFile(le->filelink);
+
+ delete le;
+
+ SendMessage(list, LB_DELETESTRING, pos, 0);
+
+ int count = SendMessage(list, LB_GETCOUNT, 0, 0);
+ if (count > 0)
+ {
+ if (pos >= count)
+ pos = count -1;
+ SendMessage(list, LB_SETCURSEL, pos, 0);
+ }
+
+ UpdateAvatarPic(hwnd);
+ EnableDisableControls(hwnd);
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case WM_COMMAND:
+ {
+ switch(LOWORD(wParam))
+ {
+ case IDOK:
+ if(HIWORD(wParam) == BN_CLICKED)
+ {
+ HANDLE hContact = (HANDLE) GetWindowLongPtr(hwnd, GWLP_USERDATA);
+
+ db_byte_set(hContact, MODULE_NAME, "AvatarPopups", (BYTE) IsDlgButtonChecked(hwnd, IDC_POPUPUSER));
+ db_byte_set(hContact, MODULE_NAME, "LogToDisk", (BYTE) IsDlgButtonChecked(hwnd, IDC_LOGUSER));
+ db_byte_set(hContact, MODULE_NAME, "LogToHistory", (BYTE) IsDlgButtonChecked(hwnd, IDC_HISTORYUSER));
+
+ CleanupAvatarPic(hwnd);
+ EndDialog(hwnd, 0);
+ return TRUE;
+ }
+ break;
+ case IDC_AVATARLIST:
+ if(HIWORD(wParam) == LBN_SELCHANGE)
+ {
+ UpdateAvatarPic(hwnd);
+ EnableDisableControls(hwnd);
+ return TRUE;
+ }
+ break;
+ case IDC_OPENFOLDER:
+ if(HIWORD(wParam) == BN_CLICKED)
+ {
+ if (opts.log_per_contact_folders)
+ {
+ TCHAR avfolder[MAX_PATH];
+ HANDLE hContact = (HANDLE)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ GetContactFolder(avfolder, hContact);
+ ShellExecute(NULL, db_byte_get(NULL, MODULE_NAME, "OpenFolderMethod", 0) ? _T("explore") : _T("open"), avfolder, NULL, NULL, SW_SHOWNORMAL);
+ return TRUE;
+ }
+ }
+ break;
+ case IDC_NEXT:
+ if(HIWORD(wParam) == BN_CLICKED)
+ {
+ HWND list = GetDlgItem(hwnd, IDC_AVATARLIST);
+ SendMessage(list, LB_SETCURSEL, SendMessage(list, LB_GETCURSEL, 0, 0) +1, 0);
+ UpdateAvatarPic(hwnd);
+ EnableDisableControls(hwnd);
+ return TRUE;
+ }
+ break;
+ case IDC_BACK:
+ if(HIWORD(wParam) == BN_CLICKED)
+ {
+ HWND list = GetDlgItem(hwnd, IDC_AVATARLIST);
+ int cursel = SendMessage(list, LB_GETCURSEL, 0, 0);
+ if (cursel == LB_ERR)
+ SendMessage(list, LB_SETCURSEL, SendMessage(list, LB_GETCOUNT, 0, 0) -1, 0);
+ else
+ SendMessage(list, LB_SETCURSEL, cursel -1, 0);
+ UpdateAvatarPic(hwnd);
+ EnableDisableControls(hwnd);
+ return TRUE;
+ }
+ break;
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
+
+
+
+int FillAvatarListFromFolder(HWND list, HANDLE hContact)
+{
+ int max_pos = 0;
+ TCHAR dir[MAX_PATH], path[MAX_PATH], lnk[MAX_PATH];
+ WIN32_FIND_DATA finddata;
+
+ GetContactFolder(dir, hContact);
+ mir_sntprintf(path, MAX_PATH, _T("%s\\*.lnk"), dir);
+
+ HANDLE hFind = FindFirstFile(path, &finddata);
+ if (hFind == INVALID_HANDLE_VALUE)
+ return 0;
+
+ do
+ {
+ if(finddata.cFileName[0] != '.')
+ {
+ mir_sntprintf(lnk, MAX_PATH, _T("%s\\%s"), dir, finddata.cFileName);
+ if (ResolveShortcut(lnk, path))
+ {
+ // Add to list
+ ListEntry *le = new ListEntry();
+ le->filename = mir_tstrdup(path);
+ le->filelink = mir_tstrdup(lnk);
+
+ TCHAR *p = _tcschr(finddata.cFileName, _T('.'));
+ if (p != NULL)
+ p[0] = _T('\0');
+ max_pos = SendMessage(list, LB_ADDSTRING, 0, (LPARAM) finddata.cFileName);
+ SendMessage(list, LB_SETITEMDATA, max_pos, (LPARAM) le);
+ }
+ }
+ } while(FindNextFile(hFind, &finddata));
+ FindClose(hFind);
+ SendMessage(list, LB_SETCURSEL, max_pos, 0); // Set to first item
+ return 0;
+}
+
+
+
+int FillAvatarListFromDB(HWND list, HANDLE hContact)
+{
+ int max_pos = 0;
+ BYTE blob[2048];
+ HANDLE dbe = (HANDLE) CallService(MS_DB_EVENT_FINDFIRST, (WPARAM) hContact, 0);
+ while(dbe != NULL)
+ {
+ DBEVENTINFO dbei = {0};
+ dbei.cbSize = sizeof(dbei);
+ dbei.cbBlob = sizeof(blob);
+ dbei.pBlob = blob;
+ if (CallService(MS_DB_EVENT_GET, (WPARAM) dbe, (LPARAM) &dbei) == 0
+ && dbei.eventType == EVENTTYPE_AVATAR_CHANGE)
+ {
+
+ // Get last char from blob
+ int i = dbei.cbBlob - 2;
+ for(; i >= 0 && dbei.pBlob[i] != 0; i--) ;
+
+ if (i != (int) dbei.cbBlob - 2 && i >= 0)
+ {
+ // Oki, found one
+
+ // Get time
+ TCHAR date[64];
+ DBTIMETOSTRINGT tts = {0};
+ tts.szFormat = _T("d s");
+ tts.szDest = date;
+ tts.cbDest = sizeof(date);
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM) dbei.timestamp, (LPARAM) &tts);
+
+ // Get file in disk
+ char path[MAX_PATH] = "";
+ CallService(MS_UTILS_PATHTOABSOLUTE,(WPARAM) (char *) &dbei.pBlob[i+1],(LPARAM)path);
+ TCHAR *filename = mir_a2t(path);
+
+ // Add to list
+ ListEntry *le = new ListEntry();
+ le->dbe = dbe;
+ le->filename = filename;
+
+ max_pos = SendMessage(list,LB_ADDSTRING, 0, (LPARAM) date);
+ SendMessage(list, LB_SETITEMDATA, max_pos, (LPARAM) le);
+ }
+ }
+
+ dbe = (HANDLE) CallService(MS_DB_EVENT_FINDNEXT, (WPARAM) dbe, 0);
+ }
+
+ SendMessage(list, LB_SETCURSEL, max_pos, 0); // Set to first item
+ return 0;
+}
+
+BOOL UpdateAvatarPic(HWND hwnd)
+{
+ HWND hwndpic = GetDlgItem(hwnd, IDC_AVATAR);
+ if (!hwnd || !hwndpic)
+ return -1;
+
+ HWND list = GetDlgItem(hwnd, IDC_AVATARLIST);
+ TCHAR *filename = GetCurrentSelFile(list);
+ if(!filename)
+ {
+ SetDlgItemText(hwnd,IDC_AVATARPATH,TranslateT("avatar path is null."));
+ return 0;
+ }
+ SetDlgItemText(hwnd,IDC_AVATARPATH,filename);
+
+ HBITMAP avpic = (HBITMAP) CallService(MS_IMG_LOAD, (WPARAM) filename, IMGL_TCHAR);
+
+ BOOL found_image = (avpic != NULL);
+
+ avpic = (HBITMAP)SendMessage(hwndpic, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)avpic);
+ if (avpic)
+ DeleteObject(avpic);
+
+ return found_image;
+}
+
+int CleanupAvatarPic(HWND hwnd)
+{
+ HWND hwndpic = GetDlgItem(hwnd, IDC_AVATAR);
+ if (!hwnd || !hwndpic)
+ return -1;
+
+ HBITMAP avpic = (HBITMAP)SendMessage(hwndpic, STM_GETIMAGE, 0, 0);
+ if(avpic)
+ DeleteObject(avpic);
+ return 0;
+}
+
+int PreBuildContactMenu(WPARAM wParam,LPARAM lParam)
+{
+ CLISTMENUITEM clmi = {0};
+ clmi.cbSize = sizeof(clmi);
+ clmi.flags = CMIM_FLAGS;
+
+ char *proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0);
+ if (!ProtocolEnabled(proto))
+ clmi.flags |= CMIF_HIDDEN;
+
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) hMenu, (LPARAM) &clmi);
+
+ return 0;
+}
+
+void InitMenuItem()
+{
+ CLISTMENUITEM mi = {0};
+
+ hServices[2] = CreateServiceFunction(MS_AVATARHISTORY_SHOWDIALOG, ShowDialogSvc);
+
+ mi.cbSize = sizeof(mi);
+ mi.ptszName = LPGENT("View Avatar History");
+ mi.flags = CMIF_TCHAR;
+ mi.position = 1000090010;
+ mi.hIcon = createDefaultOverlayedIcon(FALSE);
+ mi.pszService = MS_AVATARHISTORY_SHOWDIALOG;
+ hMenu = Menu_AddContactMenuItem(&mi);
+ DestroyIcon(mi.hIcon);
+}
+
+static INT_PTR ShowDialogSvc(WPARAM wParam, LPARAM lParam)
+{
+ OpenAvatarDialog((HANDLE)wParam, (char*)lParam);
+ return 0;
+}
+
+TCHAR* GetCurrentSelFile(HWND list)
+{
+ int cursel = SendMessage(list, LB_GETCURSEL, 0, 0);
+ if (cursel > -1)
+ return ((ListEntry*) SendMessage(list, LB_GETITEMDATA, cursel, 0))->filename;
+ else
+ return NULL;
+}
+
+int ShowSaveDialog(HWND hwnd, TCHAR* fn, HANDLE hContact)
+{
+ TCHAR filter[MAX_PATH];
+ TCHAR file[MAX_PATH];
+ OPENFILENAME ofn;
+ ZeroMemory(&ofn, sizeof(OPENFILENAME));
+ DBVARIANT dbvInitDir = {0};
+ bool ret = (DBGetContactSettingTString(hContact,MODULE_NAME,"SavedAvatarFolder",&dbvInitDir)== 0);
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.hwndOwner = hwnd;
+ ofn.hInstance = hInst;
+
+ CallService(MS_UTILS_GETBITMAPFILTERSTRINGST, MAX_PATH, (LPARAM)filter);
+ ofn.lpstrFilter = filter;
+
+ ofn.nFilterIndex = 1;
+ lstrcpyn(file, _tcsrchr(fn, '\\')+1, sizeof(file));
+ ofn.lpstrFile = file;
+
+ TCHAR *displayName = (TCHAR*) CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,GCDNF_TCHAR);
+ if(displayName)
+ {
+ TCHAR title[MAX_PATH];
+ mir_sntprintf(title,sizeof(title),TranslateT("Save Avatar for %s"),displayName);
+ ofn.lpstrTitle = title;
+ }
+ else
+ {
+ ofn.lpstrTitle = TranslateT("Save Avatar");
+ }
+ ofn.nMaxFile = MAX_PATH;
+ ofn.Flags = OFN_PATHMUSTEXIST | OFN_DONTADDTORECENT;
+ ofn.lpstrDefExt = _tcsrchr(fn, '.')+1;
+ if(ret)
+ {
+ ofn.lpstrInitialDir = dbvInitDir.ptszVal;
+ DBFreeVariant(&dbvInitDir);
+ }
+ else
+ {
+ ofn.lpstrInitialDir = _T(".");
+ }
+ if(GetSaveFileName(&ofn))
+ {
+ CopyFile(fn, file, FALSE);
+ DBWriteContactSettingTString(hContact,MODULE_NAME,"SavedAvatarFolder",file);
+ }
+ return 0;
+}
diff --git a/plugins/AvatarHistory/src/AvatarHistory.cpp b/plugins/AvatarHistory/src/AvatarHistory.cpp new file mode 100644 index 0000000000..3434dd0cc3 --- /dev/null +++ b/plugins/AvatarHistory/src/AvatarHistory.cpp @@ -0,0 +1,964 @@ +/* +Avatar History Plugin +--------- + + This plugin uses the event provided by Avatar Service to + automatically back up contacts' avatars when they change. + Copyright (C) 2006 Matthew Wild - Email: mwild1@gmail.com + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ +#include "AvatarHistory.h" + +HINSTANCE hInst; +PLUGINLINK *pluginLink; +DWORD mirVer; + +HANDLE hHooks[6] = {0}; +HANDLE hServices[3] = {0}; + +HANDLE hFolder = NULL; + +char *metacontacts_proto = NULL; + +TCHAR profilePath[MAX_PATH]; // database profile path (read at startup only) +TCHAR basedir[MAX_PATH]; +int hLangpack = 0; +HANDLE hAvatarWindowsList = NULL; + +static int ModulesLoaded(WPARAM wParam, LPARAM lParam); +static int PreShutdown(WPARAM wParam, LPARAM lParam); +static int AvatarChanged(WPARAM wParam, LPARAM lParam); +int OptInit(WPARAM wParam,LPARAM lParam); + +TCHAR * GetHistoryFolder(TCHAR *fn); +TCHAR * GetProtocolFolder(TCHAR *fn, char *proto); +TCHAR * GetOldStyleAvatarName(TCHAR *fn, HANDLE hContact); + +void InitMenuItem(); + +void * GetHistoryEventText(HANDLE hContact, HANDLE hDbEvent, DBEVENTINFO *dbe, int format); + +// Services +static INT_PTR IsEnabled(WPARAM wParam, LPARAM lParam); +static INT_PTR GetCachedAvatar(WPARAM wParam, LPARAM lParam); +TCHAR * GetCachedAvatar(char *proto, TCHAR *hash); +BOOL CreateShortcut(TCHAR *file, TCHAR *shortcut); + +PLUGININFOEX pluginInfo={ + sizeof(PLUGININFOEX), + "Avatar History", + PLUGIN_MAKE_VERSION(0,0,3,3), + "This plugin keeps backups of all your contacts' avatar changes and/or shows popups.", + "Matthew Wild (MattJ), Ricardo Pescuma Domenecci", + "mwild1@gmail.com", + "© 2006-2012 Matthew Wild, Ricardo Pescuma Domenecci", + "http://pescuma.org/miranda/avatarhist", + UNICODE_AWARE, + { 0xdbe8c990, 0x7aa0, 0x458d, { 0xba, 0xb7, 0x33, 0xeb, 0x7, 0x23, 0x8e, 0x71 } } // {DBE8C990-7AA0-458d-BAB7-33EB07238E71} +}; + +extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + hInst = hinstDLL; + return TRUE; +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +static const MUUID interfaces[] = { MIID_AVATAR_CHANGE_LOGGER, MIID_AVATAR_CHANGE_NOTIFIER, MIID_LAST }; + +extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + +static INT_PTR CALLBACK FirstRunDlgProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + switch(uMsg) + { + case WM_INITDIALOG: + { + SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) createDefaultOverlayedIcon(TRUE)); + SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) createDefaultOverlayedIcon(FALSE)); + TranslateDialogDefault(hwnd); + + CheckDlgButton(hwnd, IDC_MIR_PROTO, BST_CHECKED); + break; + } + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case IDOK: + { + int ret = 0; + + if (IsDlgButtonChecked(hwnd, IDC_MIR_SAME)) + ret = IDC_MIR_SAME; + else if (IsDlgButtonChecked(hwnd, IDC_MIR_PROTO)) + ret = IDC_MIR_PROTO; + else if (IsDlgButtonChecked(hwnd, IDC_MIR_SHORT)) + ret = IDC_MIR_SHORT; + else if (IsDlgButtonChecked(hwnd, IDC_SHORT)) + ret = IDC_SHORT; + else if (IsDlgButtonChecked(hwnd, IDC_DUP)) + ret = IDC_DUP; + + EndDialog(hwnd, ret); + return TRUE; + } + } + break; + } + case WM_CLOSE: + { + EndDialog(hwnd, 0); + return TRUE; + } + } + + return FALSE; +} + +extern "C" __declspec(dllexport) int Load(void) +{ + mir_getLP(&pluginInfo); + + // Is first run? + if (DBGetContactSettingByte(NULL, MODULE_NAME, "FirstRun", 1)) + { + // Show dialog + int ret = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_FIRST_RUN), NULL, FirstRunDlgProc, 0); + if (ret == 0) + return -1; + + // Write settings + + DBWriteContactSettingByte(NULL, MODULE_NAME, "LogToDisk", 1); + + if (ret == IDC_MIR_SAME) + DBWriteContactSettingByte(NULL, MODULE_NAME, "LogKeepSameFolder", 1); + else + DBWriteContactSettingByte(NULL, MODULE_NAME, "LogKeepSameFolder", 0); + + if (ret == IDC_MIR_SHORT || ret == IDC_SHORT || ret == IDC_DUP) + DBWriteContactSettingByte(NULL, MODULE_NAME, "LogPerContactFolders", 1); + else + DBWriteContactSettingByte(NULL, MODULE_NAME, "LogPerContactFolders", 0); + + if (ret == IDC_DUP) + DBWriteContactSettingByte(NULL, MODULE_NAME, "StoreAsHash", 0); + else + DBWriteContactSettingByte(NULL, MODULE_NAME, "StoreAsHash", 1); + + if (ret == IDC_MIR_SAME || ret == IDC_MIR_PROTO || ret == IDC_MIR_SHORT) + DBWriteContactSettingByte(NULL, MODULE_NAME, "LogToHistory", 1); + else + DBWriteContactSettingByte(NULL, MODULE_NAME, "LogToHistory", 0); + + DBWriteContactSettingByte(NULL, MODULE_NAME, "FirstRun", 0); + } + + LoadOptions(); + + hHooks[0] = HookEvent(ME_SYSTEM_MODULESLOADED,ModulesLoaded); + hHooks[1] = HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown); + hHooks[3] = HookEvent(ME_OPT_INITIALISE, OptInit); + hHooks[4] = HookEvent(ME_SKIN2_ICONSCHANGED, IcoLibIconsChanged); + hHooks[5] = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PreBuildContactMenu); + + hServices[0] = CreateServiceFunction(MS_AVATARHISTORY_ENABLED, IsEnabled); + hServices[1] = CreateServiceFunction(MS_AVATARHISTORY_GET_CACHED_AVATAR, GetCachedAvatar); + + if(CallService(MS_DB_GETPROFILEPATHT, MAX_PATH, (LPARAM)profilePath) != 0) + _tcscpy(profilePath, _T(".")); // Failed, use current dir + + SkinAddNewSoundExT("avatar_changed",LPGENT("Avatar History"),LPGENT("Contact changed avatar")); + SkinAddNewSoundExT("avatar_removed",LPGENT("Avatar History"),LPGENT("Contact removed avatar")); + + hAvatarWindowsList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); + + SetupIcoLib(); + InitMenuItem(); + + return 0; +} + +static int ModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + mir_sntprintf(basedir, MAX_REGS(basedir), _T("%s\\Avatars History"), profilePath); + + hFolder = FoldersRegisterCustomPathT(LPGEN("Avatars"), LPGEN("Avatar History"), + PROFILE_PATHT _T("\\") CURRENT_PROFILET _T("\\Avatars History")); + InitPopups(); + + if (ServiceExists(MS_MC_GETPROTOCOLNAME)) + metacontacts_proto = (char *) CallService(MS_MC_GETPROTOCOLNAME, 0, 0); + + // updater plugin support + if(ServiceExists(MS_UPDATE_REGISTER)) + { + Update upd = {0}; + char szCurrentVersion[30]; + + upd.cbSize = sizeof(upd); + upd.szComponentName = pluginInfo.shortName; + + upd.szUpdateURL = UPDATER_AUTOREGISTER; + + upd.szBetaVersionURL = "http://code.google.com/p/pescuma/downloads/list?q=label:Plugin-AVH"; + upd.szBetaChangelogURL = "http://code.google.com/p/pescuma/source/list"; +#ifdef _WIN64 + upd.pbBetaVersionPrefix = (BYTE *) "Avatar History (x64) "; + upd.szBetaUpdateURL = "http://pescuma.googlecode.com/files/avatarhistW.%VERSION%-x64.zip"; +#elif _UNICODE + upd.pbBetaVersionPrefix = (BYTE *) "Avatar History (Unicode) "; + upd.szBetaUpdateURL = "http://pescuma.googlecode.com/files/avatarhistW.%VERSION%.zip"; +#else + upd.pbBetaVersionPrefix = (BYTE *) "Avatar History (ANSI) "; + upd.szBetaUpdateURL = "http://pescuma.googlecode.com/files/avatarhist.%VERSION%.zip"; +#endif + upd.cpbBetaVersionPrefix = (int) strlen((char *)upd.pbBetaVersionPrefix); + + upd.pbVersion = (BYTE *)CreateVersionStringPluginEx(&pluginInfo, szCurrentVersion); + upd.cpbVersion = (int) strlen((char *)upd.pbVersion); + + CallService(MS_UPDATE_REGISTER, 0, (LPARAM)&upd); + } + + if (DBGetContactSettingByte(NULL, MODULE_NAME, "LogToHistory", AVH_DEF_LOGTOHISTORY)) + { + char *templates[] = { "Avatar change\nchanged his/her avatar", + "Avatar removal\nremoved his/her avatar" }; + HICON hIcon = createDefaultOverlayedIcon(FALSE); + HistoryEvents_RegisterWithTemplates(MODULE_NAME, "avatarchange", "Avatar change", EVENTTYPE_AVATAR_CHANGE, hIcon, + HISTORYEVENTS_FORMAT_CHAR | HISTORYEVENTS_FORMAT_WCHAR | HISTORYEVENTS_FORMAT_RICH_TEXT, + HISTORYEVENTS_FLAG_SHOW_IM_SRMM | HISTORYEVENTS_FLAG_EXPECT_CONTACT_NAME_BEFORE, + GetHistoryEventText, templates, MAX_REGS(templates)); + DestroyIcon(hIcon); + } + + hHooks[2] = HookEvent(ME_AV_CONTACTAVATARCHANGED, AvatarChanged); + + return 0; +} + +static int PreShutdown(WPARAM wParam, LPARAM lParam) +{ + int i; + + for (i = 0; i < MAX_REGS(hHooks); i++) + UnhookEvent(hHooks[i]); + + for (i = 0; i < MAX_REGS(hServices); i++) + DestroyServiceFunction(hServices[i]); + + WindowList_Broadcast(hAvatarWindowsList,WM_CLOSE,0,0); + + return 0; +} + +BOOL ProtocolEnabled(const char *proto) +{ + if (proto == NULL) + return FALSE; + + char setting[256]; + mir_snprintf(setting, sizeof(setting), "%sEnabled", proto); + return (BOOL) DBGetContactSettingByte(NULL, MODULE_NAME, setting, TRUE); +} + +BOOL ContactEnabled(HANDLE hContact, char *setting, int def) +{ + if (hContact == NULL) + return FALSE; + + char *proto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if (!ProtocolEnabled(proto)) + return FALSE; + + BYTE globpref = db_byte_get(NULL, MODULE_NAME, setting, def); + BYTE userpref = db_byte_get(hContact, MODULE_NAME, setting, BST_INDETERMINATE); + + return (globpref && userpref == BST_INDETERMINATE) || userpref == BST_CHECKED; +} + +// Returns true if the unicode buffer only contains 7-bit characters. +BOOL IsUnicodeAscii(const WCHAR * pBuffer, int nSize) +{ + BOOL bResult = TRUE; + int nIndex; + + for (nIndex = 0; nIndex < nSize; nIndex++) { + if (pBuffer[nIndex] > 0x7F) { + bResult = FALSE; + break; + } + } + return bResult; +} + +void ConvertToFilename(TCHAR *str, size_t size) { + for(size_t i = 0; i < size && str[i] != '\0'; i++) { + switch(str[i]) { + case '/': + case '\\': + case ':': + case '*': + case '?': + case '"': + case '<': + case '>': + case '|': + //case '.': + str[i] = '_'; + } + } +} + +void ErrorExit(HANDLE hContact,LPTSTR lpszFunction) +{ + // Retrieve the system error message for the last-error code + + LPVOID lpMsgBuf; + LPVOID lpDisplayBuf; + DWORD dw = GetLastError(); + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dw, + MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), + (LPTSTR) &lpMsgBuf, + 0, NULL ); + + // Display the error message and exit the process + + lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, + (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); + StringCchPrintf((LPTSTR)lpDisplayBuf, + LocalSize(lpDisplayBuf) / sizeof(TCHAR), + TEXT("%s failed with error %d: %s"), + lpszFunction, dw, lpMsgBuf); + ShowDebugPopup(hContact,TEXT("Error"), (LPCTSTR)lpDisplayBuf); + + LocalFree(lpMsgBuf); + LocalFree(lpDisplayBuf); +} + +#ifdef _UNICODE + +#define CS "%S" + +#else + +#define CS "%s" + +#endif + + +TCHAR * GetExtension(TCHAR *file) +{ + if(file == NULL) return _T(""); + TCHAR *ext = _tcsrchr(file, _T('.')); + if (ext != NULL) + ext++; + else + ext = _T(""); + + return ext; +} + + +void CreateOldStyleShortcut(HANDLE hContact, TCHAR *history_filename) +{ + TCHAR shortcut[MAX_PATH] = _T(""); + + GetOldStyleAvatarName(shortcut, hContact); + + mir_sntprintf(shortcut, MAX_REGS(shortcut), _T("%s.%s.lnk"), shortcut, + GetExtension(history_filename)); + + if (!CreateShortcut(history_filename, shortcut)) + { + ShowPopup(hContact, _T("Avatar History: Unable to create shortcut"), shortcut); + } + else + { + ShowDebugPopup(hContact, _T("AVH Debug: Shortcut created successfully"), shortcut); + } +} + + +BOOL CopyImageFile(TCHAR *old_file, TCHAR *new_file) +{ + TCHAR *ext = GetExtension(old_file); + mir_sntprintf(new_file, MAX_PATH, _T("%s.%s"), new_file, ext); + + BOOL ret = CopyFile(old_file, new_file, TRUE); + if(!ret) + ErrorExit(NULL,_T("CopyImageFile")); + return !ret; +} + +// fired when the contacts avatar changes +// wParam = hContact +// lParam = struct avatarCacheEntry *cacheEntry +// the event CAN pass a NULL pointer in lParam which means that the avatar has changed, +// but is no longer valid (happens, when a contact removes his avatar, for example). +// DONT DESTROY the bitmap handle passed in the struct avatarCacheEntry * +// +// It is also possible that this event passes 0 as wParam (hContact), in which case, +// a protocol picture (pseudo - avatar) has been changed. +static int AvatarChanged(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE)wParam; + CONTACTAVATARCHANGEDNOTIFICATION* avatar = (CONTACTAVATARCHANGEDNOTIFICATION*)lParam; + + if (hContact == NULL) + { + ShowDebugPopup(NULL, _T("AVH Debug"), _T("Invalid contact/avatar... skipping")); + return 0; + } + + char *proto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0); + if (proto == NULL) + { + ShowDebugPopup(hContact, _T("AVH Debug"), _T("Invalid protocol... skipping")); + return 0; + } + else if (metacontacts_proto != NULL && strcmp(metacontacts_proto, proto) == 0) + { + ShowDebugPopup(hContact, _T("AVH Debug"), _T("Ignoring metacontacts notification")); + return 0; + } + + DBVARIANT dbvOldHash = {0}; + bool ret = (DBGetContactSettingTString(hContact,MODULE_NAME,"AvatarHash",&dbvOldHash) == 0); + + if (avatar == NULL) + { + if (!ret || !_tcscmp(dbvOldHash.ptszVal, _T("-"))) + { + //avoid duplicate "removed avatar" notifications + //do not notify on an empty profile + ShowDebugPopup(hContact, _T("AVH Debug"), _T("Removed avatar, no avatar before...skipping")); + DBFreeVariant(&dbvOldHash); + return 0; + } + SkinPlaySound("avatar_removed"); + + // Is a flash avatar or avs could not load it + DBWriteContactSettingTString(hContact, MODULE_NAME, "AvatarHash", _T("-")); + + if (ContactEnabled(hContact, "AvatarPopups", AVH_DEF_AVPOPUPS) && opts.popup_show_removed) + ShowPopup(hContact, NULL, opts.popup_removed); + + if (ContactEnabled(hContact, "LogToHistory", AVH_DEF_LOGTOHISTORY)) + HistoryEvents_AddToHistorySimple(hContact, EVENTTYPE_AVATAR_CHANGE, 1, DBEF_READ); + } + else + { + if(ret && !_tcscmp(dbvOldHash.ptszVal, avatar->hash)) + { + // same avatar hash, skipping + ShowDebugPopup(hContact, _T("AVH Debug"), _T("Hashes are the same... skipping")); + DBFreeVariant(&dbvOldHash); + return 0; + } + SkinPlaySound("avatar_changed"); + DBWriteContactSettingTString(hContact, "AvatarHistory", "AvatarHash", avatar->hash); + + TCHAR history_filename[MAX_PATH] = _T(""); + + if (ContactEnabled(hContact, "LogToDisk", AVH_DEF_LOGTODISK)) + { + if (!opts.log_store_as_hash) + { + if (opts.log_per_contact_folders) + { + GetOldStyleAvatarName(history_filename, hContact); + if (CopyImageFile(avatar->filename, history_filename)) + ShowPopup(hContact, _T("Avatar History: Unable to save avatar"), history_filename); + else + ShowDebugPopup(hContact, _T("AVH Debug: File copied successfully"), history_filename); + + if (ServiceExists(MS_MC_GETMETACONTACT)) + { + HANDLE hMetaContact = (HANDLE) CallService(MS_MC_GETMETACONTACT, wParam, 0); + + if (hMetaContact != NULL && ContactEnabled(hMetaContact, "LogToDisk", AVH_DEF_LOGTOHISTORY)) + { + TCHAR filename[MAX_PATH] = _T(""); + + GetOldStyleAvatarName(filename, hMetaContact); + if (CopyImageFile(avatar->filename, filename)) + ShowPopup(hContact, _T("Avatar History: Unable to save avatar"), filename); + else + ShowDebugPopup(hContact, _T("AVH Debug: File copied successfully"), filename); + } + } + } + } + else + { + // See if we already have the avatar + TCHAR hash[128]; + lstrcpyn(hash, avatar->hash, sizeof(hash)); + ConvertToFilename(hash, sizeof(hash)); + + TCHAR *file = GetCachedAvatar(proto, hash); + + if (file != NULL) + { + lstrcpyn(history_filename, file, MAX_REGS(history_filename)); + mir_free(file); + } + else + { + if (opts.log_keep_same_folder) + GetHistoryFolder(history_filename); + else + GetProtocolFolder(history_filename, proto); + + mir_sntprintf(history_filename, MAX_REGS(history_filename), + _T("%s\\%s"), history_filename, hash); + + if (CopyImageFile(avatar->filename, history_filename)) + ShowPopup(hContact, _T("Avatar History: Unable to save avatar"), history_filename); + else + ShowDebugPopup(hContact, _T("AVH Debug: File copied successfully"), history_filename); + } + + if (opts.log_per_contact_folders) + { + CreateOldStyleShortcut(hContact, history_filename); + + if (ServiceExists(MS_MC_GETMETACONTACT)) + { + HANDLE hMetaContact = (HANDLE) CallService(MS_MC_GETMETACONTACT, wParam, 0); + + if (hMetaContact != NULL && ContactEnabled(hMetaContact, "LogToDisk", AVH_DEF_LOGTOHISTORY)) + CreateOldStyleShortcut(hMetaContact, history_filename); + } + } + } + } + + + if (ContactEnabled(hContact, "AvatarPopups", AVH_DEF_AVPOPUPS) && opts.popup_show_changed) + ShowPopup(hContact, NULL, opts.popup_changed); + + if (ContactEnabled(hContact, "LogToHistory", AVH_DEF_LOGTOHISTORY)) + { + TCHAR rel_path[MAX_PATH] = _T(""); + CallService(MS_UTILS_PATHTORELATIVET,(WPARAM)history_filename,(LPARAM)rel_path); +#ifdef _UNICODE + char *blob = mir_utf8encodeT(rel_path); + int flags = DBEF_READ | DBEF_UTF; +#else + char *blob = mir_strdup(rel_path); + int flags = DBEF_READ; +#endif + HistoryEvents_AddToHistoryEx(hContact, EVENTTYPE_AVATAR_CHANGE, 0, NULL, 0, (PBYTE) blob, (int) strlen(blob) + 1, flags); + } + } + + return 0; +} + +extern "C" __declspec(dllexport) int Unload(void) +{ + return 0; +} + + +static INT_PTR IsEnabled(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE) wParam; + return ContactEnabled(hContact, "LogToDisk", AVH_DEF_LOGTODISK) + || ContactEnabled(hContact, "AvatarPopups", AVH_DEF_AVPOPUPS) + || ContactEnabled(hContact, "LogToHistory", AVH_DEF_LOGTOHISTORY); +} + + +/* +Get cached avatar + +wParam: (char *) protocol name +lParam: (TCHAR *) hash +return: (TCHAR *) NULL if none is found or the path to the avatar. You need to free this string + with mir_free. +*/ +static INT_PTR GetCachedAvatar(WPARAM wParam, LPARAM lParam) +{ + TCHAR hash[128]; + lstrcpyn(hash, (TCHAR *) lParam, sizeof(hash)); + ConvertToFilename(hash, sizeof(hash)); + return (INT_PTR) GetCachedAvatar((char *) wParam, hash); +} + +TCHAR * GetCachedAvatar(char *proto, TCHAR *hash) +{ + TCHAR *ret = NULL; + TCHAR file[1024] = _T(""); + TCHAR search[1024] = _T(""); + if (opts.log_keep_same_folder) + GetHistoryFolder(file); + else + GetProtocolFolder(file, proto); + + mir_sntprintf(search, MAX_REGS(search), _T("%s\\%s.*"), file, hash); + + WIN32_FIND_DATA finddata; + HANDLE hFind = FindFirstFile(search, &finddata); + if (hFind == INVALID_HANDLE_VALUE) + return NULL; + + do + { + size_t len = lstrlen(finddata.cFileName); + if (len > 4 + && (!lstrcmpi(&finddata.cFileName[len-4], _T(".png")) + || !lstrcmpi(&finddata.cFileName[len-4], _T(".bmp")) + || !lstrcmpi(&finddata.cFileName[len-4], _T(".gif")) + || !lstrcmpi(&finddata.cFileName[len-4], _T(".jpg")) + || !lstrcmpi(&finddata.cFileName[len-5], _T(".jpeg")))) + { + mir_sntprintf(file, MAX_REGS(file), _T("%s\\%s"), file, finddata.cFileName); + ret = mir_tstrdup(file); + break; + } + } while(FindNextFile(hFind, &finddata)); + FindClose(hFind); + + return ret; +} + + +int GetUIDFromHContact(HANDLE contact, TCHAR* uinout, size_t uinout_len) +{ + CONTACTINFO cinfo; + + ZeroMemory(&cinfo,sizeof(CONTACTINFO)); + cinfo.cbSize = sizeof(CONTACTINFO); + cinfo.hContact = contact; + cinfo.dwFlag = CNF_UNIQUEID | CNF_TCHAR; + + bool found = true; + if(CallService(MS_CONTACT_GETCONTACTINFO,0,(LPARAM)&cinfo)==0) + { + if(cinfo.type == CNFT_ASCIIZ) + { + lstrcpyn(uinout, cinfo.pszVal, uinout_len); + // It is up to us to free the string + // The catch? We need to use Miranda's free(), not our CRT's :) + mir_free(cinfo.pszVal); + } + else if(cinfo.type == CNFT_DWORD) + { + _itot(cinfo.dVal,uinout,10); + } + else if(cinfo.type == CNFT_WORD) + { + _itot(cinfo.wVal,uinout,10); + } + else found = false; + } + else found = false; + + if (!found) + { + lstrcpyn(uinout, TranslateT("Unknown UIN"),uinout_len); + } + return 0; +} + + +TCHAR * GetHistoryFolder(TCHAR *fn) +{ + if (fn == NULL) return NULL; + FoldersGetCustomPathT(hFolder, fn, MAX_PATH, basedir); + if(!CreateDirectory(fn, NULL)) + ErrorExit(NULL,_T("GetHistoryFolder")); + + return fn; +} + + +TCHAR * GetProtocolFolder(TCHAR *fn, char *proto) +{ + GetHistoryFolder(fn); + + if (proto == NULL) + proto = Translate("Unknown Protocol"); + + mir_sntprintf(fn, MAX_PATH, _T("%s\\") _T(CS), fn, proto); + if(!CreateDirectory(fn, NULL)) + ErrorExit(NULL,_T("CreateDirectory")); + + return fn; +} + + +TCHAR * GetContactFolder(TCHAR *fn, HANDLE hContact) +{ + TCHAR uin[MAX_PATH]; + + char *proto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM) hContact, 0); + GetProtocolFolder(fn, proto); + + GetUIDFromHContact(hContact, uin, MAX_REGS(uin)); + mir_sntprintf(fn, MAX_PATH, _T("%s\\%s"), fn, uin); + if(!CreateDirectory(fn, NULL)) + ErrorExit(hContact,_T("CreateDirectory")); + ConvertToFilename(uin, sizeof(uin)); //added so that weather id's like "yw/CI0000" work + +#ifdef DBGPOPUPS + TCHAR log[1024]; + mir_sntprintf(log, MAX_REGS(log), _T("Path: %s\nProto: ") _T(CS) _T("\nUIN: %s"), fn, proto, uin); + ShowPopup(hContact, _T("AVH Debug: GetContactFolder"), log); +#endif + + return fn; +} + +TCHAR * GetOldStyleAvatarName(TCHAR *fn, HANDLE hContact) +{ + GetContactFolder(fn, hContact); + + SYSTEMTIME curtime; + GetLocalTime(&curtime); + mir_sntprintf(fn, MAX_PATH, + _T("%s\\%04d-%02d-%02d %02dh%02dm%02ds"), fn, + curtime.wYear, curtime.wMonth, curtime.wDay, + curtime.wHour, curtime.wMinute, curtime.wSecond); + ShowDebugPopup(hContact,_T("AVH Debug: GetOldStyleAvatarName"),fn); + return fn; +} + +BOOL CreateShortcut(TCHAR *file, TCHAR *shortcut) +{ + CoInitialize(NULL); + + IShellLink* psl = NULL; + + HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **) &psl); + + if (SUCCEEDED(hr)) + { + psl->SetPath(file); + + IPersistFile* ppf = NULL; + hr = psl->QueryInterface(IID_IPersistFile, (void **) &ppf); + + if (SUCCEEDED(hr)) + { +#ifdef _UNICODE + hr = ppf->Save(shortcut, TRUE); +#else + WCHAR tmp[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, shortcut, -1, tmp, MAX_PATH); + hr = ppf->Save(tmp, TRUE); +#endif + ppf->Release(); + } + + psl->Release(); + } + + if(FAILED(hr)) + ErrorExit(NULL,_T("CreateShortcut")); + return SUCCEEDED(hr); +} + + +BOOL ResolveShortcut(TCHAR *shortcut, TCHAR *file) +{ + CoInitialize(NULL); + + IShellLink* psl = NULL; + + HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **) &psl); + + if (SUCCEEDED(hr)) + { + IPersistFile* ppf = NULL; + hr = psl->QueryInterface(IID_IPersistFile, (void **) &ppf); + + if (SUCCEEDED(hr)) + { +#ifdef _UNICODE + hr = ppf->Load(shortcut, STGM_READ); +#else + WCHAR tmp[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, shortcut, -1, tmp, MAX_PATH); + hr = ppf->Load(tmp, STGM_READ); +#endif + + if (SUCCEEDED(hr)) + { + hr = psl->Resolve(NULL, SLR_UPDATE); + + if (SUCCEEDED(hr)) + { + WIN32_FIND_DATA wfd; + hr = psl->GetPath(file, MAX_PATH, &wfd, SLGP_RAWPATH); + } + } + + ppf->Release(); + } + psl->Release(); + } + + if(FAILED(hr)) + ErrorExit(NULL,_T("CreateShortcut")); + return SUCCEEDED(hr); +} + + +template<class T> +void ConvertToRTF(Buffer<char> *buffer, T *line) +{ + buffer->append("{\\uc1 ", 6); + + for (; *line; line++) + { + if (*line == (T)'\r' && line[1] == (T)'\n') { + buffer->append("\\line ", 6); + line++; + } + else if (*line == (T)'\n') { + buffer->append("\\line ", 6); + } + else if (*line == (T)'\t') { + buffer->append("\\tab ", 5); + } + else if (*line == (T)'\\' || *line == (T)'{' || *line == (T)'}') { + buffer->append('\\'); + buffer->append((char) *line); + } + else if (*line < 128) { + buffer->append((char) *line); + } + else + buffer->appendPrintf("\\u%d ?", *line); + } + + buffer->append('}'); +} + + +void GetRTFFor(Buffer<char> *buffer, HBITMAP hBitmap) +{ + BITMAP bmp; + GetObject(hBitmap, sizeof(bmp), &bmp); + + DWORD dwLen = bmp.bmWidth * bmp.bmHeight * (bmp.bmBitsPixel / 8); + BYTE *p = (BYTE *) malloc(dwLen); + if (p == NULL) + return; + + dwLen = GetBitmapBits(hBitmap, dwLen, p); + + buffer->appendPrintf("{\\pict\\wbitmap0\\wbmbitspixel%u\\wbmplanes%u\\wbmwidthbytes%u\\picw%u\\pich%u ", + bmp.bmBitsPixel, bmp.bmPlanes, bmp.bmWidthBytes, bmp.bmWidth, bmp.bmHeight); + + for (DWORD i = 0; i < dwLen; i++) + buffer->appendPrintf("%02X", p[i]); + + buffer->append('}'); + + +/* + BITMAPINFOHEADER bih = { 0 }; + HDC hdc = GetDC(NULL); + GetDIBits(hdc, hBitmap, 0, bmp.bmHeight, p, (BITMAPINFO *) & bih, DIB_RGB_COLORS); + + buffer->appendPrintf("{\\pict\\wbitmap0\\wbmbitspixel%u\\wbmplanes%u\\wbmwidthbytes%u\\picw%u\\pich%u ", + bmp.bmBitsPixel, bmp.bmPlanes, bmp.bmWidthBytes, bmp.bmWidth, bmp.bmHeight); + + DWORD i; + for (i = 0; i < sizeof(BITMAPINFOHEADER); i++) + buffer->appendPrintf("%02X", ((PBYTE) & bih)[i]); + + for (i = 0; i < dwLen; i++) + buffer->appendPrintf("%02X", p[i]); + + buffer->append('}'); +*/ + + free(p); +} + + +void * GetHistoryEventText(HANDLE hContact, HANDLE hDbEvent, DBEVENTINFO *dbe, int format) +{ + void *ret; + + if (format & HISTORYEVENTS_FORMAT_CHAR) + { + ret = DbGetEventTextA(dbe, CP_ACP); + } + else if (format & HISTORYEVENTS_FORMAT_WCHAR) + { + ret = DbGetEventTextW(dbe, CP_ACP); + } + else if (format & HISTORYEVENTS_FORMAT_RICH_TEXT) + { + Buffer<char> buffer; + + TCHAR *tmp = DbGetEventTextT(dbe, CP_ACP); + ConvertToRTF(&buffer, tmp); + mir_free(tmp); + + // Load the image + size_t i; + for(i = dbe->cbBlob-2; i > 0 && dbe->pBlob[i] != 0; i--) ; + i++; + + if (dbe->pBlob[i] != 0) + { + TCHAR absFile[MAX_PATH] = _T(""); + CallService(MS_UTILS_PATHTOABSOLUTET,(WPARAM) &dbe->pBlob[i], (LPARAM)absFile); + if(absFile != NULL) + { + HBITMAP hBmp = (HBITMAP) CallService(MS_IMG_LOAD, (WPARAM) absFile, IMGL_TCHAR); + + if (hBmp != NULL) + { + buffer.append("\\line ", 7); + GetRTFFor(&buffer, hBmp); + DeleteObject(hBmp); + } + } + } + + buffer.append(' '); + buffer.pack(); + ret = buffer.detach(); + } + + return ret; +} + diff --git a/plugins/AvatarHistory/src/AvatarHistory.h b/plugins/AvatarHistory/src/AvatarHistory.h new file mode 100644 index 0000000000..e6d7c185d5 --- /dev/null +++ b/plugins/AvatarHistory/src/AvatarHistory.h @@ -0,0 +1,108 @@ +#define _CRT_SECURE_NO_WARNINGS
+#define MIRANDA_VER 0x0A00
+#include <tchar.h>
+#include <windows.h>
+#include <stdio.h>
+#include <time.h>
+#include <strsafe.h>
+#include <commctrl.h> //for ImageList_*
+#include <prsht.h>
+#include <ShObjIdl.h>
+#include <ShlGuid.h>
+
+#include <newpluginapi.h>
+#include <m_clist.h>
+#include <m_skin.h>
+#include <m_avatars.h>
+#include <m_database.h>
+#include <m_system.h>
+#include <m_protosvc.h>
+#include <m_contacts.h>
+#include <m_popup.h>
+#include <m_options.h>
+#include <m_utils.h>
+#include <m_langpack.h>
+#include <m_history.h>
+#include <m_imgsrvc.h>
+#include <m_icolib.h>
+
+#include <m_folders.h>
+#include <m_metacontacts.h>
+#include <m_updater.h>
+#include "m_avatarhist.h"
+#include "m_historyevents.h"
+
+#include "resource.h"
+#include "../utils/mir_buffer.h"
+
+// Globals
+extern HINSTANCE hInst;
+extern HANDLE hMenu;
+extern DWORD mirVer;
+extern HANDLE hAvatarWindowsList;
+
+#define MODULE_NAME "AvatarHistory"
+
+#define AVH_DEF_POPUPFG 0
+#define AVH_DEF_POPUPBG 0x2DB6FF
+#define AVH_DEF_AVPOPUPS 0
+#define AVH_DEF_LOGTODISK 1
+#define AVH_DEF_LOGKEEPSAMEFOLDER 0
+#define AVH_DEF_LOGOLDSTYLE 0
+#define AVH_DEF_LOGTOHISTORY 1
+#define AVH_DEF_DEFPOPUPS 0
+#define AVH_DEF_SHOWMENU 1
+
+#define DEFAULT_TEMPLATE_REMOVED LPGENT("removed his/her avatar")
+#define DEFAULT_TEMPLATE_CHANGED LPGENT("changed his/her avatar")
+
+void LoadOptions();
+
+ // from icolib.cpp
+void SetupIcoLib();
+
+HICON createDefaultOverlayedIcon(BOOL big);
+HICON createProtoOverlayedIcon(HANDLE hContact);
+
+int PreBuildContactMenu(WPARAM wParam,LPARAM lParam);
+int IcoLibIconsChanged(WPARAM wParam,LPARAM lParam);
+
+int OpenAvatarDialog(HANDLE hContact, char* fn);
+
+#define MAX_REGS(_A_) ( sizeof(_A_) / sizeof(_A_[0]) )
+
+#define POPUP_ACTION_DONOTHING 0
+#define POPUP_ACTION_CLOSEPOPUP 1
+#define POPUP_ACTION_OPENAVATARHISTORY 2
+#define POPUP_ACTION_OPENHISTORY 3
+
+#define POPUP_DELAY_DEFAULT 0
+#define POPUP_DELAY_CUSTOM 1
+#define POPUP_DELAY_PERMANENT 2
+
+
+struct Options {
+ // Log
+ BOOL log_per_contact_folders;
+ BOOL log_keep_same_folder;
+ BOOL log_store_as_hash;
+
+ // Popup
+ BOOL popup_show_changed;
+ TCHAR popup_changed[1024];
+ BOOL popup_show_removed;
+ TCHAR popup_removed[1024];
+ WORD popup_delay_type;
+ WORD popup_timeout;
+ BYTE popup_use_win_colors;
+ BYTE popup_use_default_colors;
+ COLORREF popup_bkg_color;
+ COLORREF popup_text_color;
+ WORD popup_left_click_action;
+ WORD popup_right_click_action;
+};
+
+extern Options opts;
+
+
+#include "popup.h"
diff --git a/plugins/AvatarHistory/src/icolib.cpp b/plugins/AvatarHistory/src/icolib.cpp new file mode 100644 index 0000000000..a4105eef3c --- /dev/null +++ b/plugins/AvatarHistory/src/icolib.cpp @@ -0,0 +1,135 @@ +#include "AvatarHistory.h"
+
+enum IconIndex
+{
+ I_HISTORY,
+ I_OVERLAY
+};
+
+typedef struct
+{
+ TCHAR* szDescr;
+ char* szName;
+ int defIconID;
+ BOOL core;
+} IconStruct;
+
+static IconStruct iconList[] =
+{
+ { LPGENT("History"), "core_main_10", IDI_AVATARHIST, TRUE },
+ { LPGENT("Avatar Overlay"), "avh_overlay", IDI_AVATAROVERLAY, FALSE }
+};
+
+extern HANDLE hHooks[];
+
+static HICON LoadIconEx(IconIndex i)
+{
+ HICON hIcon;
+
+ if (hHooks[4])
+ hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)iconList[(int)i].szName);
+ else
+ hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(iconList[(int)i].defIconID),
+ IMAGE_ICON, 0, 0, 0);
+
+ return hIcon;
+}
+
+
+static void ReleaseIconEx(HICON hIcon)
+{
+ if (hHooks[4])
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0);
+ else
+ DestroyIcon(hIcon);
+}
+
+static void IcoLibUpdateMenus()
+{
+ CLISTMENUITEM mi = {0};
+
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_FLAGS | CMIM_ICON;
+ mi.hIcon = createDefaultOverlayedIcon(FALSE);
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hMenu, ( LPARAM )&mi );
+ DestroyIcon(mi.hIcon);
+}
+
+int IcoLibIconsChanged(WPARAM wParam, LPARAM lParam)
+{
+ IcoLibUpdateMenus();
+ return 0;
+}
+
+void SetupIcoLib()
+{
+ if (hHooks[4])
+ {
+ SKINICONDESC sid = {0};
+ TCHAR path[MAX_PATH];
+
+ GetModuleFileName(hInst, path, sizeof(path));
+
+ sid.cbSize = sizeof(sid);
+ sid.ptszSection = LPGENT("Avatar History");
+ sid.ptszDefaultFile = path;
+ sid.flags = SIDF_ALL_TCHAR;
+
+ for (unsigned i = 0; i < MAX_REGS(iconList); i++)
+ {
+ if (!iconList[i].core)
+ {
+ sid.ptszDescription = iconList[i].szDescr;
+ sid.pszName = iconList[i].szName;
+ sid.iDefaultIndex = -iconList[i].defIconID;
+ Skin_AddIcon(&sid);
+ }
+ }
+ }
+ IcoLibUpdateMenus();
+}
+
+static HICON getOverlayedIcon(HICON icon, HICON overlay, BOOL big)
+{
+ HIMAGELIST il = ImageList_Create(
+ GetSystemMetrics(big?SM_CXICON:SM_CXSMICON),
+ GetSystemMetrics(big?SM_CYICON:SM_CYSMICON),
+ ILC_COLOR32|ILC_MASK, 2, 2);
+ ImageList_AddIcon(il, icon);
+ ImageList_AddIcon(il, overlay);
+ HIMAGELIST newImage = ImageList_Merge(il,0,il,1,0,0);
+ ImageList_Destroy(il);
+ HICON hIcon = ImageList_GetIcon(newImage, 0, 0);
+ ImageList_Destroy(newImage);
+ return hIcon; // the result should be destroyed by DestroyIcon()
+}
+
+
+HICON createDefaultOverlayedIcon(BOOL big)
+{
+ HICON icon0 = LoadIconEx(I_HISTORY);
+ HICON icon1 = LoadIconEx(I_OVERLAY);
+
+ HICON resIcon = getOverlayedIcon(icon0, icon1, FALSE);
+
+ ReleaseIconEx(icon0);
+ ReleaseIconEx(icon1);
+
+ return resIcon;
+}
+
+
+HICON createProtoOverlayedIcon(HANDLE hContact)
+{
+ HICON icon1 = LoadIconEx(I_OVERLAY);
+
+ char *szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ HICON icon0 = LoadSkinnedProtoIcon(szProto, ID_STATUS_ONLINE);
+
+ HICON resIcon = getOverlayedIcon(icon0, icon1, FALSE);
+
+ ReleaseIconEx(icon1);
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)icon0, 0);
+
+ return resIcon;
+}
diff --git a/plugins/AvatarHistory/src/options.cpp b/plugins/AvatarHistory/src/options.cpp new file mode 100644 index 0000000000..bd4da44d7f --- /dev/null +++ b/plugins/AvatarHistory/src/options.cpp @@ -0,0 +1,234 @@ +/*
+Avatar History Plugin
+ Copyright (C) 2006 Matthew Wild - Email: mwild1@gmail.com
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include "AvatarHistory.h"
+#include "../utils/mir_options.h"
+
+
+
+// Prototypes /////////////////////////////////////////////////////////////////////////////////////
+
+Options opts;
+
+
+static INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+static INT_PTR CALLBACK PopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+
+static OptPageControl optionsControls[] = {
+ { NULL, CONTROL_PROTOCOL_LIST, IDC_PROTOCOLS, "%sEnabled", TRUE }
+};
+
+
+static OptPageControl popupsControls[] = {
+ { NULL, CONTROL_CHECKBOX, IDC_POPUPS, "AvatarPopups", AVH_DEF_AVPOPUPS },
+ { &opts.popup_bkg_color, CONTROL_COLOR, IDC_BGCOLOR, "PopupsBgColor", AVH_DEF_POPUPBG },
+ { &opts.popup_text_color, CONTROL_COLOR, IDC_TEXTCOLOR, "PopupsTextColor", AVH_DEF_POPUPFG },
+ { &opts.popup_use_win_colors, CONTROL_CHECKBOX, IDC_WINCOLORS, "PopupsWinColors", FALSE },
+ { &opts.popup_use_default_colors, CONTROL_CHECKBOX, IDC_DEFAULTCOLORS, "PopupsDefaultColors", AVH_DEF_DEFPOPUPS },
+ { &opts.popup_delay_type, CONTROL_RADIO, IDC_DELAYFROMPU, "PopupsDelayType", POPUP_DELAY_DEFAULT, POPUP_DELAY_DEFAULT },
+ { NULL, CONTROL_RADIO, IDC_DELAYCUSTOM, "PopupsDelayType", POPUP_DELAY_DEFAULT, POPUP_DELAY_CUSTOM },
+ { NULL, CONTROL_RADIO, IDC_DELAYPERMANENT, "PopupsDelayType", POPUP_DELAY_DEFAULT, POPUP_DELAY_PERMANENT },
+ { &opts.popup_timeout, CONTROL_SPIN, IDC_DELAY, "PopupsTimeout", 10, IDC_DELAY_SPIN, (WORD) 1, (WORD) 255 },
+ { &opts.popup_right_click_action, CONTROL_COMBO, IDC_RIGHT_ACTION, "PopupsRightClick", POPUP_ACTION_CLOSEPOPUP },
+ { &opts.popup_left_click_action, CONTROL_COMBO, IDC_LEFT_ACTION, "PopupsLeftClick", POPUP_ACTION_OPENAVATARHISTORY },
+ { &opts.popup_show_changed, CONTROL_CHECKBOX, IDC_CHANGED_L, "PopupsShowChanged", TRUE },
+ { &opts.popup_changed, CONTROL_TEXT, IDC_CHANGED, "PopupsTextChanged", (ULONG_PTR) DEFAULT_TEMPLATE_CHANGED },
+ { &opts.popup_show_removed, CONTROL_CHECKBOX, IDC_REMOVED_L, "PopupsShowRemoved", TRUE },
+ { &opts.popup_removed, CONTROL_TEXT, IDC_REMOVED, "PopupsTextRemoved", (ULONG_PTR) DEFAULT_TEMPLATE_REMOVED }
+};
+
+static UINT popupsExpertControls[] = {
+ IDC_COLOURS_G, IDC_BGCOLOR, IDC_BGCOLOR_L, IDC_TEXTCOLOR, IDC_TEXTCOLOR_L, IDC_WINCOLORS, IDC_DEFAULTCOLORS,
+ IDC_DELAY_G, IDC_DELAYFROMPU, IDC_DELAYCUSTOM, IDC_DELAYPERMANENT, IDC_DELAY, IDC_DELAY_SPIN,
+ IDC_ACTIONS_G, IDC_RIGHT_ACTION_L, IDC_RIGHT_ACTION, IDC_LEFT_ACTION_L, IDC_LEFT_ACTION,
+ IDC_PREV
+};
+
+
+// Functions //////////////////////////////////////////////////////////////////////////////////////
+
+
+int OptInit(WPARAM wParam,LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp;
+
+ ZeroMemory(&odp,sizeof(odp));
+ odp.cbSize=sizeof(odp);
+ odp.position=0;
+ odp.hInstance=hInst;
+ odp.ptszGroup = LPGENT("History"); // group to put your item under
+ odp.ptszTitle = LPGENT("Avatar"); // name of the item
+ odp.pfnDlgProc = OptionsDlgProc;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS);
+ odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR | ODPF_EXPERTONLY;
+ Options_AddPage(wParam, &odp);
+
+ if(ServiceExists(MS_POPUP_ADDPOPUPT))
+ {
+ ZeroMemory(&odp,sizeof(odp));
+ odp.cbSize=sizeof(odp);
+ odp.position=0;
+ odp.hInstance=hInst;
+ odp.ptszGroup = LPGENT("Popups");
+ odp.ptszTitle = LPGENT("Avatar Change");
+ odp.pfnDlgProc = PopupsDlgProc;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_POPUPS);
+ odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR;
+ odp.expertOnlyControls = popupsExpertControls;
+ odp.nExpertOnlyControls = MAX_REGS(popupsExpertControls);
+ odp.nIDBottomSimpleControl = IDC_POPUPS;
+ odp.nIDRightSimpleControl = IDC_POPUPS;
+ Options_AddPage(wParam, &odp);
+ }
+
+ return 0;
+}
+
+
+void LoadOptions()
+{
+ LoadOpts(optionsControls, MAX_REGS(optionsControls), MODULE_NAME);
+ LoadOpts(popupsControls, MAX_REGS(popupsControls), MODULE_NAME);
+
+ opts.log_per_contact_folders = DBGetContactSettingByte(NULL, MODULE_NAME, "LogPerContactFolders", 0);
+ opts.log_keep_same_folder = DBGetContactSettingByte(NULL, MODULE_NAME, "LogKeepSameFolder", 0);
+ opts.log_store_as_hash = DBGetContactSettingByte(NULL, MODULE_NAME, "StoreAsHash", 1);
+}
+
+
+static INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ return SaveOptsDlgProc(optionsControls, MAX_REGS(optionsControls), MODULE_NAME, hwndDlg, msg, wParam, lParam);
+}
+
+
+static void PopupsEnableDisableCtrls(HWND hwndDlg)
+{
+ BOOL enabled = IsDlgButtonChecked(hwndDlg, IDC_POPUPS);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_COLOURS_G), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BGCOLOR_L), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TEXTCOLOR_L), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_DELAY_G), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_DELAYFROMPU), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_DELAYCUSTOM), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_DELAYPERMANENT), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_ACTIONS_G), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_RIGHT_ACTION_L), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_RIGHT_ACTION), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LEFT_ACTION_L), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_LEFT_ACTION), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_PREV), enabled);
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_BGCOLOR), enabled &&
+ !IsDlgButtonChecked(hwndDlg, IDC_WINCOLORS) &&
+ !IsDlgButtonChecked(hwndDlg, IDC_DEFAULTCOLORS));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TEXTCOLOR), enabled &&
+ !IsDlgButtonChecked(hwndDlg, IDC_WINCOLORS) &&
+ !IsDlgButtonChecked(hwndDlg, IDC_DEFAULTCOLORS));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_DEFAULTCOLORS), enabled &&
+ !IsDlgButtonChecked(hwndDlg, IDC_WINCOLORS));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_WINCOLORS), enabled &&
+ !IsDlgButtonChecked(hwndDlg, IDC_DEFAULTCOLORS));
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_DELAY), enabled &&
+ IsDlgButtonChecked(hwndDlg, IDC_DELAYCUSTOM));
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHANGED_L), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVED_L), enabled);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHANGED), enabled &&
+ IsDlgButtonChecked(hwndDlg, IDC_CHANGED_L));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVED), enabled &&
+ IsDlgButtonChecked(hwndDlg, IDC_REMOVED_L));
+
+}
+
+
+static INT_PTR CALLBACK PopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ SendDlgItemMessage(hwndDlg, IDC_RIGHT_ACTION, CB_ADDSTRING, 0, (LPARAM) TranslateT("Do nothing"));
+ SendDlgItemMessage(hwndDlg, IDC_RIGHT_ACTION, CB_ADDSTRING, 0, (LPARAM) TranslateT("Close popup"));
+ SendDlgItemMessage(hwndDlg, IDC_RIGHT_ACTION, CB_ADDSTRING, 0, (LPARAM) TranslateT("Show avatar history"));
+ SendDlgItemMessage(hwndDlg, IDC_RIGHT_ACTION, CB_ADDSTRING, 0, (LPARAM) TranslateT("Show contact history"));
+
+ SendDlgItemMessage(hwndDlg, IDC_LEFT_ACTION, CB_ADDSTRING, 0, (LPARAM) TranslateT("Do nothing"));
+ SendDlgItemMessage(hwndDlg, IDC_LEFT_ACTION, CB_ADDSTRING, 0, (LPARAM) TranslateT("Close popup"));
+ SendDlgItemMessage(hwndDlg, IDC_LEFT_ACTION, CB_ADDSTRING, 0, (LPARAM) TranslateT("Show avatar history"));
+ SendDlgItemMessage(hwndDlg, IDC_LEFT_ACTION, CB_ADDSTRING, 0, (LPARAM) TranslateT("Show contact history"));
+
+ // Needs to be called here in this case
+ BOOL ret = SaveOptsDlgProc(popupsControls, MAX_REGS(popupsControls), MODULE_NAME, hwndDlg, msg, wParam, lParam);
+
+ PopupsEnableDisableCtrls(hwndDlg);
+
+ return ret;
+ }
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_POPUPS:
+ case IDC_WINCOLORS:
+ case IDC_DEFAULTCOLORS:
+ case IDC_DELAYFROMPU:
+ case IDC_DELAYPERMANENT:
+ case IDC_DELAYCUSTOM:
+ case IDC_CHANGED_L:
+ case IDC_REMOVED_L:
+ {
+ if (HIWORD(wParam) == BN_CLICKED)
+ PopupsEnableDisableCtrls(hwndDlg);
+
+ break;
+ }
+ case IDC_PREV:
+ {
+ Options op = opts;
+
+ if (IsDlgButtonChecked(hwndDlg, IDC_DELAYFROMPU))
+ op.popup_delay_type = POPUP_DELAY_DEFAULT;
+ else if (IsDlgButtonChecked(hwndDlg, IDC_DELAYCUSTOM))
+ op.popup_delay_type = POPUP_DELAY_CUSTOM;
+ else if (IsDlgButtonChecked(hwndDlg, IDC_DELAYPERMANENT))
+ op.popup_delay_type = POPUP_DELAY_PERMANENT;
+
+ op.popup_timeout = GetDlgItemInt(hwndDlg,IDC_DELAY, NULL, FALSE);
+ op.popup_bkg_color = SendDlgItemMessage(hwndDlg,IDC_BGCOLOR,CPM_GETCOLOUR,0,0);
+ op.popup_text_color = SendDlgItemMessage(hwndDlg,IDC_TEXTCOLOR,CPM_GETCOLOUR,0,0);
+ op.popup_use_win_colors = IsDlgButtonChecked(hwndDlg, IDC_WINCOLORS) != 0;
+ op.popup_use_default_colors = IsDlgButtonChecked(hwndDlg, IDC_DEFAULTCOLORS) != 0;
+
+ HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+ ShowTestPopup(hContact,TranslateT("Test Contact"), TranslateT("Test description"), &op);
+
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ return SaveOptsDlgProc(popupsControls, MAX_REGS(popupsControls), MODULE_NAME, hwndDlg, msg, wParam, lParam);
+}
diff --git a/plugins/AvatarHistory/src/popup.cpp b/plugins/AvatarHistory/src/popup.cpp new file mode 100644 index 0000000000..dc03ee783d --- /dev/null +++ b/plugins/AvatarHistory/src/popup.cpp @@ -0,0 +1,279 @@ +/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "AvatarHistory.h"
+
+
+
+// Prototypes /////////////////////////////////////////////////////////////////////////////////////
+
+#define WMU_ACTION (WM_USER + 1)
+
+
+LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+HWND hPopupWindow = NULL;
+
+
+static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+static LRESULT CALLBACK DumbPopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+
+
+// Functions //////////////////////////////////////////////////////////////////////////////////////
+
+
+// Initializations needed by popups
+void InitPopups()
+{
+ // window needed for popup commands
+ hPopupWindow = CreateWindowEx(WS_EX_TOOLWINDOW, _T("static"), _T(MODULE_NAME) _T("_PopupWindow"),
+ 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP,
+ NULL, hInst, NULL);
+ SetWindowLong(hPopupWindow, GWLP_WNDPROC, (LONG_PTR)PopupWndProc);
+}
+
+
+// Deinitializations needed by popups
+void DeInitPopups()
+{
+}
+
+
+// Show an error popup
+void ShowErrPopup(const TCHAR *description, const TCHAR *title)
+{
+ ShowPopupEx(NULL, title == NULL ? _T(MODULE_NAME) _T(" Error") : title, description,
+ NULL, POPUP_TYPE_ERROR, NULL);
+}
+
+
+void ShowTestPopup(HANDLE hContact,const TCHAR *title, const TCHAR *description, const Options *op)
+{
+ ShowPopupEx(hContact, title, description, NULL, POPUP_TYPE_TEST, op);
+}
+
+
+void ShowPopup(HANDLE hContact, const TCHAR *title, const TCHAR *description)
+{
+ ShowPopupEx(hContact, title, description, hContact, POPUP_TYPE_NORMAL, &opts);
+}
+
+void ShowDebugPopup(HANDLE hContact, const TCHAR *title, const TCHAR *description)
+{
+ if(DBGetContactSettingByte(NULL,MODULE_NAME,"Debug",0))
+ {
+ ShowPopup(hContact,title,description);
+ }
+}
+
+typedef struct
+{
+ void* plugin_data;
+ HICON hIcon;
+}
+PopupDataType;
+
+// Show an popup
+void ShowPopupEx(HANDLE hContact, const TCHAR *title, const TCHAR *description,
+ void *plugin_data, int type, const Options *op)
+{
+ if(ServiceExists(MS_POPUP_ADDPOPUPT))
+ {
+ // Make popup
+ POPUPDATAT ppd = {0};
+
+ ppd.lchContact = hContact;
+ ppd.lchIcon = createProtoOverlayedIcon(hContact);
+
+ ppd.PluginData = mir_alloc(sizeof(PopupDataType));
+ ((PopupDataType*)ppd.PluginData)->plugin_data = plugin_data;
+ ((PopupDataType*)ppd.PluginData)->hIcon = ppd.lchIcon;
+
+ if (title != NULL)
+ lstrcpyn(ppd.lptzContactName, title, MAX_REGS(ppd.lptzContactName));
+ else if (hContact != NULL)
+ lstrcpyn(ppd.lptzContactName, (TCHAR *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR | GCDNF_NOCACHE),
+ MAX_REGS(ppd.lptzContactName));
+
+ if (description != NULL)
+ lstrcpyn(ppd.lptzText, description, MAX_REGS(ppd.lptzText));
+
+ if (type == POPUP_TYPE_NORMAL || type == POPUP_TYPE_TEST)
+ {
+ if (op->popup_use_default_colors)
+ {
+ ppd.colorBack = 0;
+ ppd.colorText = 0;
+ }
+ else if (op->popup_use_win_colors)
+ {
+ ppd.colorBack = GetSysColor(COLOR_BTNFACE);
+ ppd.colorText = GetSysColor(COLOR_WINDOWTEXT);
+ }
+ else
+ {
+ ppd.colorBack = op->popup_bkg_color;
+ ppd.colorText = op->popup_text_color;
+ }
+ }
+ else // if (type == POPUP_TYPE_ERROR)
+ {
+ ppd.colorBack = RGB(200,0,0);
+ ppd.colorText = RGB(255,255,255);
+ }
+
+ if (type == POPUP_TYPE_NORMAL)
+ {
+ ppd.PluginWindowProc = PopupDlgProc;
+ }
+ else // if (type == POPUP_TYPE_TEST || type == POPUP_TYPE_ERROR)
+ {
+ ppd.PluginWindowProc = DumbPopupDlgProc;
+ }
+
+ if (type == POPUP_TYPE_NORMAL || type == POPUP_TYPE_TEST)
+ {
+ switch (op->popup_delay_type)
+ {
+ case POPUP_DELAY_CUSTOM:
+ ppd.iSeconds = opts.popup_timeout;
+ break;
+
+ case POPUP_DELAY_PERMANENT:
+ ppd.iSeconds = -1;
+ break;
+
+ case POPUP_DELAY_DEFAULT:
+ default:
+ ppd.iSeconds = 0;
+ break;
+ }
+ }
+ else // if (type == POPUP_TYPE_ERROR)
+ {
+ ppd.iSeconds = 0;
+ }
+
+ // Now that every field has been filled, we want to see the popup.
+ PUAddPopUpT(&ppd);
+ }
+ else
+ {
+ MessageBox(NULL, description, title ? title : (TCHAR *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR),
+ MB_OK);
+ }
+
+}
+
+
+// Handle to the hidden windows to handle actions for popup clicks
+// wParam has the number of MOTD in case of WMU_SHOW_MOTD_DETAILS
+LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (uMsg == WMU_ACTION)
+ {
+ if (lParam == POPUP_ACTION_OPENAVATARHISTORY)
+ {
+ CallService("AvatarHistory/ShowDialog", wParam, 0);
+ }
+ else if (lParam == POPUP_ACTION_OPENHISTORY)
+ {
+ CallService(MS_HISTORY_SHOWCONTACTHISTORY, wParam, 0);
+ }
+ }
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+
+// Handle to popup events
+static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message) {
+ case WM_COMMAND:
+ {
+ PopupDataType* popup = (PopupDataType*)PUGetPluginData(hWnd);
+ PostMessage(hPopupWindow, WMU_ACTION, (WPARAM)popup->plugin_data, opts.popup_left_click_action);
+
+ if (opts.popup_left_click_action != POPUP_ACTION_DONOTHING)
+ PUDeletePopUp(hWnd);
+
+ return TRUE;
+ }
+
+ case WM_CONTEXTMENU:
+ {
+ PopupDataType* popup = (PopupDataType*)PUGetPluginData(hWnd);
+ PostMessage(hPopupWindow, WMU_ACTION, (WPARAM)popup->plugin_data, opts.popup_right_click_action);
+
+ if (opts.popup_right_click_action != POPUP_ACTION_DONOTHING)
+ PUDeletePopUp(hWnd);
+
+ return TRUE;
+ }
+
+ case UM_FREEPLUGINDATA:
+ {
+ PopupDataType* popup = (PopupDataType*)PUGetPluginData(hWnd);
+ if ((INT_PTR)popup != CALLSERVICE_NOTFOUND)
+ {
+ DestroyIcon(popup->hIcon);
+ mir_free(popup);
+ }
+ return FALSE; //the return value is ignored
+ }
+ }
+
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+
+// Handle to popup events
+static LRESULT CALLBACK DumbPopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message) {
+ case WM_COMMAND:
+ {
+ PUDeletePopUp(hWnd);
+ return TRUE;
+ }
+
+ case WM_CONTEXTMENU:
+ {
+ PUDeletePopUp(hWnd);
+ return TRUE;
+ }
+
+ case UM_FREEPLUGINDATA:
+ {
+ PopupDataType* popup = (PopupDataType*)PUGetPluginData(hWnd);
+ if ((INT_PTR)popup != CALLSERVICE_NOTFOUND)
+ {
+ DestroyIcon(popup->hIcon);
+ mir_free(popup);
+ }
+ return FALSE; //the return value is ignored
+ }
+ }
+
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+
diff --git a/plugins/AvatarHistory/src/popup.h b/plugins/AvatarHistory/src/popup.h new file mode 100644 index 0000000000..2944ba0895 --- /dev/null +++ b/plugins/AvatarHistory/src/popup.h @@ -0,0 +1,53 @@ +/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __POPUP_H__
+# define __POPUP_H__
+
+#include <windows.h>
+
+
+// Initializations needed by popups
+void InitPopups();
+
+// Deinitializations needed by popups
+void DeInitPopups();
+
+
+#define POPUP_TYPE_NORMAL 0
+#define POPUP_TYPE_TEST 1
+#define POPUP_TYPE_ERROR 2
+
+// Show an popup
+void ShowPopup(HANDLE hContact, const TCHAR *title, const TCHAR *description);
+void ShowDebugPopup(HANDLE hContact, const TCHAR *title, const TCHAR *description);
+
+// Show an test
+void ShowTestPopup(HANDLE hContact,const TCHAR *title, const TCHAR *description, const Options *op);
+
+// Show an error popup
+void ShowErrPopup(const char *description, const char *title = NULL);
+
+void ShowPopupEx(HANDLE hContact, const TCHAR *title, const TCHAR *description,
+ void *plugin_data, int type, const Options *op);
+
+
+
+#endif // __POPUP_H__
diff --git a/plugins/AvatarHistory/src/resource.h b/plugins/AvatarHistory/src/resource.h new file mode 100644 index 0000000000..9ec6008167 --- /dev/null +++ b/plugins/AvatarHistory/src/resource.h @@ -0,0 +1,88 @@ +//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by AvatarHistory.rc
+//
+#define IDD_OPTIONS_OLD 101
+#define IDC_POPUPBG 102
+#define IDD_AVATARDLG 102
+#define IDC_POPUPFG 103
+#define IDI_AVATARHIST 104
+#define IDI_NEWAVATAR 105
+#define IDI_AVATAROVERLAY 106
+#define IDR_MENU1 108
+#define IDD_FIRST_RUN 109
+#define IDD_OPTIONS 119
+#define IDD_POPUPS 120
+#define IDC_CUSTOM1 1000
+#define IDC_AVATARPOPUPS 1001
+#define IDC_DELAY 1001
+#define IDC_LOGTODISK 1002
+#define IDC_WINCOLORS 1002
+#define IDC_LOGTOHISTORY 1003
+#define IDC_DEFAULTCOLORS 1003
+#define IDC_BGCOLOR 1004
+#define IDC_DEFPOPUPS 1005
+#define IDC_TEXTCOLOR 1005
+#define IDC_PREV 1006
+#define IDC_AVATAR 1007
+#define IDC_DELAYFROMPU 1007
+#define IDC_AVATARLIST 1008
+#define IDC_DELAYCUSTOM 1008
+#define IDC_SAVE 1009
+#define IDC_DELAYPERMANENT 1009
+#define IDC_DELETE 1010
+#define IDC_NEXT 1011
+#define IDC_BACK 1012
+#define IDC_LOGUSER 1013
+#define IDC_POPUPUSER 1014
+#define IDC_OPENFOLDER 1015
+#define IDC_PUFGTEXT 1016
+#define IDC_HISTORYUSER 1016
+#define IDC_PUBGTEXT 1017
+#define IDC_SHOWMENU 1019
+#define IDC_LOGGING_G 1020
+#define IDC_SAME_FOLDER 1021
+#define IDC_RIGHT_ACTION 1022
+#define IDC_MIR_SAME 1022
+#define IDC_LEFT_ACTION 1023
+#define IDC_MIR_PROTO 1023
+#define IDC_AVATARPATH 1023
+#define IDC_MIR_SHORT 1024
+#define IDC_SHORT 1025
+#define IDC_DUP 1026
+#define IDC_PROTOCOLS 1041
+#define IDC_CHANGED 1058
+#define IDC_REMOVED 1059
+#define IDC_POPUPS 1060
+#define IDC_DELAY_SPIN 1061
+#define IDC_LOG_DISK 1061
+#define IDC_LOG_HISTORY 1062
+#define IDC_TRACK_G 1063
+#define IDC_CHANGED_L 1064
+#define IDC_REMOVED_L 1065
+#define IDC_PROTOCOLS_G 1066
+#define IDC_PROTOCOLS_L 1067
+#define IDC_TRACK_CHANGE 1068
+#define IDC_COLOURS_G 1068
+#define IDC_OLD_STYLE 1068
+#define IDC_TRACK_REMOVE 1069
+#define IDC_BGCOLOR_L 1069
+#define IDC_TEXTCOLOR_L 1070
+#define IDC_DELAY_G 1071
+#define IDC_ACTIONS_G 1072
+#define IDC_RIGHT_ACTION_L 1073
+#define IDC_LEFT_ACTION_L 1074
+#define ID_AVATARLISTPOPUP_SAVEAS 40001
+#define ID_AVATARLISTPOPUP_DELETE 40002
+#define ID_AVATARLISTPOPUP_DELETE_BOTH 40003
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 110
+#define _APS_NEXT_COMMAND_VALUE 40004
+#define _APS_NEXT_CONTROL_VALUE 1025
+#define _APS_NEXT_SYMED_VALUE 103
+#endif
+#endif
|