void RebuildListsBasedOnGroups(vector<ExtraIconGroup *> &groups) { unsigned int i; for (i = 0; i < extraIconsByHandle.size(); ++i) extraIconsByHandle[i] = registeredExtraIcons[i]; for (i = 0; i < extraIconsBySlot.size(); ++i) { ExtraIcon *extra = extraIconsBySlot[i]; if (extra->getType() != EXTRAICON_TYPE_GROUP) continue; delete extra; } extraIconsBySlot.clear(); for (i = 0; i < groups.size(); ++i) { ExtraIconGroup *group = groups[i]; for (unsigned int j = 0; j < group->items.size(); ++j) extraIconsByHandle[group->items[j]->getID() - 1] = group; extraIconsBySlot.push_back(group); } for (i = 0; i < extraIconsByHandle.size(); ++i) { ExtraIcon *extra = extraIconsByHandle[i]; if (extra->getType() != EXTRAICON_TYPE_GROUP) extraIconsBySlot.push_back(extra); } std::sort(extraIconsBySlot.begin(), extraIconsBySlot.end(), compareFunc()); }
static void SetVisibility(MCONTACT hContact, int apparentMode, bool clear) { if (hContact == NULL) return; char *proto = GetContactProto(hContact); if (IsEmpty(proto)) return; if (apparentMode <= 0) apparentMode = db_get_w(hContact, proto, "ApparentMode", 0); HANDLE hExtraIcon, hIcolib = NULL; if (db_get_b(hContact, proto, "ChatRoom", 0)) { // Is chat hExtraIcon = hExtraChat; if (apparentMode == ID_STATUS_OFFLINE) hIcolib = Skin_GetIconHandle("ChatActivity"); } else { // Not chat hExtraIcon = hExtraVisibility; if (apparentMode == ID_STATUS_OFFLINE) hIcolib = LoadSkinnedIconHandle(SKINICON_OTHER_INVISIBLE_ALL); else if (apparentMode == ID_STATUS_ONLINE) hIcolib = LoadSkinnedIconHandle(SKINICON_OTHER_VISIBLE_ALL); } if (hIcolib != NULL || clear) { ExtraIcon *extra = GetExtraIcon(hExtraIcon); if (extra) extra->setIcon((int)hExtraIcon, hContact, hIcolib); } }
static void SetGender(MCONTACT hContact, int gender, bool clear) { if (hContact == NULL) return; char *proto = GetContactProto(hContact); if (IsEmpty(proto)) return; if (gender <= 0) gender = db_get_b(hContact, proto, "Gender", 0); if (gender <= 0) gender = db_get_b(hContact, "UserInfo", "Gender", 0); const char *ico; if (gender == 'M') ico = "gender_male"; else if (gender == 'F') ico = "gender_female"; else ico = NULL; if (ico != NULL || clear) { ExtraIcon *extra = GetExtraIcon(hExtraGender); if (extra) extra->setIconByName((int)hExtraGender, hContact, ico); } }
void RebuildListsBasedOnGroups(LIST<ExtraIconGroup> &groups) { extraIconsByHandle.destroy(); for (int i=0; i < registeredExtraIcons.getCount(); i++) extraIconsByHandle.insert(registeredExtraIcons[i]); for (int k=0; k < extraIconsBySlot.getCount(); k++) { ExtraIcon *extra = extraIconsBySlot[k]; if (extra->getType() == EXTRAICON_TYPE_GROUP) delete extra; } extraIconsBySlot.destroy(); for (int i=0; i < groups.getCount(); i++) { ExtraIconGroup *group = groups[i]; for (int j = 0; j < group->m_items.getCount(); j++) extraIconsByHandle.put(group->m_items[j]->getID()-1, group); extraIconsBySlot.insert(group); } for (int k=0; k < extraIconsByHandle.getCount(); k++) { ExtraIcon *extra = extraIconsByHandle[k]; if (extra->getType() != EXTRAICON_TYPE_GROUP) extraIconsBySlot.insert(extra); } }
int BaseExtraIcon::ClistSetExtraIcon(HANDLE hContact, HANDLE hImage) { ExtraIcon *tmp = extraIconsByHandle[id - 1]; if (tmp != this) return tmp->ClistSetExtraIcon(hContact, hImage); return Clist_SetExtraIcon(hContact, slot, hImage); }
ExtraIcon* GetExtraIconBySlot(int slot) { for (int i = 0; i < extraIconsBySlot.getCount(); i++) { ExtraIcon *extra = extraIconsBySlot[i]; if (extra->getSlot() == slot) return extra; } return NULL; }
ExtraIcon * GetExtraIconBySlot(int slot) { for (unsigned int i = 0; i < extraIconsBySlot.size(); ++i) { ExtraIcon *extra = extraIconsBySlot[i]; if (extra->getSlot() == slot) return extra; } return NULL; }
MIR_APP_DLL(int) ExtraIcon_Clear(HANDLE hExtraIcon, MCONTACT hContact) { if (hExtraIcon == NULL || hContact == NULL) return -1; ExtraIcon *extra = GetExtraIcon(hExtraIcon); if (extra == NULL) return -1; return extra->setIcon((INT_PTR)hExtraIcon, hContact, NULL); }
MIR_APP_DLL(int) ExtraIcon_SetIconByName(HANDLE hExtraIcon, MCONTACT hContact, const char *icoName) { if (hExtraIcon == NULL || hContact == NULL) return -1; ExtraIcon *extra = GetExtraIcon(hExtraIcon); if (extra == NULL) return -1; return extra->setIconByName((INT_PTR)hExtraIcon, hContact, icoName); }
void UnloadExtraIconsModule(void) { for (int k = 0; k < extraIconsBySlot.getCount(); k++) { ExtraIcon *extra = extraIconsBySlot[k]; if (extra->getType() == EXTRAICON_TYPE_GROUP) delete extra; } for (int i = 0; i < registeredExtraIcons.getCount(); i++) delete registeredExtraIcons[i]; }
INT_PTR ExtraIcon_SetIconByName(WPARAM wParam, LPARAM lParam) { if (wParam == 0) return -1; EXTRAICON *ei = (EXTRAICON*)wParam; if (ei->cbSize < (int)sizeof(EXTRAICON) || ei->hExtraIcon == NULL || ei->hContact == NULL) return -1; ExtraIcon *extra = GetExtraIcon(ei->hExtraIcon); if (extra == NULL) return -1; return extra->setIconByName((int)ei->hExtraIcon, ei->hContact, ei->icoName); }
static void EI_PostCreate(BaseExtraIcon *extra, const char *name, int _hLang) { char setting[512]; mir_snprintf(setting, "Position_%s", name); extra->setPosition(db_get_w(NULL, MODULE_NAME, setting, 1000)); mir_snprintf(setting, "Slot_%s", name); int slot = db_get_w(NULL, MODULE_NAME, setting, 1); if (slot == (WORD)-1) slot = -1; extra->setSlot(slot); extra->m_hLangpack = _hLang; registeredExtraIcons.insert(extra); extraIconsByHandle.insert(extra); LIST<ExtraIconGroup> groups(1); LoadGroups(groups); ExtraIconGroup *group = IsInGroup(groups, extra); if (group != NULL) RebuildListsBasedOnGroups(groups); else { for (int i = 0; i < groups.getCount(); i++) delete groups[i]; extraIconsBySlot.insert(extra); } if (slot >= 0 || group != NULL) { if (clistRebuildAlreadyCalled) extra->rebuildIcons(); slot = 0; for (int i = 0; i < extraIconsBySlot.getCount(); i++) { ExtraIcon *ex = extraIconsBySlot[i]; if (ex->getSlot() < 0) continue; int oldSlot = ex->getSlot(); ex->setSlot(slot++); if (clistApplyAlreadyCalled && (ex == group || ex == extra || oldSlot != slot)) extra->applyIcons(); } } }
int ClistExtraClick(WPARAM hContact, LPARAM lParam) { if (hContact == NULL) return 0; int clistSlot = (int)lParam; for (int i=0; i < extraIconsBySlot.getCount(); i++) { ExtraIcon *extra = extraIconsBySlot[i]; if (ConvertToClistSlot(extra->getSlot()) == clistSlot) { extra->onClick(hContact); break; } } return 0; }
int ClistExtraClick(WPARAM wParam, LPARAM lParam) { HANDLE hContact = (HANDLE) wParam; if (hContact == NULL) return 0; int clistSlot = (int) lParam; for (unsigned int i = 0; i < extraIconsBySlot.size(); ++i) { ExtraIcon *extra = extraIconsBySlot[i]; if (ConvertToClistSlot(extra->getSlot()) == clistSlot) { extra->onClick(hContact); break; } } return 0; }
virtual void OnInitDialog() { int numSlots = GetNumberOfSlots(); if (numSlots < (int)registeredExtraIcons.getCount()) { HWND label = GetDlgItem(m_hwnd, IDC_MAX_ICONS_L); SetWindowText(label, CMString(FORMAT, TranslateT("*only the first %d icons will be shown"), numSlots)); ShowWindow(label, SW_SHOW); } int cx = g_iIconSX; HIMAGELIST hImageList = ImageList_Create(cx, cx, ILC_COLOR32 | ILC_MASK, 2, 2); HICON hBlankIcon = (HICON)LoadImage(g_hInst, MAKEINTRESOURCE(IDI_BLANK), IMAGE_ICON, cx, cx, 0); ImageList_AddIcon(hImageList, hBlankIcon); for (int i = 0; i < registeredExtraIcons.getCount(); i++) { ExtraIcon *extra = registeredExtraIcons[i]; HICON hIcon = IcoLib_GetIcon(extra->getDescIcon()); if (hIcon == NULL) ImageList_AddIcon(hImageList, hBlankIcon); else { ImageList_AddIcon(hImageList, hIcon); IcoLib_ReleaseIcon(hIcon); } } m_tree.SetImageList(hImageList, TVSIL_NORMAL); DestroyIcon(hBlankIcon); for (int k = 0; k < extraIconsBySlot.getCount(); k++) { ExtraIcon *extra = extraIconsBySlot[k]; if (extra->getType() == EXTRAICON_TYPE_GROUP) { ExtraIconGroup *group = (ExtraIconGroup *)extra; intlist ids; for (int j = 0; j < group->m_items.getCount(); j++) ids.add(group->m_items[j]->getID()); Tree_AddExtraIconGroup(ids, extra->isEnabled()); } else Tree_AddExtraIcon((BaseExtraIcon *)extra, extra->isEnabled()); } TVSORTCB sort = { 0 }; sort.hParent = NULL; sort.lParam = 0; sort.lpfnCompare = CompareFunc; m_tree.SortChildrenCB(&sort, 0); }
INT_PTR ExtraIcon_Register(WPARAM wParam, LPARAM lParam) { if (wParam == 0) return 0; EXTRAICON_INFO *ei = (EXTRAICON_INFO *)wParam; if (ei->cbSize < (int)sizeof(EXTRAICON_INFO)) return 0; if (ei->type != EXTRAICON_TYPE_CALLBACK && ei->type != EXTRAICON_TYPE_ICOLIB) return 0; if (IsEmpty(ei->name) || IsEmpty(ei->description)) return 0; if (ei->type == EXTRAICON_TYPE_CALLBACK && (ei->ApplyIcon == NULL || ei->RebuildIcons == NULL)) return 0; ptrT tszDesc(mir_a2t(ei->description)); TCHAR *desc = TranslateTH(lParam, tszDesc); BaseExtraIcon *extra = GetExtraIconByName(ei->name); if (extra != NULL) { if (ei->type != extra->getType() || ei->type != EXTRAICON_TYPE_ICOLIB) return 0; // Found one, now merge it if (_tcsicmp(extra->getDescription(), desc)) { CMString newDesc = extra->getDescription(); newDesc += _T(" / "); newDesc += desc; extra->setDescription(newDesc.c_str()); } if (!IsEmpty(ei->descIcon)) extra->setDescIcon(ei->descIcon); if (ei->OnClick != NULL) extra->setOnClick(ei->OnClick, ei->onClickParam); if (extra->getSlot() > 0) { if (clistRebuildAlreadyCalled) extra->rebuildIcons(); if (clistApplyAlreadyCalled) extraIconsByHandle[extra->getID() - 1]->applyIcons(); } return extra->getID(); } int id = registeredExtraIcons.getCount() + 1; switch (ei->type) { case EXTRAICON_TYPE_CALLBACK: extra = new CallbackExtraIcon(id, ei->name, desc, ei->descIcon == NULL ? "" : ei->descIcon, ei->RebuildIcons, ei->ApplyIcon, ei->OnClick, ei->onClickParam); break; case EXTRAICON_TYPE_ICOLIB: extra = new IcolibExtraIcon(id, ei->name, desc, ei->descIcon == NULL ? "" : ei->descIcon, ei->OnClick, ei->onClickParam); break; default: return 0; } char setting[512]; mir_snprintf(setting, SIZEOF(setting), "Position_%s", ei->name); extra->setPosition(db_get_w(NULL, MODULE_NAME, setting, 1000)); mir_snprintf(setting, SIZEOF(setting), "Slot_%s", ei->name); int slot = db_get_w(NULL, MODULE_NAME, setting, 1); if (slot == (WORD)-1) slot = -1; extra->setSlot(slot); extra->hLangpack = (int)lParam; registeredExtraIcons.insert(extra); extraIconsByHandle.insert(extra); LIST<ExtraIconGroup> groups(1); LoadGroups(groups); ExtraIconGroup *group = IsInGroup(groups, extra); if (group != NULL) RebuildListsBasedOnGroups(groups); else { for (int i = 0; i < groups.getCount(); i++) delete groups[i]; extraIconsBySlot.insert(extra); } if (slot >= 0 || group != NULL) { if (clistRebuildAlreadyCalled) extra->rebuildIcons(); slot = 0; for (int i = 0; i < extraIconsBySlot.getCount(); i++) { ExtraIcon *ex = extraIconsBySlot[i]; if (ex->getSlot() < 0) continue; int oldSlot = ex->getSlot(); ex->setSlot(slot++); if (clistApplyAlreadyCalled && (ex == group || ex == extra || oldSlot != slot)) extra->applyIcons(); } } return id; }
virtual void OnApply() { // Store old slots int *oldSlots = new int[registeredExtraIcons.getCount()]; int lastUsedSlot = -1; for (int i = 0; i < registeredExtraIcons.getCount(); i++) { if (extraIconsByHandle[i] == registeredExtraIcons[i]) oldSlots[i] = registeredExtraIcons[i]->getSlot(); else // Remove old slot for groups to re-set images oldSlots[i] = -1; lastUsedSlot = MAX(lastUsedSlot, registeredExtraIcons[i]->getSlot()); } lastUsedSlot = MIN(lastUsedSlot, GetNumberOfSlots()); // Get user data and create new groups LIST<ExtraIconGroup> groups(1); BYTE pos = 0; int firstEmptySlot = 0; HTREEITEM ht = m_tree.GetRoot(); TVITEMEX tvi; tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_STATE; tvi.stateMask = TVIS_STATEIMAGEMASK; while (ht) { tvi.hItem = ht; m_tree.GetItem(&tvi); intlist*ids = (intlist*)tvi.lParam; if (ids == NULL || ids->count < 1) continue; // ??? bool enabled = ((tvi.state & INDEXTOSTATEIMAGEMASK(3)) == INDEXTOSTATEIMAGEMASK(2)); int slot = (enabled ? firstEmptySlot++ : -1); if (slot >= GetNumberOfSlots()) slot = -1; if (ids->count == 1) { BaseExtraIcon *extra = registeredExtraIcons[ids->data[0] - 1]; extra->setPosition(pos++); extra->setSlot(slot); } else { char name[128]; mir_snprintf(name, "__group_%d", groups.getCount()); ExtraIconGroup *group = new ExtraIconGroup(name); for (int i = 0; i < ids->count; i++) { BaseExtraIcon *extra = registeredExtraIcons[ids->data[i] - 1]; extra->setPosition(pos++); group->addExtraIcon(extra); } group->setSlot(slot); groups.insert(group); } ht = m_tree.GetNextSibling(ht); } // Store data for (int i = 0; i < registeredExtraIcons.getCount(); i++) { BaseExtraIcon *extra = registeredExtraIcons[i]; char setting[512]; mir_snprintf(setting, "Position_%s", extra->getName()); db_set_w(NULL, MODULE_NAME, setting, extra->getPosition()); mir_snprintf(setting, "Slot_%s", extra->getName()); db_set_w(NULL, MODULE_NAME, setting, extra->getSlot()); } CallService(MS_DB_MODULE_DELETE, 0, (LPARAM)MODULE_NAME "Groups"); db_set_w(NULL, MODULE_NAME "Groups", "Count", groups.getCount()); for (int k = 0; k < groups.getCount(); k++) { ExtraIconGroup *group = groups[k]; char setting[512]; mir_snprintf(setting, "%d_count", k); db_set_w(NULL, MODULE_NAME "Groups", setting, (WORD)group->m_items.getCount()); for (int j = 0; j < group->m_items.getCount(); j++) { BaseExtraIcon *extra = group->m_items[j]; mir_snprintf(setting, "%d_%d", k, j); db_set_s(NULL, MODULE_NAME "Groups", setting, extra->getName()); } } // Clean removed slots for (int j = firstEmptySlot; j <= lastUsedSlot; j++) RemoveExtraIcons(j); // Apply icons to new slots RebuildListsBasedOnGroups(groups); for (int n = 0; n < extraIconsBySlot.getCount(); n++) { ExtraIcon *extra = extraIconsBySlot[n]; if (extra->getType() != EXTRAICON_TYPE_GROUP) if (oldSlots[((BaseExtraIcon *)extra)->getID() - 1] == extra->getSlot()) continue; if (extra->isEnabled()) extra->applyIcons(); } delete[] oldSlots; }
void ExtraIconGroup::onClick(MCONTACT hContact) { ExtraIcon *extra = getCurrentItem(hContact); if (extra != NULL) extra->onClick(hContact); }
INT_PTR ExtraIcon_Register(WPARAM wParam, LPARAM lParam) { if (wParam == 0) return 0; EXTRAICON_INFO *ei = (EXTRAICON_INFO *) wParam; if (ei->cbSize < (int) sizeof(EXTRAICON_INFO)) return 0; if (ei->type != EXTRAICON_TYPE_CALLBACK && ei->type != EXTRAICON_TYPE_ICOLIB) return 0; if (IsEmpty(ei->name) || IsEmpty(ei->description)) return 0; if (ei->type == EXTRAICON_TYPE_CALLBACK && (ei->ApplyIcon == NULL || ei->RebuildIcons == NULL)) return 0; const char *desc = Translate(ei->description); BaseExtraIcon *extra = GetExtraIconByName(ei->name); if (extra != NULL) { if (ei->type != extra->getType() || ei->type != EXTRAICON_TYPE_ICOLIB) return 0; // Found one, now merge it if (_stricmp(extra->getDescription(), desc)) { string newDesc = extra->getDescription(); newDesc += " / "; newDesc += desc; extra->setDescription(newDesc.c_str()); } if (!IsEmpty(ei->descIcon)) extra->setDescIcon(ei->descIcon); if (ei->OnClick != NULL) extra->setOnClick(ei->OnClick, ei->onClickParam); if (extra->getSlot() > 0) { if (clistRebuildAlreadyCalled) extra->rebuildIcons(); if (clistApplyAlreadyCalled) extraIconsByHandle[extra->getID() - 1]->applyIcons(); } return extra->getID(); } size_t id = registeredExtraIcons.size() + 1; switch (ei->type) { case EXTRAICON_TYPE_CALLBACK: extra = new CallbackExtraIcon(id, ei->name, desc, ei->descIcon == NULL ? "" : ei->descIcon, ei->RebuildIcons, ei->ApplyIcon, ei->OnClick, ei->onClickParam); break; case EXTRAICON_TYPE_ICOLIB: extra = new IcolibExtraIcon(id, ei->name, desc, ei->descIcon == NULL ? "" : ei->descIcon, ei->OnClick, ei->onClickParam); break; default: return 0; } char setting[512]; mir_snprintf(setting, MAX_REGS(setting), "Position_%s", ei->name); extra->setPosition(DBGetContactSettingWord(NULL, MODULE_NAME, setting, 1000)); mir_snprintf(setting, MAX_REGS(setting), "Slot_%s", ei->name); int slot = DBGetContactSettingWord(NULL, MODULE_NAME, setting, 1); if (slot == (WORD) -1) slot = -1; extra->setSlot(slot); registeredExtraIcons.push_back(extra); extraIconsByHandle.push_back(extra); vector<ExtraIconGroup *> groups; LoadGroups(groups); ExtraIconGroup *group = IsInGroup(groups, extra); if (group != NULL) { RebuildListsBasedOnGroups(groups); } else { for (unsigned int i = 0; i < groups.size(); ++i) delete groups[i]; extraIconsBySlot.push_back(extra); std::sort(extraIconsBySlot.begin(), extraIconsBySlot.end(), compareFunc()); } if (slot >= 0 || group != NULL) { if (clistRebuildAlreadyCalled) extra->rebuildIcons(); slot = 0; for (unsigned int i = 0; i < extraIconsBySlot.size(); ++i) { ExtraIcon *ex = extraIconsBySlot[i]; if (ex->getSlot() < 0) continue; int oldSlot = ex->getSlot(); ex->setSlot(slot++); if (clistApplyAlreadyCalled && (ex == group || ex == extra || oldSlot != slot)) extra->applyIcons(); } } return id; }