/* Copyright (C) 2009 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 "commons.h" /* 0, // EXTRA_ICON_VISMODE 1, // EXTRA_ICON_EMAIL 2, // EXTRA_ICON_PROTO 3, // EXTRA_ICON_SMS 4, // EXTRA_ICON_ADV1 5, // EXTRA_ICON_ADV2 6, // EXTRA_ICON_WEB 7, // EXTRA_ICON_CLIENT 8, // EXTRA_ICON_ADV3 9, // EXTRA_ICON_ADV4 */ static void ProtocolInit(); static void DBExtraIconsInit(); void DefaultExtraIcons_Load() { DBExtraIconsInit(); ProtocolInit(); } void DefaultExtraIcons_Unload() { } // DB extra icons /////////////////////////////////////////////////////////////////////// struct Info; HANDLE hExtraVisibility = NULL; HANDLE hExtraChat = NULL; HANDLE hExtraGender = NULL; static void SetVisibility(HANDLE hContact, int apparentMode, BOOL clear) { if (hContact == NULL) return; char *proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); if (IsEmpty(proto)) return; if (apparentMode <= 0) apparentMode = DBGetContactSettingWord(hContact, proto, "ApparentMode", 0); const char *ico = NULL; if (DBGetContactSettingByte(hContact, proto, "ChatRoom", 0)) { // Is chat if (apparentMode == ID_STATUS_OFFLINE) ico = "ChatActivity"; if (ico == NULL && !clear) return; ExtraIcon_SetIcon(hExtraChat, hContact, ico); } else { // Not chat if (apparentMode == ID_STATUS_OFFLINE) ico = "NeverVis"; else if (apparentMode == ID_STATUS_ONLINE) ico = "AlwaysVis"; if (ico == NULL && !clear) return; ExtraIcon_SetIcon(hExtraVisibility, hContact, ico); } } static void SetGender(HANDLE hContact, int gender, BOOL clear) { if (hContact == NULL) return; char *proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); if (IsEmpty(proto)) return; if (gender <= 0) gender = DBGetContactSettingByte(hContact, proto, "Gender", 0); if (gender <= 0) gender = DBGetContactSettingByte(hContact, "UserInfo", "Gender", 0); const char *ico = NULL; if (gender == 'M') ico = "gender_male"; else if (gender == 'F') ico = "gender_female"; else ico = NULL; if (ico == NULL && !clear) return; ExtraIcon_SetIcon(hExtraGender, hContact, ico); } static void EmailOnClick(Info *info, const char *text); static void HomepageOnClick(Info *info, const char *text); static void DefaultSetIcon(HANDLE hContact, Info *info, const char *text); struct Info { const char *name; const char *desc; const char *icon; const char *db[8]; void (*SetIcon)(HANDLE hContact, Info *info, const char *text); void (*OnClick)(Info *info, const char *text); HANDLE hExtraIcon; } infos[] = { { "homepage", "Homepage", "core_main_2", { NULL, "Homepage", "UserInfo", "Homepage" }, DefaultSetIcon, &HomepageOnClick, NULL }, { "sms", "Phone/SMS", "core_main_17", { NULL, "Cellular", "UserInfo", "Cellular", "UserInfo", "Phone", "UserInfo", "MyPhone0" }, DefaultSetIcon, NULL, NULL }, { "email", "E-mail", "core_main_14", { NULL, "e-mail", "UserInfo", "e-mail", "UserInfo", "Mye-mail0" }, DefaultSetIcon, &EmailOnClick, NULL }, }; static void EmailOnClick(Info *info, const char *text) { char cmd[1024]; mir_snprintf(cmd, MAX_REGS(cmd), "mailto:%s", text); ShellExecute(NULL, "open", cmd, NULL, NULL, SW_SHOW); } static void HomepageOnClick(Info *info, const char *text) { ShellExecute(NULL, "open", text, NULL, NULL, SW_SHOW); } static void DefaultSetIcon(HANDLE hContact, Info *info, const char *text) { ExtraIcon_SetIcon(info->hExtraIcon, hContact, text ? info->icon : NULL); } static void SetExtraIcons(HANDLE hContact) { if (hContact == NULL) return; char *proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); if (IsEmpty(proto)) return; for (unsigned int i = 0; i < MAX_REGS(infos); ++i) { Info &info = infos[i]; bool show = false; for (unsigned int j = 0; !show && j < MAX_REGS(info.db); j += 2) { if (info.db[j + 1] == NULL) break; DBVARIANT dbv = { 0 }; if (!DBGetContactSettingString(hContact, info.db[j] == NULL ? proto : info.db[j], info.db[j+1], &dbv)) { if (!IsEmpty(dbv.pszVal)) { info.SetIcon(hContact, &info, dbv.pszVal); show = true; } DBFreeVariant(&dbv); } } } } static int SettingChanged(WPARAM wParam, LPARAM lParam) { HANDLE hContact = (HANDLE) wParam; DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*) lParam; if (hContact == NULL) return 0; char *proto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); if (IsEmpty(proto)) return 0; bool isProto = (strcmp(cws->szModule, proto) == 0); if (isProto && strcmp(cws->szSetting, "ApparentMode") == 0) { SetVisibility(hContact, cws->value.type == DBVT_DELETED ? 0 : cws->value.wVal, TRUE); return 0; } if (strcmp(cws->szSetting, "Gender") == 0 && (isProto || strcmp(cws->szModule, "UserInfo") == 0)) { SetGender(hContact, cws->value.type == DBVT_DELETED ? 0 : cws->value.bVal, TRUE); return 0; } for (unsigned int i = 0; i < MAX_REGS(infos); ++i) { Info &info = infos[i]; for (unsigned int j = 0; j < MAX_REGS(info.db); j += 2) { if (info.db[j + 1] == NULL) break; if (info.db[j] == NULL && !isProto) continue; if (info.db[j] != NULL && strcmp(cws->szModule, info.db[j])) continue; if (strcmp(cws->szSetting, info.db[j + 1])) continue; bool show = (cws->value.type != DBVT_DELETED && !IsEmpty(cws->value.pszVal)); info.SetIcon(hContact, &info, show ? cws->value.pszVal : NULL); break; } } return 0; } static int DefaultOnClick(WPARAM wParam, LPARAM lParam, LPARAM param) { Info *info = (Info *) param; if (info == NULL) return 0; HANDLE hContact = (HANDLE) wParam; if (hContact == NULL) return 0; char *proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); if (IsEmpty(proto)) return 0; bool found = false; for (unsigned int j = 0; !found && j < MAX_REGS(info->db); j += 2) { if (info->db[j + 1] == NULL) break; DBVARIANT dbv = { 0 }; if (!DBGetContactSettingString(hContact, info->db[j] == NULL ? proto : info->db[j], info->db[j+1], &dbv)) { if (!IsEmpty(dbv.ptszVal)) { info->OnClick(info, dbv.ptszVal); found = true; } DBFreeVariant(&dbv); } } return 0; } static void DBExtraIconsInit() { hExtraChat = ExtraIcon_Register("chat_activity", "Chat activity", "ChatActivity"); hExtraVisibility = ExtraIcon_Register("visibility", "Visibility", "AlwaysVis"); hExtraGender = ExtraIcon_Register("gender", "Gender", "gender_male"); for (unsigned int i = 0; i < MAX_REGS(infos); ++i) { Info &info = infos[i]; if (info.OnClick) info.hExtraIcon = ExtraIcon_Register(info.name, info.desc, info.icon, DefaultOnClick, (LPARAM) &info); else info.hExtraIcon = ExtraIcon_Register(info.name, info.desc, info.icon); } HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); while (hContact != NULL) { SetExtraIcons(hContact); SetVisibility(hContact, -1, FALSE); SetGender(hContact, -1, FALSE); hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); } HookEvent(ME_DB_CONTACT_SETTINGCHANGED, SettingChanged); } // Protocol ///////////////////////////////////////////////////////////////////////////// struct ProtoInfo { string proto; HANDLE hImage; }; vector protos; HANDLE hExtraProto = NULL; static int ProtocolRebuildIcons(WPARAM wParam, LPARAM lParam) { protos.clear(); return 0; } static ProtoInfo *FindProto(const char * proto) { for (unsigned int i = 0; i < protos.size(); ++i) { ProtoInfo *pi = &protos[i]; if (strcmp(pi->proto.c_str(), proto) == 0) return pi; } HICON hIcon = LoadSkinnedProtoIcon(proto, ID_STATUS_ONLINE); if (hIcon == NULL) return NULL; HANDLE hImage = (HANDLE) CallService(MS_CLIST_EXTRA_ADD_ICON, (WPARAM) hIcon, 0); if (hImage == INVALID_HANDLE_VALUE) return NULL; ProtoInfo tmp; tmp.proto = proto; tmp.hImage = hImage; protos.push_back(tmp); return &protos[protos.size() - 1]; } static int ProtocolApplyIcon(WPARAM wParam, LPARAM lParam) { HANDLE hContact = (HANDLE) wParam; char *proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); if (IsEmpty(proto)) return 0; ProtoInfo *pi = FindProto(proto); HANDLE hImage = INVALID_HANDLE_VALUE; if (pi != NULL) hImage = pi->hImage; ExtraIcon_SetIcon(hExtraProto, hContact, hImage); return 0; } static int ProtocolOnClick(WPARAM wParam, LPARAM lParam, LPARAM param) { HANDLE hContact = (HANDLE) wParam; if (hContact == NULL) return 0; CallService(MS_USERINFO_SHOWDIALOG, (WPARAM) hContact, 0); return 0; } static void ProtocolInit() { hExtraProto = ExtraIcon_Register("protocol", "Account", "core_main_34", &ProtocolRebuildIcons, &ProtocolApplyIcon, &ProtocolOnClick); }