summaryrefslogtreecommitdiff
path: root/plugins/NewStory/src/templates.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/NewStory/src/templates.cpp')
-rw-r--r--plugins/NewStory/src/templates.cpp116
1 files changed, 85 insertions, 31 deletions
diff --git a/plugins/NewStory/src/templates.cpp b/plugins/NewStory/src/templates.cpp
index 9d3a9cf633..ad7510baaa 100644
--- a/plugins/NewStory/src/templates.cpp
+++ b/plugins/NewStory/src/templates.cpp
@@ -1,6 +1,6 @@
/*
Copyright (c) 2005 Victor Pavlychko (nullbyte@sotline.net.ua)
-Copyright (C) 2012-24 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-25 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
@@ -29,13 +29,57 @@ wchar_t *months[12] =
};
///////////////////////////////////////////////////////////////////////////////
-// HTML generator
+// color table
+
+struct
+{
+ const wchar_t *pwszName;
+ uint32_t iValue;
+}
+static builtinColors[] = {
+ { L"black", RGB(0, 0, 0) },
+ { L"navy", RGB(0, 0, 128) },
+ { L"blue", RGB(0, 0, 255) },
+ { L"green", RGB(0, 128, 0) },
+ { L"lime", RGB(0, 255, 0) },
+ { L"red", RGB(255, 0, 0) },
+ { L"maroon", RGB(128, 0, 0) },
+ { L"purple", RGB(128, 0, 128) },
+ { L"pink", RGB(255, 0, 255) },
+ { L"olive", RGB(128, 128, 0) },
+ { L"yellow", RGB(255, 255, 0) },
+ { L"cyan", RGB(0, 128, 128) },
+ { L"aqua", RGB(0, 255, 255) },
+ { L"gray", RGB(128, 128, 128) },
+ { L"white", RGB(255, 255, 255) },
+ { L"silver", RGB(192, 192, 192) },
+};
static uint32_t color2html(COLORREF clr)
{
return (((clr & 0xFF) << 16) | (clr & 0xFF00) | ((clr & 0xFF0000) >> 16));
}
+static int str2color(const CMStringW &str)
+{
+ for (auto &it : builtinColors)
+ if (str == it.pwszName)
+ return it.iValue;
+
+ // 6 hex digits in the RGB format
+ if (str.GetLength() != 6)
+ return -1;
+
+ for (int i = 0; i < 6; i++)
+ if (!is_hex_digit(str[i]))
+ return -1;
+
+ return color2html(wcstoul(str, 0, 16));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// HTML generator
+
static wchar_t* font2html(LOGFONTA &lf, wchar_t *dest)
{
mir_snwprintf(dest, 100, L"font-family: %S; font-size: %dpt; font-weight: %s %s",
@@ -175,7 +219,9 @@ static void AppendString(CMStringW &buf, const wchar_t *p, ItemData *pItem)
if (auto *p2 = wcsstr(p1, L"[/url]")) {
CMStringW wszDescr(p1, int(p2 - p1));
- buf.AppendFormat(L"<a class=\"link\" href=\"%s\">%s</a>", wszUrl.c_str(), wszDescr.c_str());
+ buf.AppendFormat(L"<a class=\"link\" href=\"%s\">", wszUrl.c_str());
+ AppendString(buf, wszDescr, pItem);
+ buf.Append(L"</a>");
p = p2 + 5;
}
}
@@ -195,14 +241,17 @@ static void AppendString(CMStringW &buf, const wchar_t *p, ItemData *pItem)
p += 6;
if (auto *p1 = wcschr(p, ']')) {
- CMStringW wszColor(p, int(p1 - p));
- buf.AppendFormat(L"<font color=#%06X>", color2html(wcstoul(wszColor, 0, 16)));
+ int iColor = str2color(CMStringW(p, int(p1 - p)));
+ if (iColor != -1)
+ buf.AppendFormat(L"<font color=#%06X>", color2html(iColor));
+ else
+ buf.Append(L"<font class=\"body\">");
p = p1;
}
else p--;
}
- else if (!wcsncmp(p, L"/color]", 7)) {
- p += 6;
+ else if (*pEnd && !wcsncmp(p, L"color]", 6)) {
+ p += 5;
buf.AppendFormat(L"</font>");
}
else if (!wcsncmp(p, L"code]", 5)) {
@@ -235,8 +284,8 @@ CMStringW ItemData::formatHtml(const wchar_t *pwszStr)
auto &F = g_fontTable[fontID];
wchar_t szFont[100];
- str.AppendFormat(L"body {margin: 0px; text-align: left; %s; color: NSText; overflow: auto;}\n", font2html(F.lf, szFont));
- str.AppendFormat(L".nick {color: #%06X }\n", color2html(g_colorTable[(dbe.flags & DBEF_SENT) ? COLOR_OUTNICK : COLOR_INNICK].cl));
+ str.AppendFormat(L"body {margin: 0px; text-align: left; %s; overflow: auto;}\n", font2html(F.lf, szFont));
+ str.AppendFormat(L".nick {color: #%06X }\n", color2html(g_colorTable[dbe.bSent ? COLOR_OUTNICK : COLOR_INNICK].cl));
str.AppendFormat(L".link {color: #%06X }\n", color2html(g_colorTable[COLOR_LINK].cl));
str.AppendFormat(L".quote {border-left: 4px solid #%06X; padding-left: 8px; }\n", color2html(g_colorTable[COLOR_QUOTE].cl));
@@ -270,7 +319,11 @@ CMStringW ItemData::formatHtml(const wchar_t *pwszStr)
CMStringW szBody(wszOrigText);
UrlAutodetect(szBody);
+
+ str.Append(L"<div id=\"bbody\">");
AppendString(str, szBody, this);
+ str.Append(L"</div>");
+
if (spRes) {
int iOffset = 0;
for (int i = 0; i < (int)sp.numSmileys; i++) {
@@ -409,7 +462,7 @@ CMStringA NewstoryListData::GatherSelectedRtf()
buf.AppendFormat("{\\uc1\\pard \\cb%d\\cf%d\\f%d\\b0\\i0\\fs%d ", COLOR_BACK + 7, colorID+COLOR_COUNT+7, fontID, GetFontHeight(g_fontTable[fontID].lf));
CMStringW wszText(p->formatString());
wszText.Replace(L"[c0]", CMStringW(FORMAT, L"[c%d]", colorID + COLOR_COUNT + 7));
- wszText.Replace(L"[c1]", CMStringW(FORMAT, L"[c%d]", 7 + ((p->dbe.flags & DBEF_SENT) ? COLOR_OUTNICK : COLOR_INNICK)));
+ wszText.Replace(L"[c1]", CMStringW(FORMAT, L"[c%d]", 7 + (p->dbe.bSent ? COLOR_OUTNICK : COLOR_INNICK)));
AppendUnicodeToBuffer(buf, wszText);
buf.Append("\\par }");
}
@@ -427,18 +480,15 @@ CMStringW TplFormatString(int tpl, MCONTACT hContact, ItemData *item)
return CMStringW();
auto &T = templates[tpl];
- if (T.value == nullptr)
- T.value = mir_wstrdup(T.defvalue);
+ wchar_t *pValue = TranslateW((T.value) ? T.value : T.defvalue);
TemplateVars vars;
-
for (auto &it : T.vf)
if (it)
it(&vars, hContact, item);
CMStringW buf;
-
- for (wchar_t *p = T.value; *p; p++) {
+ for (wchar_t *p = pValue; *p; p++) {
if (*p == '%') {
wchar_t *var = vars.GetVar((p[1] & 0xff));
if (var)
@@ -512,11 +562,11 @@ void vfGlobal(TemplateVars *vars, MCONTACT hContact, ItemData *)
vars->SetVar('S', nick, true);
}
-void vfContact(TemplateVars *vars, MCONTACT hContact, ItemData *)
+void vfContact(TemplateVars *vars, MCONTACT hContact, ItemData *pItem)
{
// %N: buddy's nick (not for messages)
wchar_t *nick = (hContact == 0) ? TranslateT("System history") : Clist_GetContactDisplayName(hContact, 0);
- vars->SetNick(nick);
+ vars->SetNick(nick, pItem);
wchar_t buf[20];
// %c: event count
@@ -524,10 +574,10 @@ void vfContact(TemplateVars *vars, MCONTACT hContact, ItemData *)
vars->SetVar('c', buf, true);
}
-void vfSystem(TemplateVars *vars, MCONTACT hContact, ItemData *)
+void vfSystem(TemplateVars *vars, MCONTACT hContact, ItemData *pItem)
{
// %N: buddy's nick (not for messages)
- vars->SetNick(TranslateT("System event"));
+ vars->SetNick(TranslateT("System event"), pItem);
// %c: event count
wchar_t buf[20];
@@ -535,33 +585,33 @@ void vfSystem(TemplateVars *vars, MCONTACT hContact, ItemData *)
vars->SetVar('c', buf, true);
}
-void vfEvent(TemplateVars *vars, MCONTACT, ItemData *item)
+void vfEvent(TemplateVars *vars, MCONTACT, ItemData *pItem)
{
wchar_t buf[100];
// %N: Nickname
- if (!item->m_bIsResult && (item->dbe.flags & DBEF_SENT)) {
- if (!item->wszNick) {
- char *proto = Proto_GetBaseAccountName(item->dbe.hContact);
+ if (!pItem->m_bIsResult && pItem->dbe.bSent) {
+ if (!pItem->wszNick) {
+ char *proto = Proto_GetBaseAccountName(pItem->dbe.hContact);
ptrW nick(Contact::GetInfo(CNF_DISPLAY, 0, proto));
- vars->SetNick(nick);
+ vars->SetNick(nick, pItem);
}
- else vars->SetNick(item->wszNick);
+ else vars->SetNick(pItem->wszNick, pItem);
}
else {
- wchar_t *nick = (item->wszNick) ? item->wszNick : Clist_GetContactDisplayName(item->dbe.hContact, 0);
- vars->SetNick(nick);
+ wchar_t *nick = (pItem->wszNick) ? pItem->wszNick : Clist_GetContactDisplayName(pItem->dbe.hContact, 0);
+ vars->SetNick(nick, pItem);
}
// %D: direction symbol
- if (item->dbe.flags & DBEF_SENT)
+ if (pItem->dbe.bSent)
vars->SetVar('D', L"<<", false);
else
vars->SetVar('D', L">>", false);
// %t: timestamp
SYSTEMTIME st;
- if (!TimeZone_GetSystemTime(nullptr, item->dbe.timestamp, &st, 0)) {
+ if (!TimeZone_GetSystemTime(nullptr, pItem->dbe.getUnixtime(), &st, 0)) {
int iLocale = Langpack_GetDefaultLocale();
GetDateFormatW(iLocale, 0, &st, L"dd.MM.yyyy, ", buf, _countof(buf));
@@ -653,9 +703,13 @@ void vfOther(TemplateVars *vars, MCONTACT, ItemData *item)
/////////////////////////////////////////////////////////////////////////////////////////
-void TemplateVars::SetNick(wchar_t *v)
+void TemplateVars::SetNick(wchar_t *v, ItemData *pItem)
{
- CMStringW wszNick(FORMAT, L"[c1]%s[c0]", v);
+ CMStringW wszNick;
+ if (pItem)
+ wszNick.Format(L"[c1]%s[c0]", v);
+ else
+ wszNick = v;
auto &V = vars['N'];
if (V.del)