/*
Copyright (C) 2012-24 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 wchar_t g_szSkinLib[MAX_PATH];
/*
* Prepare
* prepares upperstring masks and registers them in IcoLib
*/
static wchar_t *getSectionName(int flag)
{
switch (flag) {
case MIRANDA_CASE:
if (g_plugin.getByte("GroupMiranda", 1))
return LPGENW("Client icons") L"/" LPGENW("Miranda clients");
break;
case MIRANDA_VERSION_CASE:
if (g_plugin.getByte("GroupMirandaVersion", 1))
return LPGENW("Client icons") L"/" LPGENW("Miranda clients");
break;
case MIRANDA_PACKS_CASE:
if (g_plugin.getByte("GroupMirandaPacks", 1))
return LPGENW("Client icons") L"/" LPGENW("Miranda clients") L"/" LPGENW("Pack overlays");
break;
case MULTI_CASE:
if (g_plugin.getByte("GroupMulti", 1))
return LPGENW("Client icons") L"/" LPGENW("Multi-proto clients");
break;
case GG_CASE:
if (g_plugin.getByte("GroupGG", 1))
return LPGENW("Client icons") L"/" LPGENW("Gadu-Gadu clients");
break;
case ICQ_CASE:
if (g_plugin.getByte("GroupICQ", 1))
return LPGENW("Client icons") L"/" LPGENW("ICQ clients");
break;
case IRC_CASE:
if (g_plugin.getByte("GroupIRC", 1))
return LPGENW("Client icons") L"/" LPGENW("IRC clients");
break;
case JABBER_CASE:
if (g_plugin.getByte("GroupJabber", 1))
return LPGENW("Client icons") L"/" LPGENW("Jabber clients");
break;
case RSS_CASE:
if (g_plugin.getByte("GroupRSS", 1))
return LPGENW("Client icons") L"/" LPGENW("RSS clients");
break;
case WEATHER_CASE:
if (g_plugin.getByte("GroupWeather", 1))
return LPGENW("Client icons") L"/" LPGENW("Weather clients");
break;
case FACEBOOK_CASE:
if (g_plugin.getByte("GroupFacebook", 1))
return LPGENW("Client icons") L"/" LPGENW("Facebook clients");
break;
case VK_CASE:
if (g_plugin.getByte("GroupVK", 1))
return LPGENW("Client icons") L"/" LPGENW("VKontakte clients");
break;
case OTHER_PROTOS_CASE:
if (g_plugin.getByte("GroupOtherProtos", 1))
return LPGENW("Client icons") L"/" LPGENW("Other protocols");
break;
case OTHERS_CASE:
if (g_plugin.getByte("GroupOthers", 1))
return LPGENW("Client icons") L"/" LPGENW("Other icons");
break;
case OVERLAYS_RESOURCE_CASE:
if (g_plugin.getByte("GroupOverlaysResource", 1))
return LPGENW("Client icons") L"/" LPGENW("Overlays") L"/" LPGENW("Resource");
break;
case OVERLAYS_PLATFORM_CASE:
if (g_plugin.getByte("GroupOverlaysPlatform", 1))
return LPGENW("Client icons") L"/" LPGENW("Overlays") L"/" LPGENW("Platform");
break;
case OVERLAYS_UNICODE_CASE:
if (g_plugin.getByte("GroupOverlaysUnicode", 1))
return LPGENW("Client icons") L"/" LPGENW("Overlays") L"/" LPGENW("Platform");
break;
case OVERLAYS_SECURITY_CASE:
if (g_plugin.getByte("GroupOverlaysSecurity", 1))
return LPGENW("Client icons") L"/" LPGENW("Overlays") L"/" LPGENW("Security");
break;
case OVERLAYS_PROTO_CASE:
if (g_plugin.getByte("GroupOverlaysProtos", 1))
return LPGENW("Client icons") L"/" LPGENW("Overlays") L"/" LPGENW("Protocol");
break;
default:
return LPGENW("Client icons");
}
return nullptr;
}
void Prepare(KN_FP_MASK *mask, bool bEnable, LIST &dest)
{
mask->szMaskUpper = nullptr;
if (mask->hIcolibItem)
IcoLib_RemoveIconByHandle(mask->hIcolibItem);
mask->hIcolibItem = nullptr;
if (!mask->szMask || !bEnable)
return;
size_t iMaskLen = mir_wstrlen(mask->szMask) + 1;
LPTSTR pszNewMask = (LPTSTR)HeapAlloc(hHeap, HEAP_NO_SERIALIZE, iMaskLen * sizeof(wchar_t));
wcscpy_s(pszNewMask, iMaskLen, mask->szMask);
_wcsupr_s(pszNewMask, iMaskLen);
mask->szMaskUpper = pszNewMask;
wchar_t destfile[MAX_PATH];
if (mask->iIconIndex == IDI_NOTFOUND || mask->iIconIndex == IDI_UNKNOWN || mask->iIconIndex == IDI_UNDETECTED)
GetModuleFileName(g_plugin.getInst(), destfile, MAX_PATH);
else {
wcsncpy_s(destfile, g_szSkinLib, _TRUNCATE);
if (0 != _waccess(destfile, 0))
return;
}
LPTSTR SectName = getSectionName(mask->iSectionFlag);
if (SectName == nullptr)
return;
SKINICONDESC sid = {};
sid.flags = SIDF_ALL_UNICODE;
sid.section.w = SectName;
sid.pszName = mask->szIconName;
sid.description.w = mask->szClientDescription;
sid.defaultFile.w = destfile;
sid.iDefaultIndex = -mask->iIconIndex;
mask->hIcolibItem = g_plugin.addIcon(&sid);
mask->idx = dest.getCount();
dest.insert(mask);
}
/////////////////////////////////////////////////////////////////////////////////////////
static LIST arCustom(10);
void UnregisterCustomIcons()
{
for (auto &it : arCustom) {
if (it->hIcolibItem)
IcoLib_RemoveIconByHandle(it->hIcolibItem);
mir_free(it->szClientDescription);
mir_free(it->szIconName);
mir_free(it->szMask);
mir_free(it);
}
}
void RegisterCustomIcons()
{
UnregisterCustomIcons();
FILE *in = _wfopen(VARSW(L"%miranda_userdata%\\fingerprint.json"), L"r");
if (in == nullptr)
return;
int cbSize = filelength(fileno(in));
ptrA szJson((char*)mir_alloc(cbSize+1));
fread(szJson, 1, cbSize, in);
fclose(in);
JSONNode root = JSONNode::parse(szJson);
if (!root)
return;
for (auto &it : root["masks"]) {
CMStringA szName = it["name"].as_mstring();
CMStringW wszMask = it["mask"].as_mstring();
CMStringW szDescription = it["descr"].as_mstring();
if (wszMask.IsEmpty() || szName.IsEmpty() || szDescription.IsEmpty())
continue;
wchar_t wszFullPath[MAX_PATH];
PathToAbsoluteW(it["iconFile"].as_mstring(), wszFullPath);
if (0 != _waccess(wszFullPath, 0))
continue;
LPTSTR SectName = getSectionName(it["group"].as_int());
if (SectName == nullptr)
continue;
auto *pMask = (KN_FP_MASK *)mir_calloc(sizeof(KN_FP_MASK));
int iMaskLen = wszMask.GetLength() + 1;
pMask->szMaskUpper = (LPTSTR)HeapAlloc(hHeap, HEAP_NO_SERIALIZE, iMaskLen * sizeof(wchar_t));
wcscpy_s(pMask->szMaskUpper, iMaskLen, wszMask);
_wcsupr_s(pMask->szMaskUpper, iMaskLen);
pMask->szMask = pMask->szMaskUpper;
pMask->iIconIndex = it["iconIndex"].as_int();
pMask->szIconName = szName.Detach();
pMask->szClientDescription = szDescription.Detach();
SKINICONDESC sid = {};
sid.flags = SIDF_ALL_UNICODE;
sid.section.w = SectName;
sid.pszName = pMask->szIconName;
sid.description.w = pMask->szClientDescription;
sid.defaultFile.w = wszFullPath;
sid.iDefaultIndex = -pMask->iIconIndex;
pMask->hIcolibItem = g_plugin.addIcon(&sid);
pMask->idx = g_arCommon.getCount();
g_arCommon.insert(pMask, 0);
}
}