diff options
Diffstat (limited to 'plugins/NewStory/src')
-rw-r--r-- | plugins/NewStory/src/calendartool.cpp | 2 | ||||
-rw-r--r-- | plugins/NewStory/src/fonts.cpp | 3 | ||||
-rw-r--r-- | plugins/NewStory/src/history.h | 3 | ||||
-rw-r--r-- | plugins/NewStory/src/history_array.cpp | 34 | ||||
-rw-r--r-- | plugins/NewStory/src/history_control.cpp | 158 | ||||
-rw-r--r-- | plugins/NewStory/src/history_control.h | 6 | ||||
-rw-r--r-- | plugins/NewStory/src/history_dlg.cpp | 126 | ||||
-rw-r--r-- | plugins/NewStory/src/history_log.cpp | 15 | ||||
-rw-r--r-- | plugins/NewStory/src/history_menus.cpp | 7 | ||||
-rw-r--r-- | plugins/NewStory/src/history_svc.cpp | 2 | ||||
-rw-r--r-- | plugins/NewStory/src/main.cpp | 6 | ||||
-rw-r--r-- | plugins/NewStory/src/options.cpp | 5 | ||||
-rw-r--r-- | plugins/NewStory/src/stdafx.cxx | 2 | ||||
-rw-r--r-- | plugins/NewStory/src/stdafx.h | 2 | ||||
-rw-r--r-- | plugins/NewStory/src/templates.cpp | 116 | ||||
-rw-r--r-- | plugins/NewStory/src/templates.h | 2 | ||||
-rw-r--r-- | plugins/NewStory/src/utils.cpp | 31 | ||||
-rw-r--r-- | plugins/NewStory/src/utils.h | 2 | ||||
-rw-r--r-- | plugins/NewStory/src/version.h | 2 | ||||
-rw-r--r-- | plugins/NewStory/src/webpage.cpp | 22 |
20 files changed, 309 insertions, 237 deletions
diff --git a/plugins/NewStory/src/calendartool.cpp b/plugins/NewStory/src/calendartool.cpp index d7c3a4bb27..a03d05057f 100644 --- a/plugins/NewStory/src/calendartool.cpp +++ b/plugins/NewStory/src/calendartool.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
diff --git a/plugins/NewStory/src/fonts.cpp b/plugins/NewStory/src/fonts.cpp index 72bf329028..09720e3406 100644 --- a/plugins/NewStory/src/fonts.cpp +++ b/plugins/NewStory/src/fonts.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
@@ -77,6 +77,7 @@ int evtFontsChanged(WPARAM, LPARAM) }
WindowList_Broadcast(g_hNewstoryLogs, UM_REDRAW_LIST, 0, 0);
+ WindowList_Broadcast(g_hNewstoryHistLogs, UM_REDRAW_LIST, 0, 0);
return 0;
}
diff --git a/plugins/NewStory/src/history.h b/plugins/NewStory/src/history.h index 0b3bebe5d9..e83b8c69ec 100644 --- a/plugins/NewStory/src/history.h +++ b/plugins/NewStory/src/history.h @@ -30,9 +30,10 @@ enum UM_BOOKMARKS = WM_USER + 0x661,
UM_LOCATETIME = WM_USER + 0x662,
+ UM_UPDATE_WINDOW = WM_USER + 0x663,
};
-extern MWindowList g_hNewstoryWindows, g_hNewstoryLogs;
+extern MWindowList g_hNewstoryWindows, g_hNewstoryLogs, g_hNewstoryHistLogs;
void InitMenus();
void InitHotkeys();
diff --git a/plugins/NewStory/src/history_array.cpp b/plugins/NewStory/src/history_array.cpp index bcf1120a9b..6b57f8ca67 100644 --- a/plugins/NewStory/src/history_array.cpp +++ b/plugins/NewStory/src/history_array.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
@@ -25,7 +25,7 @@ bool Filter::check(ItemData *item) const {
if (!item) return false;
if (!(flags & EVENTONLY)) {
- if (item->dbe.flags & DBEF_SENT) {
+ if (item->dbe.bSent) {
if (!(flags & OUTGOING))
return false;
}
@@ -92,9 +92,9 @@ static bool isEqual(const ItemData *p1, const ItemData *p2) return false;
if (p1->dbe.eventType != p2->dbe.eventType)
return false;
- if ((p1->dbe.flags & DBEF_SENT) != (p2->dbe.flags & DBEF_SENT))
+ if (p1->dbe.bSent != p2->dbe.bSent)
return false;
- if (p1->dbe.timestamp / 86400 != p2->dbe.timestamp / 86400)
+ if (p1->dbe.getUnixtime() / 86400 != p2->dbe.getUnixtime() / 86400)
return false;
return true;
}
@@ -165,7 +165,7 @@ static bool isEqualGC(const ItemData *p1, const ItemData *p2) if (wcscmp(p1->wszNick, p2->wszNick))
return false;
- if (p1->dbe.timestamp / 86400 != p2->dbe.timestamp / 86400)
+ if (p1->dbe.getUnixtime() / 86400 != p2->dbe.getUnixtime() / 86400)
return false;
return true;
}
@@ -216,6 +216,8 @@ int ItemData::calcHeight(int width) cx -= xPos;
if (m_bOfflineDownloaded != 0 || m_bDelivered || m_bRemoteRead) // Download completed icon
cx -= 18;
+ if (dbe.bEdited)
+ cx -= 18;
}
leftOffset = xPos;
@@ -316,13 +318,13 @@ void ItemData::getFontColor(int &fontId, int &colorId) const {
switch (dbe.eventType) {
case EVENTTYPE_MESSAGE:
- fontId = !(dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG;
- colorId = !(dbe.flags & DBEF_SENT) ? COLOR_INMSG : COLOR_OUTMSG;
+ fontId = !dbe.bSent ? FONT_INMSG : FONT_OUTMSG;
+ colorId = !dbe.bSent ? COLOR_INMSG : COLOR_OUTMSG;
break;
case EVENTTYPE_FILE:
- fontId = !(dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE;
- colorId = !(dbe.flags & DBEF_SENT) ? COLOR_INFILE : COLOR_OUTFILE;
+ fontId = !dbe.bSent ? FONT_INFILE : FONT_OUTFILE;
+ colorId = !dbe.bSent ? COLOR_INFILE : COLOR_OUTFILE;
break;
case EVENTTYPE_STATUSCHANGE:
@@ -341,13 +343,13 @@ void ItemData::getFontColor(int &fontId, int &colorId) const break;
case EVENTTYPE_JABBER_PRESENCE:
- fontId = !(dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
- colorId = !(dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
+ fontId = !dbe.bSent ? FONT_INOTHER : FONT_OUTOTHER;
+ colorId = !dbe.bSent ? COLOR_INOTHER : COLOR_OUTOTHER;
break;
default:
- fontId = !(dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
- colorId = !(dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
+ fontId = !dbe.bSent ? FONT_INOTHER : FONT_OUTOTHER;
+ colorId = !dbe.bSent ? COLOR_INOTHER : COLOR_OUTOTHER;
break;
}
}
@@ -444,11 +446,11 @@ void ItemData::load(bool bLoadAlways) CMStringW str, wszNick;
wchar_t wszTime[100];
- TimeZone_PrintTimeStamp(0, dbei.timestamp, L"D t", wszTime, _countof(wszTime), 0);
+ TimeZone_PrintTimeStamp(0, dbei.getUnixtime(), L"D t", wszTime, _countof(wszTime), 0);
if (Contact::IsGroupChat(dbe.hContact) && dbei.szUserId)
wszNick = Utf2T(dbei.szUserId);
- else if (dbei.flags & DBEF_SENT) {
+ else if (dbei.bSent) {
if (char *szProto = Proto_GetBaseAccountName(dbe.hContact))
wszNick = ptrW(Contact::GetInfo(CNF_DISPLAY, 0, szProto));
else
@@ -523,7 +525,7 @@ void HistoryArray::addChatEvent(NewstoryListData *pOwner, SESSION_INFO *si, cons p.wtext = wszText.Detach();
p.m_bLoaded = true;
p.m_bHighlighted = lin->bIsHighlighted;
- p.dbe.timestamp = lin->time;
+ p.dbe.iTimestamp = lin->time;
if (lin->bIsMe)
p.dbe.flags |= DBEF_SENT;
diff --git a/plugins/NewStory/src/history_control.cpp b/plugins/NewStory/src/history_control.cpp index f7797fc912..a25760ae87 100644 --- a/plugins/NewStory/src/history_control.cpp +++ b/plugins/NewStory/src/history_control.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
@@ -186,10 +186,7 @@ bool NewstoryListData::AtTop(void) const if (scrollTopItem < 0)
return true;
- if (scrollTopItem == 0 && scrollTopPixel == 0)
- return true;
-
- return false;
+ return (scrollTopItem == 0 && scrollTopPixel == 0);
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -270,7 +267,7 @@ void NewstoryListData::BeginEditItem() mir_subclassWindow(hwndEditBox, HistoryEditWndProc);
SendMessage(hwndEditBox, WM_SETFONT, (WPARAM)g_fontTable[fontid].hfnt, 0);
SendMessage(hwndEditBox, EM_SETMARGINS, EC_RIGHTMARGIN, 100);
- if (item->dbe.eventType != EVENTTYPE_MESSAGE || !(item->dbe.flags & DBEF_SENT))
+ if (item->dbe.eventType != EVENTTYPE_MESSAGE || !item->dbe.bSent)
SendMessage(hwndEditBox, EM_SETREADONLY, TRUE, 0);
ShowWindow(hwndEditBox, SW_SHOW);
@@ -411,7 +408,7 @@ void NewstoryListData::DeleteItems(void) for (int i = totalCount - 1; i >= 0; i--) {
auto *pItem = GetItem(i);
if (pItem->m_bSelected) {
- if ((pItem->dbe.flags & DBEF_SENT) == 0)
+ if (!pItem->dbe.bSent)
bIncoming = true;
nSelected++;
}
@@ -419,6 +416,7 @@ void NewstoryListData::DeleteItems(void) CDeleteEventsDlg dlg(m_hContact, nSelected, bIncoming);
if (IDOK == dlg.DoModal()) {
+ int iSaveCount = totalCount;
g_plugin.bDisableDelete = true;
int firstSel = -1, flags = 0;
@@ -440,6 +438,8 @@ void NewstoryListData::DeleteItems(void) }
g_plugin.bDisableDelete = false;
+ if (iSaveCount != totalCount)
+ PostMessage(GetParent(m_hwnd), UM_UPDATE_WINDOW, 0, 0);
if (firstSel != -1) {
SetCaret(firstSel, false);
@@ -459,7 +459,7 @@ void NewstoryListData::DeliverEvent(MCONTACT hContact, MEVENT hEvent) for (int i = totalCount - 1; i >= 0; i--) {
auto *pItem = GetItem(i);
- if (pItem->dbe.hContact != hContact || !(pItem->dbe.flags & DBEF_SENT))
+ if (pItem->dbe.hContact != hContact || !pItem->dbe.bSent)
continue;
if (pItem->dbe.getEvent() == hEvent)
@@ -499,11 +499,12 @@ void NewstoryListData::EndEditItem(bool bAccept) pItem->wtext[iTextLen] = 0;
if (pItem->dbe.hContact && pItem->dbe.getEvent()) {
- DBEVENTINFO dbei = pItem->dbe;
+ DB::EventInfo dbei(pItem->dbe.getEvent());
ptrA szUtf(mir_utf8encodeW(pItem->wtext));
dbei.cbBlob = (int)mir_strlen(szUtf) + 1;
- dbei.pBlob = szUtf.get();
+ dbei.pBlob = szUtf.detach();
+ dbei.bEdited = true;
db_event_edit(pItem->dbe.getEvent(), &dbei);
}
@@ -729,6 +730,18 @@ void NewstoryListData::OpenFolder() /////////////////////////////////////////////////////////////////////////////////////////
// Painting
+static void recursive_set_color(element::ptr el, const web_color &fore, const background &back)
+{
+ el->css_w().set_bg(back);
+ el->css_w().set_color(fore);
+
+ for (auto &it : el->children()) {
+ if (it->tag() == _a_ || (it->tag() == _font_ && mir_strcmp(it->get_attr("class"), "body")))
+ continue;
+ recursive_set_color(it, fore, back);
+ }
+}
+
void NewstoryListData::Paint(simpledib::dib &dib)
{
int top = 0;
@@ -780,7 +793,8 @@ void NewstoryListData::Paint(simpledib::dib &dib) SetBkMode(dib, TRANSPARENT);
// left offset of icons & text
- int xPos = 2, yPos = top + 2, xRight = 0, yOffset = 0;
+ bool bDrawProgress = false;
+ int xPos = 2, yPos = top + 2, xRight = 0;
if (!bReadOnly) {
HICON hIcon;
@@ -804,7 +818,7 @@ void NewstoryListData::Paint(simpledib::dib &dib) if (g_plugin.bShowType) {
switch (pItem->dbe.eventType) {
case EVENTTYPE_MESSAGE:
- hIcon = g_plugin.getIcon(IDI_SENDMSG);
+ hIcon = Skin_LoadIcon(SKINICON_EVENT_MESSAGE);
break;
case EVENTTYPE_FILE:
hIcon = Skin_LoadIcon(SKINICON_EVENT_FILE);
@@ -818,20 +832,22 @@ void NewstoryListData::Paint(simpledib::dib &dib) }
DrawIconEx(dib, xPos, yPos, hIcon, 16, 16, 0, 0, DI_NORMAL);
xPos += 18;
+ IcoLib_ReleaseIcon(hIcon);
}
// Direction icon
if (g_plugin.bShowDirection) {
- if (pItem->dbe.flags & DBEF_SENT)
+ if (pItem->dbe.bSent)
hIcon = g_plugin.getIcon(IDI_MSGOUT);
else
hIcon = g_plugin.getIcon(IDI_MSGIN);
DrawIconEx(dib, xPos, yPos, hIcon, 16, 16, 0, 0, DI_NORMAL);
xPos += 18;
+ IcoLib_ReleaseIcon(hIcon);
}
// Bookmark icon
- if (pItem->dbe.flags & DBEF_BOOKMARK) {
+ if (pItem->dbe.isBookmark) {
DrawIconEx(dib, xPos, yPos, g_plugin.getIcon(IDI_BOOKMARK), 16, 16, 0, 0, DI_NORMAL);
xPos += 18;
}
@@ -839,37 +855,48 @@ void NewstoryListData::Paint(simpledib::dib &dib) // Finished icon
if (pItem->m_bOfflineDownloaded != 0) {
if (pItem->completed())
- DrawIconEx(dib, cachedWindowWidth - (xRight = 20), yPos, g_plugin.getIcon(IDI_OK), 16, 16, 0, 0, DI_NORMAL);
- else {
- HPEN hpn = (HPEN)SelectObject(dib, CreatePen(PS_SOLID, 4, g_colorTable[COLOR_PROGRESS].cl));
- MoveToEx(dib, rc.left, rc.bottom - 4, 0);
- LineTo(dib, rc.left + (rc.right - rc.left) * int(pItem->m_bOfflineDownloaded) / 100, rc.bottom - 4);
- DeleteObject(SelectObject(dib, hpn));
- yOffset = 4;
- }
+ DrawIconEx(dib, cachedWindowWidth - (xRight = 18), yPos, g_plugin.getIcon(IDI_OK), 16, 16, 0, 0, DI_NORMAL);
+ else
+ bDrawProgress = true;
}
// Delivered & remote read icons
if (pItem->m_bRemoteRead)
- DrawIconEx(dib, cachedWindowWidth - (xRight = 20), yPos, g_plugin.getIcon(IDI_REMOTEREAD), 16, 16, 0, 0, DI_NORMAL);
+ DrawIconEx(dib, cachedWindowWidth - (xRight = 18), yPos, g_plugin.getIcon(IDI_REMOTEREAD), 16, 16, 0, 0, DI_NORMAL);
else if (pItem->m_bDelivered)
- DrawIconEx(dib, cachedWindowWidth - (xRight = 20), yPos, g_plugin.getIcon(IDI_DELIVERED), 16, 16, 0, 0, DI_NORMAL);
+ DrawIconEx(dib, cachedWindowWidth - (xRight = 18), yPos, g_plugin.getIcon(IDI_DELIVERED), 16, 16, 0, 0, DI_NORMAL);
+
+ // Edited icon
+ if (pItem->dbe.bEdited) {
+ xRight += 18;
+ DrawIconEx(dib, cachedWindowWidth - xRight, yPos, g_plugin.getIcon(IDI_SENDMSG), 16, 16, 0, 0, DI_NORMAL);
+ }
}
// draw html itself
- litehtml::position clip(xPos, yPos, cachedWindowWidth - xPos - xRight, iItemHeigth - yOffset);
+ litehtml::position clip(xPos, yPos, cachedWindowWidth - xPos - xRight, iItemHeigth);
if (auto &pDoc = pItem->m_doc) {
if (auto pBody = pDoc->root()->select_one("body")) {
- litehtml::background back = pBody->css().get_bg();
- back.m_color = litehtml::web_color(GetRValue(clBack), GetGValue(clBack), GetBValue(clBack));
- pBody->css_w().set_bg(back);
+ if (auto pBbody = pBody->select_one("[id=bbody]")) {
+ litehtml::background back = pBbody->css().get_bg();
+ back.m_color = litehtml::web_color(GetRValue(clBack), GetGValue(clBack), GetBValue(clBack));
- pBody->css_w().set_color(litehtml::web_color(GetRValue(clText), GetGValue(clText), GetBValue(clText)));
+ litehtml::web_color fore(GetRValue(clText), GetGValue(clText), GetBValue(clText));
+ recursive_set_color(pBbody, fore, back);
+ }
}
pDoc->draw((UINT_PTR)dib.hdc(), xPos, yPos + iOffsetY, &clip);
}
+ // draw progress
+ if (bDrawProgress) {
+ HPEN hpn = (HPEN)SelectObject(dib, CreatePen(PS_SOLID, 4, g_colorTable[COLOR_PROGRESS].cl));
+ MoveToEx(dib, rc.left, rc.bottom - 4, 0);
+ LineTo(dib, rc.left + (rc.right - rc.left) * int(pItem->m_bOfflineDownloaded) / 100, rc.bottom - 4);
+ DeleteObject(SelectObject(dib, hpn));
+ }
+
// draw border
HPEN hpn = (HPEN)SelectObject(dib, CreatePen(PS_SOLID, 1, clLine));
MoveToEx(dib, rc.left, rc.bottom - 1, 0);
@@ -964,7 +991,7 @@ void NewstoryListData::RemoteRead(MCONTACT hContact, MEVENT hEvent) if (!pItem->m_bLoaded)
pItem->fetch();
- if (pItem->dbe.hContact != hContact || !(pItem->dbe.flags & DBEF_SENT))
+ if (pItem->dbe.hContact != hContact || !pItem->dbe.bSent)
continue;
if (pItem->dbe.getEvent() == hEvent)
@@ -1010,19 +1037,6 @@ void NewstoryListData::SetCaret(int idx, bool bEnsureVisible) }
}
-void NewstoryListData::SetContact(MCONTACT hContact)
-{
- m_hContact = hContact;
-
- WindowList_Add(g_hNewstoryLogs, m_hwnd, hContact);
-}
-
-void NewstoryListData::SetDialog(CSrmmBaseDialog *pDlg)
-{
- if (pMsgDlg = pDlg)
- SetContact(pDlg->m_hContact);
-}
-
void NewstoryListData::SetPos(int pos)
{
SetSelection((selStart == -1) ? pos : selStart, pos);
@@ -1128,7 +1142,7 @@ void NewstoryListData::TryUp(int iCount) for (int j = 0; j < i + 1; j++)
if (auto *pItem = GetItem(j)) {
pItem->fetch();
- if (pItem->dbe.flags & DBEF_SENT)
+ if (pItem->dbe.bSent)
pItem->m_bRemoteRead = hasRead;
pPrev = pItem->checkNext(pPrev);
}
@@ -1323,7 +1337,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM int eventCount = data->totalCount;
for (int i = 0; i < eventCount; i++) {
auto *p = data->GetItem(i);
- if (p->dbe.timestamp >= wParam) {
+ if (p->dbe.getUnixtime() >= wParam) {
data->SetSelection(i, i);
data->SetCaret(i);
break;
@@ -1470,57 +1484,62 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM if (msg == WM_KEYUP)
break;
+ int oldCaret = data->caret;
switch (wParam) {
case VK_UP:
- if (g_plugin.bHppCompat)
+ if (g_plugin.bHppCompat) {
data->EventUp();
- else
- data->LineUp();
- if (isShift)
- data->SetSelection(data->scrollTopItem, data->caret);
+ if (isShift)
+ data->AddSelection(data->caret, oldCaret);
+ }
+ else data->LineUp();
break;
case VK_DOWN:
- if (g_plugin.bHppCompat)
+ if (g_plugin.bHppCompat) {
data->EventDown();
- else
- data->LineDown();
- if (isShift)
- data->SetSelection(data->scrollTopItem, data->caret);
+ if (isShift)
+ data->AddSelection(oldCaret, data->caret);
+ }
+ else data->LineDown();
break;
case VK_PRIOR:
if (isCtrl)
data->ScrollTop();
- else if (g_plugin.bHppCompat)
- data->EventPageUp();
- else
- data->PageUp();
- if (isShift)
- data->SetSelection(data->scrollTopItem, data->caret);
+ else {
+ if (g_plugin.bHppCompat) {
+ data->EventPageUp();
+ if (isShift)
+ data->AddSelection(data->caret, oldCaret);
+ }
+ else data->PageUp();
+ }
break;
case VK_NEXT:
if (isCtrl)
data->ScrollBottom();
- else if (g_plugin.bHppCompat)
- data->EventPageDown();
- else
- data->PageDown();
- if (isShift)
- data->SetSelection(data->scrollTopItem, data->caret);
+ else {
+ if (g_plugin.bHppCompat) {
+ data->EventPageDown();
+ if (isShift)
+ data->AddSelection(oldCaret, data->caret);
+ }
+ else data->PageDown();
+ }
break;
case VK_HOME:
data->ScrollTop();
if (isShift)
- data->SetSelection(0, data->caret);
+ data->AddSelection(0, data->caret);
break;
case VK_END:
data->ScrollBottom();
if (isShift)
- data->SetSelection(data->caret, data->totalCount);
+ data->AddSelection(data->caret, data->totalCount);
break;
case VK_F2:
@@ -1715,7 +1734,6 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM break;
case WM_DESTROY:
- WindowList_Remove(g_hNewstoryLogs, hwnd);
delete data;
SetWindowLongPtr(hwnd, 0, 0);
break;
diff --git a/plugins/NewStory/src/history_control.h b/plugins/NewStory/src/history_control.h index 5c26afb970..4fcc518096 100644 --- a/plugins/NewStory/src/history_control.h +++ b/plugins/NewStory/src/history_control.h @@ -21,7 +21,7 @@ class NSWebPage : public document_container std::string resolve_color(const string &color) const;
uint_ptr get_image(LPCWSTR url_or_path, bool redraw_on_ready);
- void get_client_rect(position &client) const override;
+ void get_viewport(litehtml::position &) const override;
void import_css(string &text, const string &url, string &baseurl) override;
void on_anchor_click(const char *url, const element::ptr &el) override;
void set_base_url(const char *base_url) override;
@@ -32,7 +32,7 @@ class NSWebPage : public document_container void get_img_size(uint_ptr img, size &sz);
// document_container members
- uint_ptr create_font(const char *faceName, int size, int weight, font_style italic, unsigned int decoration, font_metrics *fm) override;
+ uint_ptr create_font(const font_description &descr, const document *doc, font_metrics *fm) override;
void delete_font(uint_ptr hFont) override;
const char* get_default_font_name() const override;
int get_default_font_size() const override;
@@ -174,8 +174,6 @@ struct NewstoryListData : public MZeroedObject void ScrollTop();
void ScrollUp(int deltaY);
void SetCaret(int idx, bool bEnsureVisible = true);
- void SetContact(MCONTACT hContact);
- void SetDialog(CSrmmBaseDialog *pDialog);
void SetPos(int pos);
void SetSelection(int iFirst, int iLast);
void ToggleBookmark();
diff --git a/plugins/NewStory/src/history_dlg.cpp b/plugins/NewStory/src/history_dlg.cpp index eb239d100e..85dcd9ea5d 100644 --- a/plugins/NewStory/src/history_dlg.cpp +++ b/plugins/NewStory/src/history_dlg.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
@@ -165,7 +165,7 @@ class CHistoryDlg : public CDlgBase CharLowerW(pwszText);
if (wcsstr(pwszText, pwszPattern))
- m_arResults.insert(new SearchResult(hContact, hDbEvent, dbei.timestamp));
+ m_arResults.insert(new SearchResult(hContact, hDbEvent, dbei.getUnixtime()));
}
}
@@ -295,25 +295,25 @@ class CHistoryDlg : public CDlgBase auto &pArray = m_histCtrl->items;
int numItems = pArray.getCount();
- int CurYear = 0, CurMonth = 0, CurDay = 0, PrevYear = -1, PrevMonth = -1, PrevDay = -1;
+ int PrevYear = -1, PrevMonth = -1, PrevDay = -1;
HTREEITEM hCurYear = 0, hCurMonth = 0, hCurDay = 0;
for (int i = 0; i < numItems; i++) {
auto *pItem = pArray.get(i, false);
if (!pItem->fetch())
continue;
- if (pItem->dbe.timestamp == 0)
+ if (pItem->dbe.iTimestamp == 0)
continue;
struct tm ts = { 0 };
- time_t timestamp = pItem->dbe.timestamp;
+ time_t timestamp = pItem->dbe.getUnixtime();
errno_t err = localtime_s(&ts, ×tamp); /* statically alloced, local time correction */
if (err != 0)
return;
- CurYear = ts.tm_year + 1900;
- CurMonth = ts.tm_mon + 1;
- CurDay = ts.tm_mday;
+ int CurYear = ts.tm_year + 1900;
+ int CurMonth = ts.tm_mon + 1;
+ int CurDay = ts.tm_mday;
wchar_t buf[50];
TVINSERTSTRUCT tvi;
tvi.hParent = nullptr;
@@ -321,14 +321,14 @@ class CHistoryDlg : public CDlgBase if (CurYear != PrevYear) {
_itow(CurYear, buf, 10);
tvi.item.pszText = buf;
- tvi.item.lParam = CurYear;
+ tvi.item.lParam = CurYear * 100 * 100;
hCurYear = TreeView_InsertItem(m_timeTree.GetHwnd(), &tvi);
PrevYear = CurYear;
}
if (CurMonth != PrevMonth) {
tvi.hParent = hCurYear;
tvi.item.pszText = TranslateW(months[CurMonth - 1]);
- tvi.item.lParam = CurMonth;
+ tvi.item.lParam = (CurYear * 100 + CurMonth) * 100;
hCurMonth = TreeView_InsertItem(m_timeTree.GetHwnd(), &tvi);
PrevMonth = CurMonth;
}
@@ -336,11 +336,12 @@ class CHistoryDlg : public CDlgBase _itow(CurDay, buf, 10);
tvi.hParent = hCurMonth;
tvi.item.pszText = buf;
- tvi.item.lParam = CurDay;
+ tvi.item.lParam = (CurYear * 100 + CurMonth) * 100 + CurDay;
hCurDay = TreeView_InsertItem(m_timeTree.GetHwnd(), &tvi);
PrevDay = CurDay;
}
}
+
disableTimeTreeChange = true;
HTREEITEM root = m_timeTree.GetRoot();
m_timeTree.SelectItem(root);
@@ -349,9 +350,6 @@ class CHistoryDlg : public CDlgBase HTREEITEM FindSibling(HTREEITEM root, int value)
{
if (root) {
- if (value < 1000)
- root = m_timeTree.GetChild(root);
-
for (HTREEITEM hti = root; hti; hti = m_timeTree.GetNextSibling(hti)) {
TVITEMEX tvi;
tvi.mask = TVIF_PARAM;
@@ -372,9 +370,13 @@ class CHistoryDlg : public CDlgBase if (err != 0)
return;
- HTREEITEM hti = FindSibling(m_timeTree.GetRoot(), ts.tm_year + 1900);
- hti = FindSibling(hti, ts.tm_mon + 1);
- hti = FindSibling(hti, ts.tm_mday);
+ int iValue = (ts.tm_year + 1900) * 100 * 100;
+ HTREEITEM hti = FindSibling(m_timeTree.GetRoot(), iValue);
+
+ iValue += (ts.tm_mon + 1) * 100;
+ hti = FindSibling(m_timeTree.GetChild(hti), iValue);
+
+ hti = FindSibling(m_timeTree.GetChild(hti), iValue + ts.tm_mday);
if (hti) {
disableTimeTreeChange = true;
m_timeTree.SelectItem(hti);
@@ -433,7 +435,7 @@ public: m_toolbar.push_back(Button(btnTimeTree));
m_toolbar.push_back(Button(btnBookmarks));
m_toolbar.push_back(Button(btnSearch));
- m_toolbar.push_back(Button(btnFilter));
+ // m_toolbar.push_back(Button(btnFilter));
m_toolbar.push_back(Button(btnCalendar, Button::SPACED));
m_toolbar.push_back(Button(btnCopy));
m_toolbar.push_back(Button(btnDelete));
@@ -489,6 +491,7 @@ public: // filterbar
btnFilter.MakePush();
+ btnFilter.Hide();
btnTimeTree.MakePush();
if (m_dwOptions & WND_OPT_TIMETREE)
@@ -568,8 +571,6 @@ public: // Ask for layout
PostMessage(m_hwnd, WM_SIZE, 0, 0);
- WindowList_Add(g_hNewstoryWindows, m_hwnd, m_hContact);
-
ShowHideControls();
UpdateTitle();
@@ -584,6 +585,11 @@ public: if (m_hContact != INVALID_CONTACT_ID) {
Utils_RestoreWindowPosition(m_hwnd, m_hContact, MODULENAME, "wnd_");
+ WindowList_Add(g_hNewstoryWindows, m_hwnd, m_hContact);
+
+ m_histCtrl->m_hContact = m_hContact;
+ WindowList_Add(g_hNewstoryHistLogs, m_histCtrl->m_hwnd, m_hContact);
+
m_histCtrl->AddEvent(m_hContact, 0, -1);
BuildTimeTree();
@@ -594,7 +600,6 @@ public: OnResize();
BuildBookmarksList();
- m_histCtrl->SetContact(m_hContact);
m_histCtrl->ScrollBottom();
Window_SetIcon_IcoLib(m_hwnd, g_plugin.getIconHandle(IDI_NEWSTORY));
@@ -798,6 +803,7 @@ public: Window_FreeIcon_IcoLib(m_hwnd);
WindowList_Remove(g_hNewstoryWindows, m_hwnd);
+ WindowList_Remove(g_hNewstoryHistLogs, m_histCtrl->m_hwnd);
if (m_hwndStatus != nullptr) {
DestroyWindow(m_hwndStatus);
@@ -1153,7 +1159,12 @@ public: case UM_LOCATETIME:
if (m_dwOptions & WND_OPT_TIMETREE)
if (auto *pItem = m_histCtrl->GetItem(wParam))
- LocateDateTime(pItem->dbe.timestamp);
+ LocateDateTime(pItem->dbe.getUnixtime());
+ break;
+
+ case UM_UPDATE_WINDOW:
+ UpdateTitle();
+ BuildTimeTree();
break;
}
@@ -1180,62 +1191,25 @@ public: void onSelChanged_TimeTree(CCtrlTreeView::TEventInfo *)
{
- wchar_t *val1, *val2, *val3;
- int yearsel = 0, monthsel = 0, daysel = 1;
- bool monthfound = false;
- if (disableTimeTreeChange)
+ if (disableTimeTreeChange) {
disableTimeTreeChange = false;
- else {
- HTREEITEM hti1 = m_timeTree.GetSelection();
- TVITEMEX tvi = { 0 };
- tvi.hItem = hti1;
- tvi.mask = TVIF_HANDLE | TVIF_TEXT | TVIF_PARAM;
- tvi.cchTextMax = MAX_PATH;
- tvi.lParam = 0;
- tvi.pszText = (wchar_t *)_alloca(MAX_PATH * sizeof(wchar_t));
-
- m_timeTree.GetItem(&tvi);
- val1 = tvi.pszText;
- if (tvi.lParam) {
- monthsel = tvi.lParam;
- monthfound = true;
- }
- HTREEITEM hti2 = m_timeTree.GetParent(hti1);
- if ((!monthfound) && (!hti2))
- yearsel = _wtoi(val1);
- if ((!monthfound) && (hti2))
- daysel = _wtoi(val1);
- if (hti2) {
- tvi.hItem = hti2;
- tvi.lParam = 0;
- m_timeTree.GetItem(&tvi);
- val2 = tvi.pszText;
- if (tvi.lParam) {
- monthsel = tvi.lParam;
- monthfound = true;
- }
- else
- yearsel = _wtoi(val2);
- HTREEITEM hti3 = m_timeTree.GetParent(hti2);
- if (hti3) {
- tvi.hItem = hti3;
- tvi.lParam = 0;
- m_timeTree.GetItem(&tvi);
- val3 = tvi.pszText;
- yearsel = _wtoi(val3);
- }
- }
- struct tm tm_sel;
- tm_sel.tm_hour = tm_sel.tm_min = tm_sel.tm_sec = 0;
- tm_sel.tm_isdst = 1;
- tm_sel.tm_mday = daysel;
- if (monthsel)
- tm_sel.tm_mon = monthsel - 1;
- else
- tm_sel.tm_mon = 0;
- tm_sel.tm_year = yearsel - 1900;
- PostMessage(m_hwnd, WM_USER + 0x600, mktime(&tm_sel), 0);
+ return;
}
+
+ HTREEITEM hti1 = m_timeTree.GetSelection();
+ TVITEMEX tvi = {};
+ tvi.hItem = hti1;
+ tvi.mask = TVIF_HANDLE | TVIF_PARAM;
+ m_timeTree.GetItem(&tvi);
+
+ struct tm tm_sel = {};
+ tm_sel.tm_isdst = 1;
+ tm_sel.tm_mday = tvi.lParam % 100; tvi.lParam /= 100;
+ tm_sel.tm_mon = tvi.lParam % 100;
+ if (tm_sel.tm_mon)
+ tm_sel.tm_mon--;
+ tm_sel.tm_year = tvi.lParam / 100 - 1900;
+ PostMessage(m_hwnd, WM_USER + 0x600, mktime(&tm_sel), 0);
}
};
diff --git a/plugins/NewStory/src/history_log.cpp b/plugins/NewStory/src/history_log.cpp index 4221a1a56e..a49b53eaff 100644 --- a/plugins/NewStory/src/history_log.cpp +++ b/plugins/NewStory/src/history_log.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
@@ -37,12 +37,21 @@ public: 0, 0, rc.left - rc.right, rc.bottom - rc.top, m_pDlg.GetHwnd(), 0, m_pDlg.GetInst(), 0);
m_histCtrl = (NewstoryListData *)GetWindowLongPtr(m_hwnd, 0);
- m_histCtrl->SetDialog(&m_pDlg);
+ m_histCtrl->pMsgDlg = &m_pDlg;
+ m_histCtrl->m_hContact = m_pDlg.m_hContact;
+ WindowList_Add(g_hNewstoryLogs, m_hwnd, m_histCtrl->m_hContact);
+
+ DB::ECPTR pCursor(DB::Events(m_pDlg.m_hContact, db_event_firstUnread(m_pDlg.m_hContact)));
+ while (MEVENT hDbEvent = pCursor.FetchNext()) {
+ DB::EventInfo dbei(hDbEvent, false);
+ if (dbei && !dbei.bRead)
+ m_pDlg.MarkEventRead(dbei);
+ }
}
void Detach() override
{
- WindowList_Remove(g_hNewstoryLogs, m_pDlg.GetHwnd());
+ WindowList_Remove(g_hNewstoryLogs, m_hwnd);
::DestroyWindow(m_hwnd);
}
diff --git a/plugins/NewStory/src/history_menus.cpp b/plugins/NewStory/src/history_menus.cpp index d8db517b34..74e3f3c525 100644 --- a/plugins/NewStory/src/history_menus.cpp +++ b/plugins/NewStory/src/history_menus.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
@@ -61,7 +61,7 @@ HMENU NSMenu_Build(NewstoryListData *data, ItemData *item) else if (mir_strlen(item->getUrl()))
Menu_ShowItem(hmiCopyUrl, true);
- bEditable = (item->dbe.flags & DBEF_SENT) != 0;
+ bEditable = item->dbe.bSent;
bShowEventActions = item->dbe.getEvent() != 0;
DB::EventInfo dbei(item->dbe.getEvent());
@@ -242,8 +242,7 @@ void InitMenus() hMenuObject = Menu_AddObject("NSMenu", "NewStory item menu", nullptr, "NSMenu/ExecService");
Menu_ConfigureObject(hMenuObject, MCO_OPT_USERDEFINEDITEMS, INT_PTR(FALSE));
- Menu_ConfigureObject(hMenuObject, MCO_OPT_FREE_SERVICE, INT_PTR("NSMenu/FreeOwnerData"));
- Menu_ConfigureObject(hMenuObject, MCO_OPT_ONADD_SERVICE, INT_PTR("NSMenu/OnAddService"));
+ Menu_ConfigureObject(hMenuObject, MCO_OPT_FREE_SERVICE, "NSMenu/FreeOwnerData");
CMenuItem mi(&g_plugin);
mi.pszService = "NSMenu/Helper";
diff --git a/plugins/NewStory/src/history_svc.cpp b/plugins/NewStory/src/history_svc.cpp index fa8771bb7f..2fd39daeca 100644 --- a/plugins/NewStory/src/history_svc.cpp +++ b/plugins/NewStory/src/history_svc.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
diff --git a/plugins/NewStory/src/main.cpp b/plugins/NewStory/src/main.cpp index f271bf1f40..cb03cebe7d 100644 --- a/plugins/NewStory/src/main.cpp +++ b/plugins/NewStory/src/main.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
@@ -38,7 +38,7 @@ CMOption<uint32_t> g_clCustom4(MODULENAME, "CustomColor4", -1); CMOption<int> g_iPreviewHeight(MODULENAME, "PreviewHeight", 300);
-MWindowList g_hNewstoryWindows = 0, g_hNewstoryLogs = 0;
+MWindowList g_hNewstoryWindows = 0, g_hNewstoryLogs = 0, g_hNewstoryHistLogs = 0;
/////////////////////////////////////////////////////////////////////////////////////////
@@ -188,6 +188,7 @@ int CMPlugin::Load() g_hNewstoryLogs = WindowList_Create();
g_hNewstoryWindows = WindowList_Create();
+ g_hNewstoryHistLogs = WindowList_Create();
HookEvent(ME_DB_EVENT_ADDED, evtEventAdded);
HookEvent(ME_DB_EVENT_DELETED, evtEventDeleted);
@@ -208,6 +209,7 @@ int CMPlugin::Unload() {
WindowList_Destroy(g_hNewstoryLogs);
WindowList_Destroy(g_hNewstoryWindows);
+ WindowList_Destroy(g_hNewstoryHistLogs);
GdiplusShutdown(m_gdiplusToken);
diff --git a/plugins/NewStory/src/options.cpp b/plugins/NewStory/src/options.cpp index 7098909ecd..5c2b4c1238 100644 --- a/plugins/NewStory/src/options.cpp +++ b/plugins/NewStory/src/options.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
@@ -33,6 +33,7 @@ protected: void OnFinish(void *)
{
WindowList_BroadcastAsync(g_hNewstoryLogs, NSM_SET_OPTIONS, 0, 0);
+ WindowList_BroadcastAsync(g_hNewstoryHistLogs, NSM_SET_OPTIONS, 0, 0);
}
};
@@ -147,7 +148,7 @@ public: m_tempItem->dbe.flags = DBEF_TEMPORARY | DBEF_BOOKMARK;
m_tempItem->dbe.szModule = MODULENAME;
m_tempItem->dbe.eventType = EVENTTYPE_MESSAGE;
- m_tempItem->dbe.timestamp = time(0);
+ m_tempItem->dbe.iTimestamp = time(0);
m_histCtrl->totalCount++;
HTREEITEM hGroup = 0, hFirst = 0;
diff --git a/plugins/NewStory/src/stdafx.cxx b/plugins/NewStory/src/stdafx.cxx index d714e70110..aa565d1100 100644 --- a/plugins/NewStory/src/stdafx.cxx +++ b/plugins/NewStory/src/stdafx.cxx @@ -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
diff --git a/plugins/NewStory/src/stdafx.h b/plugins/NewStory/src/stdafx.h index a0edec01c5..729d79369e 100644 --- a/plugins/NewStory/src/stdafx.h +++ b/plugins/NewStory/src/stdafx.h @@ -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
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)
diff --git a/plugins/NewStory/src/templates.h b/plugins/NewStory/src/templates.h index ad16b646ef..2a460d1cc9 100644 --- a/plugins/NewStory/src/templates.h +++ b/plugins/NewStory/src/templates.h @@ -16,7 +16,7 @@ struct TemplateVars return vars[id].val;
}
- void SetNick(wchar_t *v);
+ void SetNick(wchar_t *v, ItemData *item);
void SetVar(uint8_t id, wchar_t *v, bool d);
};
diff --git a/plugins/NewStory/src/utils.cpp b/plugins/NewStory/src/utils.cpp index f6aca92604..b8b5369451 100644 --- a/plugins/NewStory/src/utils.cpp +++ b/plugins/NewStory/src/utils.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
@@ -49,19 +49,29 @@ Bitmap* LoadImageFromResource(HINSTANCE hInst, int resourceId, const wchar_t *pw /////////////////////////////////////////////////////////////////////////////////////////
-int SmartSendEvent(int iEventType, MCONTACT hContact, LPARAM hEvent)
+static void SmartSendEventWorker(MWindowList wndList, int iEventType, MCONTACT cc1, MCONTACT cc2, MEVENT hEvent)
{
- if (HWND hwnd = WindowList_Find(g_hNewstoryLogs, hContact))
- SendMessage(hwnd, iEventType, hContact, hEvent);
+ if (HWND hwnd = WindowList_Find(wndList, cc1))
+ PostMessage(hwnd, iEventType, cc1, hEvent);
- if (db_mc_isMeta(hContact)) {
- // Send a message to a real contact too
+ if (cc2 != INVALID_CONTACT_ID)
+ if (HWND hwnd = WindowList_Find(wndList, cc2))
+ PostMessage(hwnd, iEventType, cc2, hEvent);
+}
+
+int SmartSendEvent(int iEventType, MCONTACT cc1, MEVENT hEvent)
+{
+ MCONTACT cc2 = INVALID_CONTACT_ID;
+
+ // Send a message to a real contact too
+ if (db_mc_isMeta(cc1)) {
MCONTACT cc = db_event_getContact(hEvent);
- if (cc != hContact)
- if (HWND hwnd = WindowList_Find(g_hNewstoryLogs, cc))
- SendMessage(hwnd, iEventType, cc, hEvent);
+ if (cc != cc1)
+ cc2 = cc;
}
+ SmartSendEventWorker(g_hNewstoryLogs, iEventType, cc1, cc2, hEvent);
+ SmartSendEventWorker(g_hNewstoryHistLogs, iEventType, cc1, cc2, hEvent);
return 0;
}
@@ -194,6 +204,9 @@ static int DetectUrl(const wchar_t *text) void UrlAutodetect(CMStringW &str)
{
+ if (str.IsEmpty())
+ return;
+
int level = 0;
for (auto *p = str.c_str(); *p; p++) {
diff --git a/plugins/NewStory/src/utils.h b/plugins/NewStory/src/utils.h index 1858c34d9c..7ebc0a4980 100644 --- a/plugins/NewStory/src/utils.h +++ b/plugins/NewStory/src/utils.h @@ -14,4 +14,4 @@ void RemoveBbcodes(CMStringW &pwszText); Bitmap* LoadImageFromResource(HINSTANCE, int, const wchar_t *);
-int SmartSendEvent(int iEvent, MCONTACT hContact, LPARAM lParam);
+int SmartSendEvent(int iEvent, MCONTACT hContact, MEVENT lParam);
diff --git a/plugins/NewStory/src/version.h b/plugins/NewStory/src/version.h index deec274fc5..36c1c6656e 100644 --- a/plugins/NewStory/src/version.h +++ b/plugins/NewStory/src/version.h @@ -10,4 +10,4 @@ #define __DESCRIPTION "History viewer for Miranda NG."
#define __AUTHOR "nullbie"
#define __AUTHORWEB "https://miranda-ng.org/p/NewStory"
-#define __COPYRIGHT "© 2005 Victor Pavlychko, 2012-24 Miranda NG team"
+#define __COPYRIGHT "© 2005 Victor Pavlychko, 2012-25 Miranda NG team"
diff --git a/plugins/NewStory/src/webpage.cpp b/plugins/NewStory/src/webpage.cpp index e0453db41b..955e45d368 100644 --- a/plugins/NewStory/src/webpage.cpp +++ b/plugins/NewStory/src/webpage.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 @@ -186,11 +186,11 @@ static void trim_quotes(std::string &str) str.erase(str.length() - 1, 1); } -uint_ptr NSWebPage::create_font(const char *font_list, int size, int weight, font_style italic, unsigned int decoration, font_metrics *fm) +uint_ptr NSWebPage::create_font(const font_description &descr, const document *, font_metrics *fm) { std::wstring font_name; string_vector fonts; - split_string(font_list, fonts, ","); + split_string(descr.family, fonts, ","); bool found = false; for (auto &name : fonts) { trim(name); @@ -208,15 +208,15 @@ uint_ptr NSWebPage::create_font(const char *font_list, int size, int weight, fon LOGFONT lf = {}; wcscpy_s(lf.lfFaceName, LF_FACESIZE, font_name.c_str()); - lf.lfHeight = -size; - lf.lfWeight = weight; - lf.lfItalic = (italic == font_style_italic) ? TRUE : FALSE; + lf.lfHeight = -descr.size; + lf.lfWeight = descr.weight; + lf.lfItalic = (descr.style == font_style_italic) ? TRUE : FALSE; lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; - lf.lfStrikeOut = (decoration & font_decoration_linethrough) ? TRUE : FALSE; - lf.lfUnderline = (decoration & font_decoration_underline) ? TRUE : FALSE; + lf.lfStrikeOut = (descr.decoration_line & text_decoration_line_line_through) ? TRUE : FALSE; + lf.lfUnderline = (descr.decoration_line & text_decoration_line_underline) ? TRUE : FALSE; HFONT hFont = CreateFontIndirect(&lf); if (fm) { @@ -227,7 +227,7 @@ uint_ptr NSWebPage::create_font(const char *font_list, int size, int weight, fon fm->descent = tm.tmDescent; fm->height = tm.tmHeight; fm->x_height = tm.tmHeight / 2; // this is an estimate; call GetGlyphOutline to get the real value - fm->draw_spaces = italic || decoration; + fm->draw_spaces = lf.lfItalic || descr.decoration_line; } return (uint_ptr)hFont; @@ -449,7 +449,7 @@ element::ptr NSWebPage::create_element(const char *, const string_map &, const d void NSWebPage::get_media_features(media_features &media) const { position client; - get_client_rect(client); + get_viewport(client); media.type = media_type_screen; media.width = client.width; @@ -718,7 +718,7 @@ uint_ptr NSWebPage::get_image(LPCWSTR url_or_path, bool) return (uint_ptr)pImage; } -void NSWebPage::get_client_rect(position &pos) const +void NSWebPage::get_viewport(position &pos) const { pos = size(ctrl.cachedWindowWidth, ctrl.cachedWindowHeight); } |