/* Copyright (C) 2012-21 Miranda NG team (https://miranda-ng.org) 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 version 2 of the License. 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, see . */ #include "stdafx.h" extern BYTE nameOrder[NAMEORDERCOUNT]; ///////////////////////////////////////////////////////////////////////////////////////// int ListView_GetItemTextA(HWND hwndLV, int i, int iSubItem, char *pszText, int cchTextMax) { LV_ITEMA lvi; lvi.iSubItem = iSubItem; lvi.cchTextMax = cchTextMax; lvi.pszText = pszText; return SendMessageA(hwndLV, LVM_GETITEMTEXTA, (WPARAM)(i), (LPARAM)(LV_ITEMA *)&lvi); } int ListView_SetItemTextA(HWND hwndLV, int i, int iSubItem, const char *pszText) { LV_ITEMA lvi; lvi.iSubItem = iSubItem; lvi.pszText = (char*)pszText; return SendMessageA(hwndLV, LVM_SETITEMTEXTA, (WPARAM)(i), (LPARAM)(LV_ITEMA *)&lvi); } ///////////////////////////////////////////////////////////////////////////////////////// char* StringFromBlob(BYTE *blob, WORD len) { int j; char tmp[16]; char *data = (char*)mir_alloc(3 * (len + 2)); data[0] = 0; for (j = 0; j < len; j++) { mir_snprintf(tmp, "%02X ", blob[j]); mir_strcat(data, tmp); } return data; } int WriteBlobFromString(MCONTACT hContact, const char *szModule, const char *szSetting, const char *szValue, int len) { int j = 0, i = 0; BYTE b; int tmp, res = 0; BYTE *data = (BYTE*)mir_alloc(2 + len / 2); if (!data) return 0; while (j < len) { b = szValue[j]; if ((b >= '0' && b <= '9') || (b >= 'A' && b <= 'F') || (b >= 'a' && b <= 'f')) { if (sscanf(&szValue[j], "%02X", &tmp) == 1) { data[i++] = (BYTE)(tmp & 0xFF); j++; } } j++; } if (i) res = !db_set_blob(hContact, szModule, szSetting, data, (WORD)i); mir_free(data); return res; } wchar_t* DBVType(BYTE type) { switch (type) { case DBVT_BYTE: return L"BYTE"; case DBVT_WORD: return L"WORD"; case DBVT_DWORD: return L"DWORD"; case DBVT_ASCIIZ: return L"STRING"; case DBVT_WCHAR: case DBVT_UTF8: return L"UNICODE"; case DBVT_BLOB: return L"BLOB"; case DBVT_DELETED: return L"DELETED"; } return L""; } DWORD getNumericValue(DBVARIANT *dbv) { switch (dbv->type) { case DBVT_DWORD: return dbv->dVal; case DBVT_WORD: return dbv->wVal; case DBVT_BYTE: return dbv->bVal; } return 0; } int setNumericValue(MCONTACT hContact, const char *module, const char *setting, DWORD value, int type) { switch (type) { case DBVT_BYTE: if (value <= 0xFF) return !db_set_b(hContact, module, setting, (BYTE)value); break; case DBVT_WORD: if (value <= 0xFFFF) return !db_set_w(hContact, module, setting, (WORD)value); break; case DBVT_DWORD: return !db_set_dw(hContact, module, setting, value); } return 0; } int IsRealUnicode(wchar_t *value) { BOOL nonascii = 0; WideCharToMultiByte(Langpack_GetDefaultCodePage(), WC_NO_BEST_FIT_CHARS, value, -1, nullptr, 0, nullptr, &nonascii); return nonascii; } int setTextValue(MCONTACT hContact, const char *module, const char *setting, wchar_t *value, int type) { if (type == DBVT_UTF8 || type == DBVT_WCHAR) return !db_set_ws(hContact, module, setting, value); if (type == DBVT_ASCIIZ && IsRealUnicode(value)) return 0; return !db_set_s(hContact, module, setting, _T2A(value)); } int GetValueA(MCONTACT hContact, const char *module, const char *setting, char *value, int length) { DBVARIANT dbv = {}; if (!module || !setting || !value) return 0; if (length >= 10 && !db_get_s(hContact, module, setting, &dbv, 0)) { switch (dbv.type) { case DBVT_ASCIIZ: mir_strncpy(value, dbv.pszVal, length); break; case DBVT_DWORD: case DBVT_WORD: case DBVT_BYTE: _ultoa(getNumericValue(&dbv), value, 10); break; case DBVT_WCHAR: mir_strncpy(value, ptrA(mir_u2a(dbv.pwszVal)), length); break; case DBVT_UTF8: mir_strncpy(value, ptrA(mir_utf8decodeA(dbv.pszVal)), length); break; case DBVT_DELETED: value[0] = 0; return 0; } int type = dbv.type; db_free(&dbv); return type; } value[0] = 0; return 0; } int GetValueW(MCONTACT hContact, const char *module, const char *setting, wchar_t *value, int length) { DBVARIANT dbv = {}; if (!module || !setting || !value) return 0; if (length >= 10 && !db_get_s(hContact, module, setting, &dbv, 0)) { switch (dbv.type) { case DBVT_ASCIIZ: mir_wstrncpy(value, ptrW(mir_a2u(dbv.pszVal)), length); break; case DBVT_DWORD: case DBVT_WORD: case DBVT_BYTE: _ultow(getNumericValue(&dbv), value, 10); break; case DBVT_WCHAR: mir_wstrncpy(value, dbv.pwszVal, length); break; case DBVT_UTF8: mir_wstrncpy(value, ptrW(mir_utf8decodeW(dbv.pszVal)), length); break; case DBVT_DELETED: value[0] = 0; return 0; } int type = dbv.type; db_free(&dbv); return type; } value[0] = 0; return 0; } int GetContactName(MCONTACT hContact, const char *proto, wchar_t *value, int maxlen) { if (!value) return 0; if (!hContact) { mir_wstrncpy(value, TranslateT("Settings"), maxlen); return 1; } char *szProto = (char*)proto; char tmp[FLD_SIZE]; wchar_t name[NAME_SIZE]; name[0] = 0; if (hContact && (!proto || !proto[0])) if (!db_get_static(hContact, "Protocol", "p", tmp, _countof(tmp))) szProto = tmp; for (int i = 0; i < NAMEORDERCOUNT - 1; i++) { switch (nameOrder[i]) { case 0: // custom name GetValueW(hContact, "CList", "MyHandle", name, _countof(name)); break; case 1: // nick if (!szProto) break; GetValueW(hContact, szProto, "Nick", name, _countof(name)); break; case 2: // First Name // if (!szProto) break; // GetValueW(hContact, szProto, "FirstName", name, _countof(name)); break; case 3: // E-mail if (!szProto) break; GetValueW(hContact, szProto, "e-mail", name, _countof(name)); break; case 4: // Last Name // GetValueW(hContact, szProto, "LastName", name, _countof(name)); break; case 5: // Unique id if (szProto) { // protocol must define a PFLAG_UNIQUEIDSETTING const char *uid = Proto_GetUniqueId(szProto); if (uid) GetValueW(hContact, szProto, uid, name, _countof(name)); } break; case 6: // first + last name if (szProto) { GetValueW(hContact, szProto, "FirstName", name, _countof(name)); int len = (int)mir_wstrlen(name); if (len + 2 < _countof(name)) { if (len) mir_wstrncat(name, L" ", _countof(name)); len++; GetValueW(hContact, szProto, "LastName", &name[len], _countof(name) - len); } } break; } if (name[0]) break; } if (!name[0]) mir_wstrncpy(name, TranslateT(""), _countof(name)); if (szProto && szProto[0]) { if (g_Order) mir_snwprintf(value, maxlen, L"(%S) %s", szProto, name); else mir_snwprintf(value, maxlen, L"%s (%S)", name, szProto); } else mir_wstrncpy(value, name, maxlen); PROTOACCOUNT *pa = Proto_GetAccount(szProto); if (!pa->IsEnabled()) { mir_wstrncat(value, L" ", maxlen); mir_wstrncat(value, TranslateT("[UNLOADED]"), maxlen); } return 1; } int ApplyProtoFilter(MCONTACT hContact) { if (g_Mode == MODE_ALL) return 0; int loaded = 0; char szProto[FLD_SIZE]; if (!db_get_static(hContact, "Protocol", "p", szProto, _countof(szProto))) loaded = Proto_GetAccount(szProto) ? 1 : 0; if ((loaded && g_Mode == MODE_UNLOADED) || (!loaded && g_Mode == MODE_LOADED)) return 1; return 0; } void loadListSettings(HWND hwnd, ColumnsSettings *cs) { LVCOLUMN sLC = {}; sLC.fmt = LVCFMT_LEFT; sLC.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH; int i = 0; while (cs[i].name) { sLC.pszText = TranslateW(cs[i].name); sLC.cx = g_plugin.getWord(cs[i].dbname, cs[i].defsize); ListView_InsertColumn(hwnd, cs[i].index, &sLC); i++; } } void saveListSettings(HWND hwnd, ColumnsSettings *cs) { char tmp[FLD_SIZE]; LVCOLUMN sLC = {}; sLC.mask = LVCF_WIDTH; int i = 0; while (cs[i].name) { if (ListView_GetColumn(hwnd, cs[i].index, &sLC)) { mir_snprintf(tmp, cs[i].dbname, i); g_plugin.setWord(tmp, (WORD)sLC.cx); } i++; } } int CALLBACK ColumnsCompare(LPARAM lParam1, LPARAM lParam2, LPARAM myParam) { ColumnsSortParams params = *(ColumnsSortParams *)myParam; const int maxSize = 1024; wchar_t text1[maxSize]; wchar_t text2[maxSize]; ListView_GetItemText(params.hList, lParam1, params.column, text1, _countof(text1)); ListView_GetItemText(params.hList, lParam2, params.column, text2, _countof(text2)); int res = mir_wstrcmpi(text1, text2); return (params.column == params.last) ? -res : res; }