summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2024-03-20 17:15:58 +0300
committerGeorge Hazan <george.hazan@gmail.com>2024-03-20 17:15:58 +0300
commit210010f8ec3aaa180d29937ca22119fba5ecaeed (patch)
treeeca09f815f62d61de722b5084a1b631abb615a0b /plugins
parent78b05a9a69927af0bcad6d88036bc8b9d58dc152 (diff)
NewStory: first html-based version which looks more or less like RTF version
Diffstat (limited to 'plugins')
-rw-r--r--plugins/NewStory/NewStory.vcxproj30
-rw-r--r--plugins/NewStory/NewStory.vcxproj.filters23
-rw-r--r--plugins/NewStory/src/dib.cpp176
-rw-r--r--plugins/NewStory/src/dib.h40
-rw-r--r--plugins/NewStory/src/history_array.cpp118
-rw-r--r--plugins/NewStory/src/history_array.h17
-rw-r--r--plugins/NewStory/src/history_control.cpp309
-rw-r--r--plugins/NewStory/src/history_control.h30
-rw-r--r--plugins/NewStory/src/main.cpp2
-rw-r--r--plugins/NewStory/src/options.cpp13
-rw-r--r--plugins/NewStory/src/stdafx.cxx4
-rw-r--r--plugins/NewStory/src/stdafx.h18
-rw-r--r--plugins/NewStory/src/templates.cpp146
-rw-r--r--plugins/NewStory/src/webpage.cpp63
14 files changed, 686 insertions, 303 deletions
diff --git a/plugins/NewStory/NewStory.vcxproj b/plugins/NewStory/NewStory.vcxproj
index cfb8c75c47..9df881d8b1 100644
--- a/plugins/NewStory/NewStory.vcxproj
+++ b/plugins/NewStory/NewStory.vcxproj
@@ -18,11 +18,6 @@
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\..\libs\mTextControl\mtextcontrol.vcxproj">
- <Project>{e26d2311-c164-48cf-ba24-5ceda873d1b2}</Project>
- </ProjectReference>
- </ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>NewStory</ProjectName>
<ProjectGuid>{A7FAD273-8C71-4D72-A84F-2D160F2DC589}</ProjectGuid>
@@ -30,8 +25,27 @@
<ImportGroup Label="PropertySheets">
<Import Project="$(ProjectDir)..\..\build\vc.common\plugin.props" />
</ImportGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>.\src;../../libs/litehtml/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DisableSpecificWarnings>4458;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ </ItemDefinitionGroup>
<ItemGroup>
+ <ClCompile Include="..\..\libs\litehtml\containers\cairo\cairo_borders.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\libs\litehtml\containers\cairo\container_cairo.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\libs\litehtml\containers\windows\cairo\cairo_font.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\libs\litehtml\containers\windows\cairo\windows_container.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
<ClCompile Include="src\calendartool.cpp" />
+ <ClCompile Include="src\dib.cpp" />
<ClCompile Include="src\fonts.cpp" />
<ClCompile Include="src\history_array.cpp" />
<ClCompile Include="src\history_control.cpp" />
@@ -39,6 +53,7 @@
<ClCompile Include="src\history_log.cpp" />
<ClCompile Include="src\history_menus.cpp" />
<ClCompile Include="src\history_svc.cpp" />
+ <ClCompile Include="src\webpage.cpp" />
<ClCompile Include="src\main.cpp" />
<ClCompile Include="src\options.cpp" />
<ClCompile Include="src\stdafx.cxx">
@@ -62,4 +77,9 @@
<ResourceCompile Include="res\resource.rc" />
<ResourceCompile Include="res\Version.rc" />
</ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\libs\litehtml\litehtml.vcxproj">
+ <Project>{51db004a-e160-47c7-b017-bec90fdc442d}</Project>
+ </ProjectReference>
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/plugins/NewStory/NewStory.vcxproj.filters b/plugins/NewStory/NewStory.vcxproj.filters
index 72e30edc11..83fc3b22e0 100644
--- a/plugins/NewStory/NewStory.vcxproj.filters
+++ b/plugins/NewStory/NewStory.vcxproj.filters
@@ -41,6 +41,24 @@
<ClCompile Include="src\history_svc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\libs\litehtml\containers\cairo\container_cairo.cpp">
+ <Filter>Source Files\Litehtml</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libs\litehtml\containers\windows\cairo\cairo_font.cpp">
+ <Filter>Source Files\Litehtml</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libs\litehtml\containers\windows\cairo\windows_container.cpp">
+ <Filter>Source Files\Litehtml</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libs\litehtml\containers\cairo\cairo_borders.cpp">
+ <Filter>Source Files\Litehtml</Filter>
+ </ClCompile>
+ <ClCompile Include="src\webpage.cpp">
+ <Filter>Source Files\Litehtml</Filter>
+ </ClCompile>
+ <ClCompile Include="src\dib.cpp">
+ <Filter>Source Files\Litehtml</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\calendartool.h">
@@ -85,4 +103,9 @@
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
+ <ItemGroup>
+ <Filter Include="Source Files\Litehtml">
+ <UniqueIdentifier>{b1a3b930-2ec1-4ee0-8a76-0d65fecddd00}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/plugins/NewStory/src/dib.cpp b/plugins/NewStory/src/dib.cpp
new file mode 100644
index 0000000000..c54ef944fa
--- /dev/null
+++ b/plugins/NewStory/src/dib.cpp
@@ -0,0 +1,176 @@
+#include "stdafx.h"
+
+simpledib::dib::dib()
+{
+ memset(this, 0, sizeof(*this));
+}
+
+simpledib::dib::~dib()
+{
+ destroy();
+}
+
+void simpledib::dib::destroy(bool del_bmp)
+{
+ if (m_hdc && m_ownData) {
+ SelectObject(m_hdc, m_oldBmp);
+ if (del_bmp)
+ DeleteObject(m_bmp);
+ DeleteDC(m_hdc);
+ }
+ else if (m_restore_view_port && m_hdc) {
+ ::SetWindowOrgEx(m_hdc, m_oldViewPort.x, m_oldViewPort.y, NULL);
+ }
+
+ memset(this, 0, sizeof(*this));
+}
+
+bool simpledib::dib::create(int width, int height, bool topdowndib)
+{
+ destroy();
+
+ BITMAPINFO bmp_info;
+ bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmp_info.bmiHeader.biWidth = width;
+ bmp_info.bmiHeader.biHeight = height * (topdowndib ? -1 : 1);
+ bmp_info.bmiHeader.biPlanes = 1;
+ bmp_info.bmiHeader.biBitCount = 32;
+ bmp_info.bmiHeader.biCompression = BI_RGB;
+ bmp_info.bmiHeader.biSizeImage = 0;
+ bmp_info.bmiHeader.biXPelsPerMeter = 0;
+ bmp_info.bmiHeader.biYPelsPerMeter = 0;
+ bmp_info.bmiHeader.biClrUsed = 0;
+ bmp_info.bmiHeader.biClrImportant = 0;
+
+ m_hdc = CreateCompatibleDC(NULL);
+
+ m_bmp = ::CreateDIBSection(m_hdc, &bmp_info, DIB_RGB_COLORS, (LPVOID *)&m_bits, 0, 0);
+ if (m_bits && m_bmp) {
+ m_oldBmp = (HBITMAP)::SelectObject(m_hdc, m_bmp);
+ }
+ else {
+ DeleteDC(m_hdc);
+ m_hdc = nullptr;
+ }
+
+ if (!m_hdc)
+ return false;
+
+ m_width = width;
+ m_height = height;
+ m_ownData = true;
+ return true;
+}
+
+/*
+bool simpledib::dib::create( HDC hdc, HBITMAP bmp, LPRGBQUAD bits, int width, int height, int shift_x, int shift_y )
+{
+ destroy();
+
+ m_bmp = bmp;
+ m_hdc = hdc;
+ m_bits = bits;
+ m_width = width;
+ m_height = height;
+ m_ownData = FALSE;
+
+ SetWindowOrgEx(m_hdc, -shift_x, -shift_y, &m_oldViewPort);
+ m_restore_view_port = TRUE;
+ return true;
+}
+
+*/
+bool simpledib::dib::create(HDC hdc, HBITMAP bmp, LPRGBQUAD bits, int width, int height)
+{
+ destroy();
+
+ m_bmp = bmp;
+ m_hdc = hdc;
+ m_bits = bits;
+ m_width = width;
+ m_height = height;
+ m_ownData = m_restore_view_port = false;
+ return true;
+}
+
+void simpledib::dib::clear()
+{
+ if (m_bits)
+ memset(m_bits, 0, m_width * m_height * 4);
+}
+
+void simpledib::dib::draw(HDC hdc, int x, int y)
+{
+ BLENDFUNCTION bf;
+ bf.BlendOp = AC_SRC_OVER;
+ bf.BlendFlags = 0;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ bf.SourceConstantAlpha = 255;
+
+ AlphaBlend(hdc, x, y, m_width, m_height, m_hdc, 0, 0, m_width, m_height, bf);
+}
+
+void simpledib::dib::draw(HDC hdc, LPRECT rcDraw)
+{
+ BLENDFUNCTION bf;
+ bf.BlendOp = AC_SRC_OVER;
+ bf.BlendFlags = 0;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ bf.SourceConstantAlpha = 255;
+
+ AlphaBlend(hdc,
+ rcDraw->left, rcDraw->top,
+ rcDraw->right - rcDraw->left,
+ rcDraw->bottom - rcDraw->top, m_hdc,
+
+ rcDraw->left, rcDraw->top,
+ rcDraw->right - rcDraw->left,
+ rcDraw->bottom - rcDraw->top,
+ bf);
+}
+
+HDC simpledib::dib::beginPaint(HDC hdc, LPRECT rcDraw)
+{
+ if (!create(rcDraw->right - rcDraw->left, rcDraw->bottom - rcDraw->top, true))
+ return nullptr;
+
+ m_hTargetDC = hdc;
+ m_rcTarget = *rcDraw;
+ SetWindowOrgEx(m_hdc, rcDraw->left, rcDraw->top, &m_oldViewPort);
+ return m_hdc;
+}
+
+void simpledib::dib::endPaint(bool copy)
+{
+ SetWindowOrgEx(m_hdc, m_oldViewPort.x, m_oldViewPort.y, NULL);
+
+ if (!copy) {
+ BLENDFUNCTION bf = {};
+ bf.BlendOp = AC_SRC_OVER;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ bf.SourceConstantAlpha = 255;
+
+ AlphaBlend(m_hTargetDC, m_rcTarget.left, m_rcTarget.top,
+ m_rcTarget.right - m_rcTarget.left,
+ m_rcTarget.bottom - m_rcTarget.top, m_hdc,
+ 0, 0,
+ m_rcTarget.right - m_rcTarget.left,
+ m_rcTarget.bottom - m_rcTarget.top,
+ bf);
+ }
+ else {
+ BitBlt(m_hTargetDC, m_rcTarget.left, m_rcTarget.top,
+ m_rcTarget.right - m_rcTarget.left,
+ m_rcTarget.bottom - m_rcTarget.top, m_hdc, 0, 0, SRCCOPY);
+ }
+
+ m_hTargetDC = NULL;
+ destroy();
+}
+
+HBITMAP simpledib::dib::detach_bitmap()
+{
+ HBITMAP bmp = m_bmp;
+ destroy(false);
+ return bmp;
+}
diff --git a/plugins/NewStory/src/dib.h b/plugins/NewStory/src/dib.h
new file mode 100644
index 0000000000..62e6051d9e
--- /dev/null
+++ b/plugins/NewStory/src/dib.h
@@ -0,0 +1,40 @@
+#pragma once
+
+namespace simpledib
+{
+ class dib
+ {
+ HBITMAP m_bmp;
+ HBITMAP m_oldBmp;
+ HDC m_hdc;
+ LPRGBQUAD m_bits;
+ int m_width, m_height;
+
+ HDC m_hTargetDC;
+ POINT m_oldViewPort;
+ bool m_restore_view_port = false, m_ownData = false;
+ RECT m_rcTarget;
+
+ public:
+ dib();
+ ~dib();
+
+ __forceinline int width() const { return m_width; }
+ __forceinline int height() const { return m_height; }
+ __forceinline HDC hdc() const { return m_hdc; }
+ __forceinline HBITMAP bmp() const { return m_bmp; }
+ __forceinline LPRGBQUAD bits() const { return m_bits; }
+ __forceinline operator HDC() { return m_hdc; }
+
+ bool create(int width, int height, bool topdowndib = false);
+ bool create(HDC hdc, HBITMAP bmp, LPRGBQUAD bits, int width, int height);
+
+ void clear();
+ void destroy(bool del_bmp = true);
+ void draw(HDC hdc, int x, int y);
+ void draw(HDC hdc, LPRECT rcDraw);
+ HDC beginPaint(HDC hdc, LPRECT rcDraw);
+ void endPaint(bool copy = false);
+ HBITMAP detach_bitmap();
+ };
+}
diff --git a/plugins/NewStory/src/history_array.cpp b/plugins/NewStory/src/history_array.cpp
index 8fbcee0ed9..a22708743e 100644
--- a/plugins/NewStory/src/history_array.cpp
+++ b/plugins/NewStory/src/history_array.cpp
@@ -18,8 +18,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
-extern HANDLE htuLog;
-
/////////////////////////////////////////////////////////////////////////////////////////
// Filters
@@ -82,8 +80,6 @@ ItemData::~ItemData()
mir_free(wtext);
if (dbe.szReplyId)
mir_free((char*)dbe.szReplyId);
- if (data)
- MTextDestroy(data);
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -101,7 +97,7 @@ static bool isEqual(const ItemData *p1, const ItemData *p2)
return true;
}
-ItemData* ItemData::checkPrev(ItemData *pPrev, HWND hwnd)
+ItemData* ItemData::checkPrev(ItemData *pPrev)
{
m_grouping = GROUPING_NONE;
if (!pPrev || !g_plugin.bMsgGrouping)
@@ -118,7 +114,7 @@ ItemData* ItemData::checkPrev(ItemData *pPrev, HWND hwnd)
if (pPrev->m_grouping == GROUPING_NONE) {
pPrev->m_grouping = GROUPING_HEAD;
if (pPrev->m_bLoaded)
- pPrev->setText(hwnd);
+ pPrev->setText();
}
m_grouping = GROUPING_ITEM;
}
@@ -127,7 +123,7 @@ ItemData* ItemData::checkPrev(ItemData *pPrev, HWND hwnd)
/////////////////////////////////////////////////////////////////////////////////////////
-ItemData* ItemData::checkNext(ItemData *pPrev, HWND hwnd)
+ItemData* ItemData::checkNext(ItemData *pPrev)
{
m_grouping = GROUPING_NONE;
if (!pPrev || !g_plugin.bMsgGrouping)
@@ -145,11 +141,11 @@ ItemData* ItemData::checkNext(ItemData *pPrev, HWND hwnd)
if (pPrev->m_grouping == GROUPING_NONE) {
pPrev->m_grouping = GROUPING_HEAD;
if (pPrev->m_bLoaded)
- pPrev->setText(hwnd);
+ pPrev->setText();
}
m_grouping = GROUPING_ITEM;
if (m_bLoaded)
- setText(hwnd);
+ setText();
}
return this;
}
@@ -172,7 +168,7 @@ static bool isEqualGC(const ItemData *p1, const ItemData *p2)
return true;
}
-ItemData* ItemData::checkPrevGC(ItemData *pPrev, HWND hwnd)
+ItemData* ItemData::checkPrevGC(ItemData *pPrev)
{
m_grouping = GROUPING_NONE;
if (!pPrev || !g_plugin.bMsgGrouping)
@@ -185,7 +181,7 @@ ItemData* ItemData::checkPrevGC(ItemData *pPrev, HWND hwnd)
if (pPrev->m_grouping == GROUPING_NONE) {
pPrev->m_grouping = GROUPING_HEAD;
if (pPrev->m_bLoaded)
- pPrev->setText(hwnd);
+ pPrev->setText();
}
m_grouping = GROUPING_ITEM;
}
@@ -194,61 +190,44 @@ ItemData* ItemData::checkPrevGC(ItemData *pPrev, HWND hwnd)
/////////////////////////////////////////////////////////////////////////////////////////
-void ItemData::checkCreate(HWND hwnd)
+int ItemData::calcHeight(int top, int width, POINT *pPos)
{
- if (data == nullptr) {
- setText(hwnd);
- MTextSetParent(data, hwnd);
- MTextActivate(data, true);
- }
-}
+ checkCreate();
-bool ItemData::isLink(HWND hwnd, POINT pt, CMStringW *pwszUrl) const
-{
- int cp = MTextSendMessage(0, data, EM_CHARFROMPOS, 0, LPARAM(&pt));
- if (cp == -1)
- return false;
+ SIZE sz;
+ sz.cx = width - 2;
- if (!isLinkChar(hwnd, cp))
- return false;
+ POINT pos;
+ pos.x = 2;
+ pos.y = top + 2;
- if (pwszUrl) {
- CHARRANGE sel = { cp, cp };
- while (isLinkChar(hwnd, sel.cpMin-1))
- sel.cpMin--;
-
- while (isLinkChar(hwnd, sel.cpMax))
- sel.cpMax++;
-
- if (sel.cpMax > sel.cpMin) {
- pwszUrl->Truncate(sel.cpMax - sel.cpMin + 1);
-
- TEXTRANGE tr = { 0 };
- tr.chrg = sel;
- tr.lpstrText = pwszUrl->GetBuffer();
- int iRes = MTextSendMessage(0, data, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
- if (iRes > 0)
- pwszUrl->Trim();
- else
- pwszUrl->Empty();
- }
+ if (g_plugin.bShowType) // Message type icon
+ pos.x += 18;
+
+ if (g_plugin.bShowDirection) // Message direction icon
+ pos.x += 18;
+
+ if (dbe.flags & DBEF_BOOKMARK) // Bookmark icon
+ pos.x += 18;
+
+ sz.cx -= pos.x;
+ if (m_bOfflineDownloaded != 0) // Download completed icon
+ sz.cx -= 18;
+
+ if (savedHeight == -1) {
+ m_doc->render(sz.cx);
+ savedHeight = m_doc->height();
}
- return true;
+
+ if (pPos)
+ *pPos = pos;
+ return savedHeight + 5;
}
-bool ItemData::isLinkChar(HWND hwnd, int idx) const
+void ItemData::checkCreate()
{
- if (idx < 0)
- return false;
-
- CHARRANGE sel = { idx, idx + 1 };
- MTextSendMessage(hwnd, data, EM_EXSETSEL, 0, LPARAM(&sel));
-
- CHARFORMAT2 cf = {};
- cf.cbSize = sizeof(cf);
- cf.dwMask = CFM_LINK;
- uint32_t res = MTextSendMessage(hwnd, data, EM_GETCHARFORMAT, SCF_SELECTION, LPARAM(&cf));
- return ((res & CFM_LINK) && (cf.dwEffects & CFE_LINK)) || ((res & CFM_REVISED) && (cf.dwEffects & CFE_REVISED));
+ if (m_doc == nullptr)
+ setText();
}
bool ItemData::fetch(void)
@@ -475,14 +454,11 @@ void ItemData::load(bool bLoadAlways)
dbe.unload();
}
-void ItemData::setText(HWND hwnd)
+void ItemData::setText()
{
- if (data)
- MTextDestroy(data);
-
- data = MTextCreateEx2(hwnd, htuLog, formatRtf().GetBuffer(), MTEXT_FLG_RTF);
- MTextSetProto(data, hContact);
- savedHeight = -1;
+ m_doc = litehtml::document::createFromString(formatHtml(), &pOwner->webPage);
+ m_doc->render(pOwner->cachedWindowWidth);
+ savedHeight = m_doc->height();
}
// Array
@@ -559,7 +535,7 @@ void HistoryArray::addChatEvent(NewstoryListData *pOwner, SESSION_INFO *si, cons
if (lin->ptszNick) {
addNick(p, lin->ptszNick);
- p.checkPrevGC((numItems == 0) ? nullptr : get(numItems - 1), hwndOwner);
+ p.checkPrevGC((numItems == 0) ? nullptr : get(numItems - 1));
}
}
@@ -582,9 +558,9 @@ bool HistoryArray::addEvent(NewstoryListData *pOwner, MCONTACT hContact, MEVENT
p.dbe = hEvent;
if (si) {
checkGC(p, si);
- pPrev = p.checkPrevGC(pPrev, hwndOwner);
+ pPrev = p.checkPrevGC(pPrev);
}
- else pPrev = p.checkPrev(pPrev, hwndOwner);
+ else pPrev = p.checkPrev(pPrev);
}
else {
DB::ECPTR pCursor(DB::Events(hContact, hEvent));
@@ -599,9 +575,9 @@ bool HistoryArray::addEvent(NewstoryListData *pOwner, MCONTACT hContact, MEVENT
p.dbe = hEvent;
if (si) {
checkGC(p, si);
- pPrev = p.checkPrevGC(pPrev, hwndOwner);
+ pPrev = p.checkPrevGC(pPrev);
}
- else pPrev = p.checkPrev(pPrev, hwndOwner);
+ else pPrev = p.checkPrev(pPrev);
}
}
@@ -628,7 +604,7 @@ void HistoryArray::addResults(NewstoryListData *pOwner, const OBJLIST<SearchResu
p.hContact = it->hContact;
p.dbe = it->hEvent;
p.m_bIsResult = true;
- pPrev = p.checkPrev(pPrev, hwndOwner);
+ pPrev = p.checkPrev(pPrev);
}
}
diff --git a/plugins/NewStory/src/history_array.h b/plugins/NewStory/src/history_array.h
index 00482f76c2..f5a39ba5bd 100644
--- a/plugins/NewStory/src/history_array.h
+++ b/plugins/NewStory/src/history_array.h
@@ -26,29 +26,28 @@ struct ItemData
wchar_t *wszNick;
struct NewstoryListData *pOwner;
- HText data;
+ litehtml::document::ptr m_doc;
ItemData();
~ItemData();
- ItemData* checkNext(ItemData *pPrev, HWND hwnd);
- ItemData* checkPrev(ItemData *pPrev, HWND hwnd);
- ItemData* checkPrevGC(ItemData *pPrev, HWND hwnd);
- void checkCreate(HWND hwnd);
- void setText(HWND hwnd);
+ ItemData* checkNext(ItemData *pPrev);
+ ItemData* checkPrev(ItemData *pPrev);
+ ItemData* checkPrevGC(ItemData *pPrev);
+ void checkCreate();
+ int calcHeight(int top, int width, POINT *pPos = nullptr);
bool completed() const { return m_bOfflineDownloaded == 100; }
bool fetch(void);
void fill(int tmpl);
void load(bool bLoad = false);
- bool isLink(HWND, POINT pt, CMStringW *url = nullptr) const;
- bool isLinkChar(HWND, int idx) const;
+ void setText();
int getTemplate() const;
int getCopyTemplate() const;
void getFontColor(int &fontId, int &colorId) const;
- CMStringA formatRtf(const wchar_t *pwszStr = 0);
+ CMStringA formatHtml(const wchar_t *pwszStr = 0);
CMStringW formatString() { return TplFormatString(getTemplate(), hContact, this); }
CMStringW formatStringEx(wchar_t *sztpl);
diff --git a/plugins/NewStory/src/history_control.cpp b/plugins/NewStory/src/history_control.cpp
index 2aafa3e58c..ee714e2771 100644
--- a/plugins/NewStory/src/history_control.cpp
+++ b/plugins/NewStory/src/history_control.cpp
@@ -20,8 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define AVERAGE_ITEM_HEIGHT 100
-HANDLE htuLog = 0;
-
void InitHotkeys()
{
HOTKEYDESC hkd = {};
@@ -57,6 +55,7 @@ void InitHotkeys()
NewstoryListData::NewstoryListData(HWND _1) :
m_hwnd(_1),
+ webPage(*this),
redrawTimer(Miranda_GetSystemWindow(), LPARAM(this))
{
items.setOwner(_1);
@@ -89,6 +88,11 @@ void NewstoryListData::OnContextMenu(int index, POINT pt)
void NewstoryListData::OnResize(int newWidth, int newHeight)
{
+ if (dib.width() < newWidth || dib.height() < newHeight) {
+ dib.destroy();
+ dib.create(newWidth, newHeight, true);
+ }
+
bool bDraw = false;
if (newWidth != cachedWindowWidth) {
cachedWindowWidth = newWidth;
@@ -137,8 +141,8 @@ void NewstoryListData::AddResults(const OBJLIST<SearchResult> &results)
void NewstoryListData::AddSelection(int iFirst, int iLast)
{
- int start = min(totalCount - 1, iFirst);
- int end = min(totalCount - 1, max(0, iLast));
+ int start = std::min(totalCount - 1, iFirst);
+ int end = std::min(totalCount - 1, std::max(0, iLast));
if (start > end)
std::swap(start, end);
@@ -247,7 +251,7 @@ void NewstoryListData::BeginEditItem()
if (itemHeight > height)
dwStyle |= WS_VSCROLL;
- hwndEditBox = CreateWindow(L"EDIT", wszText, dwStyle, 0, top, width, min(height, itemHeight), m_hwnd, NULL, g_plugin.getInst(), NULL);
+ hwndEditBox = CreateWindow(L"EDIT", wszText, dwStyle, 0, top, width, std::min(height, itemHeight), m_hwnd, NULL, g_plugin.getInst(), NULL);
mir_subclassWindow(hwndEditBox, HistoryEditWndProc);
SendMessage(hwndEditBox, WM_SETFONT, (WPARAM)g_fontTable[fontid].hfnt, 0);
SendMessage(hwndEditBox, EM_SETMARGINS, EC_RIGHTMARGIN, 100);
@@ -276,7 +280,7 @@ void NewstoryListData::Clear()
void NewstoryListData::ClearSelection(int iFirst, int iLast)
{
- int start = min(0, iFirst);
+ int start = std::min(0, iFirst);
int end = (iLast <= 0) ? totalCount - 1 : iLast;
if (start > end)
std::swap(start, end);
@@ -436,9 +440,9 @@ void NewstoryListData::EndEditItem(bool bAccept)
db_event_edit(pItem->dbe.getEvent(), &dbei);
}
- MTextDestroy(pItem->data); pItem->data = 0;
+ pItem->m_doc = 0;
pItem->savedHeight = -1;
- pItem->checkCreate(m_hwnd);
+ pItem->checkCreate();
}
}
@@ -581,11 +585,8 @@ int NewstoryListData::GetItemHeight(int index)
int NewstoryListData::GetItemHeight(ItemData *pItem)
{
- if (pItem->savedHeight == -1) {
- HDC hdc = GetDC(m_hwnd);
- pItem->savedHeight = PaintItem(hdc, pItem, 0, cachedWindowWidth, false);
- ReleaseDC(m_hwnd, hdc);
- }
+ if (pItem->savedHeight == -1)
+ pItem->savedHeight = pItem->calcHeight(0, cachedWindowWidth);
return pItem->savedHeight;
}
@@ -648,130 +649,142 @@ void NewstoryListData::OpenFolder()
}
}
-int NewstoryListData::PaintItem(HDC hdc, ItemData *pItem, int top, int width, bool bDraw)
+/////////////////////////////////////////////////////////////////////////////////////////
+// Painting
+
+void NewstoryListData::Paint(simpledib::dib &dib, RECT *rcDraw)
{
- // remove any selections that might be created by the BBCodes parser
- MTextSendMessage(m_hwnd, pItem->data, EM_SETSEL, 0, 0);
+ cairo_surface_t *surface = cairo_image_surface_create_for_data((unsigned char *)dib.bits(), CAIRO_FORMAT_ARGB32, dib.width(), dib.height(), dib.width() * 4);
+ cairo_t *cr = cairo_create(surface);
- // LOGFONT lfText;
- COLORREF clText, clBack, clLine;
- int fontid, colorid;
- pItem->getFontColor(fontid, colorid);
+ cairo_rectangle(cr, rcDraw->left, rcDraw->top, rcDraw->right - rcDraw->left, rcDraw->bottom - rcDraw->top);
+ cairo_clip(cr);
- clText = g_fontTable[fontid].cl;
- if (pItem->m_bHighlighted) {
- clText = g_fontTable[FONT_HIGHLIGHT].cl;
- clBack = g_colorTable[COLOR_HIGHLIGHT_BACK].cl;
- clLine = g_colorTable[COLOR_FRAME].cl;
- }
- else if (pItem->m_bSelected) {
- clText = g_colorTable[COLOR_SELTEXT].cl;
- clBack = g_colorTable[COLOR_SELBACK].cl;
- clLine = g_colorTable[COLOR_SELFRAME].cl;
- }
- else {
- clLine = g_colorTable[COLOR_FRAME].cl;
- clBack = g_colorTable[colorid].cl;
- }
+ cairo_set_source_rgb(cr, 1, 1, 1);
+ cairo_paint(cr);
- pItem->checkCreate(m_hwnd);
+ int top = scrollTopPixel;
- SIZE sz;
- sz.cx = width - 2;
+ int idx;
+ for (idx = scrollTopItem; top < cachedWindowHeight && idx < totalCount; idx++) {
+ if (hwndEditBox && caret == idx)
+ continue;
- POINT pos;
- pos.x = 2;
- pos.y = top + 2;
+ auto *pItem = LoadItem(idx);
- if (g_plugin.bShowType) // Message type icon
- pos.x += 18;
+ POINT pos;
+ int height = pItem->calcHeight(top, cachedWindowWidth, &pos);
- if (g_plugin.bShowDirecction) // Message direction icon
- pos.x += 18;
+ COLORREF clText, clBack, clLine;
+ int fontid, colorid;
+ pItem->getFontColor(fontid, colorid);
- if (pItem->dbe.flags & DBEF_BOOKMARK) // Bookmark icon
- pos.x += 18;
+ if (pItem->m_bHighlighted) {
+ clText = g_fontTable[FONT_HIGHLIGHT].cl;
+ clBack = g_colorTable[COLOR_HIGHLIGHT_BACK].cl;
+ clLine = g_colorTable[COLOR_FRAME].cl;
+ }
+ else if (pItem->m_bSelected) {
+ clText = g_colorTable[COLOR_SELTEXT].cl;
+ clBack = g_colorTable[COLOR_SELBACK].cl;
+ clLine = g_colorTable[COLOR_SELFRAME].cl;
+ }
+ else {
+ clText = g_fontTable[fontid].cl;
+ clLine = g_colorTable[COLOR_FRAME].cl;
+ clBack = g_colorTable[colorid].cl;
+ }
- sz.cx -= pos.x;
- if (pItem->m_bOfflineDownloaded != 0) // Download completed icon
- sz.cx -= 18;
+ HBRUSH hbr = CreateSolidBrush(clBack);
+ RECT rc = { 0, top, cachedWindowWidth, top + height };
+ FillRect(dib, &rc, hbr);
+ DeleteObject(hbr);
- HFONT hfnt = (HFONT)SelectObject(hdc, g_fontTable[fontid].hfnt);
- MTextMeasure(hdc, &sz, pItem->data);
- SelectObject(hdc, hfnt);
+ SetTextColor(dib, clText);
+ SetBkMode(dib, TRANSPARENT);
- int height = sz.cy + 5;
- if (!bDraw)
- return height;
+ pos.x = 2;
+ HICON hIcon;
- HBRUSH hbr = CreateSolidBrush(clBack);
- RECT rc = { 0, top, width, top + height };
- FillRect(hdc, &rc, hbr);
- DeleteObject(hbr);
+ // Message type icon
+ if (g_plugin.bShowType) {
+ switch (pItem->dbe.eventType) {
+ case EVENTTYPE_MESSAGE:
+ hIcon = g_plugin.getIcon(IDI_SENDMSG);
+ break;
+ case EVENTTYPE_FILE:
+ hIcon = Skin_LoadIcon(SKINICON_EVENT_FILE);
+ break;
+ case EVENTTYPE_STATUSCHANGE:
+ hIcon = g_plugin.getIcon(IDI_SIGNIN);
+ break;
+ default:
+ hIcon = g_plugin.getIcon(IDI_UNKNOWN);
+ break;
+ }
+ DrawIconEx(dib, pos.x, pos.y, hIcon, 16, 16, 0, 0, DI_NORMAL);
+ pos.x += 18;
+ }
- SetTextColor(hdc, clText);
- SetBkMode(hdc, TRANSPARENT);
+ // Direction icon
+ if (g_plugin.bShowDirection) {
+ if (pItem->dbe.flags & DBEF_SENT)
+ hIcon = g_plugin.getIcon(IDI_MSGOUT);
+ else
+ hIcon = g_plugin.getIcon(IDI_MSGIN);
+ DrawIconEx(dib, pos.x, pos.y, hIcon, 16, 16, 0, 0, DI_NORMAL);
+ pos.x += 18;
+ }
- pos.x = 2;
- HICON hIcon;
-
- // Message type icon
- if (g_plugin.bShowType) {
- switch (pItem->dbe.eventType) {
- case EVENTTYPE_MESSAGE:
- hIcon = g_plugin.getIcon(IDI_SENDMSG);
- break;
- case EVENTTYPE_FILE:
- hIcon = Skin_LoadIcon(SKINICON_EVENT_FILE);
- break;
- case EVENTTYPE_STATUSCHANGE:
- hIcon = g_plugin.getIcon(IDI_SIGNIN);
- break;
- default:
- hIcon = g_plugin.getIcon(IDI_UNKNOWN);
- break;
+ // Bookmark icon
+ if (pItem->dbe.flags & DBEF_BOOKMARK) {
+ DrawIconEx(dib, pos.x, pos.y, g_plugin.getIcon(IDI_BOOKMARK), 16, 16, 0, 0, DI_NORMAL);
+ pos.x += 18;
}
- DrawIconEx(hdc, pos.x, pos.y, hIcon, 16, 16, 0, 0, DI_NORMAL);
- pos.x += 18;
- }
- // Direction icon
- if (g_plugin.bShowDirecction) {
- if (pItem->dbe.flags & DBEF_SENT)
- hIcon = g_plugin.getIcon(IDI_MSGOUT);
- else
- hIcon = g_plugin.getIcon(IDI_MSGIN);
- DrawIconEx(hdc, pos.x, pos.y, hIcon, 16, 16, 0, 0, DI_NORMAL);
- pos.x += 18;
- }
+ // Finished icon
+ if (pItem->m_bOfflineDownloaded != 0) {
+ if (pItem->completed())
+ DrawIconEx(dib, cachedWindowWidth - 20, pos.y, 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));
+ }
+ }
- // Bookmark icon
- if (pItem->dbe.flags & DBEF_BOOKMARK) {
- DrawIconEx(hdc, pos.x, pos.y, g_plugin.getIcon(IDI_BOOKMARK), 16, 16, 0, 0, DI_NORMAL);
- pos.x += 18;
- }
+ HFONT hfnt = (HFONT)SelectObject(dib, g_fontTable[fontid].hfnt);
+ litehtml::position clip(pos.x, pos.y, cachedWindowWidth - pos.x, height);
+ pItem->m_doc->draw((UINT_PTR)cr, pos.x, pos.y, &clip);
+ SelectObject(dib, hfnt);
- // Finished icon
- if (pItem->m_bOfflineDownloaded != 0) {
- if (pItem->completed())
- DrawIconEx(hdc, width - 20, pos.y, g_plugin.getIcon(IDI_OK), 16, 16, 0, 0, DI_NORMAL);
- else {
- HPEN hpn = (HPEN)SelectObject(hdc, CreatePen(PS_SOLID, 4, g_colorTable[COLOR_PROGRESS].cl));
- MoveToEx(hdc, rc.left, rc.bottom - 4, 0);
- LineTo(hdc, rc.left + (rc.right - rc.left) * int(pItem->m_bOfflineDownloaded) / 100, rc.bottom - 4);
- DeleteObject(SelectObject(hdc, hpn));
- }
+ HPEN hpn = (HPEN)SelectObject(dib, CreatePen(PS_SOLID, 1, clLine));
+ MoveToEx(dib, rc.left, rc.bottom - 1, 0);
+ LineTo(dib, rc.right, rc.bottom - 1);
+ DeleteObject(SelectObject(dib, hpn));
+
+ top += height;
}
- hfnt = (HFONT)SelectObject(hdc, g_fontTable[fontid].hfnt);
- MTextDisplay(hdc, pos, sz, pItem->data);
- SelectObject(hdc, hfnt);
+ cachedMaxDrawnItem = idx;
+
+ if (top <= cachedWindowHeight) {
+ RECT rc2;
+ SetRect(&rc2, 0, top, cachedWindowWidth, cachedWindowHeight);
+
+ HBRUSH hbr = CreateSolidBrush(g_colorTable[COLOR_BACK].cl);
+ FillRect(dib, &rc2, hbr);
+ DeleteObject(hbr);
+ }
- HPEN hpn = (HPEN)SelectObject(hdc, CreatePen(PS_SOLID, 1, clLine));
- MoveToEx(hdc, rc.left, rc.bottom - 1, 0);
- LineTo(hdc, rc.right, rc.bottom - 1);
- DeleteObject(SelectObject(hdc, hpn));
- return height;
+ if (g_plugin.bOptVScroll)
+ RecalcScrollBar();
+
+ if (g_plugin.bDrawEdge) {
+ RECT rc = { 0, 0, cachedWindowWidth, cachedWindowHeight };
+ DrawEdge(dib, &rc, BDR_SUNKENOUTER, BF_RECT);
+ }
}
void NewstoryListData::RecalcScrollBar()
@@ -868,8 +881,8 @@ void NewstoryListData::SetPos(int pos)
void NewstoryListData::SetSelection(int iFirst, int iLast)
{
- int start = min(totalCount - 1, iFirst);
- int end = min(totalCount - 1, max(0, iLast));
+ int start = std::min(totalCount - 1, iFirst);
+ int end = std::min(totalCount - 1, std::max(0, iLast));
if (start > end)
std::swap(start, end);
@@ -899,7 +912,7 @@ void NewstoryListData::ToggleBookmark()
p->dbe.flags |= DBEF_BOOKMARK;
db_event_edit(p->dbe.getEvent(), &p->dbe);
- p->setText(m_hwnd);
+ p->setText();
}
InvalidateRect(m_hwnd, 0, FALSE);
@@ -907,8 +920,8 @@ void NewstoryListData::ToggleBookmark()
void NewstoryListData::ToggleSelection(int iFirst, int iLast)
{
- int start = min(totalCount - 1, iFirst);
- int end = min(totalCount - 1, max(0, iLast));
+ int start = std::min(totalCount - 1, iFirst);
+ int end = std::min(totalCount - 1, std::max(0, iLast));
if (start > end)
std::swap(start, end);
@@ -946,7 +959,7 @@ void NewstoryListData::TryUp(int iCount)
ItemData *pPrev = nullptr;
for (int j = 0; j < i + 1; j++) {
auto *pItem = GetItem(j);
- pPrev = pItem->checkNext(pPrev, m_hwnd);
+ pPrev = pItem->checkNext(pPrev);
}
caret = 0;
@@ -1174,7 +1187,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
if (idx != -1) {
auto *p = data->GetItem(idx);
p->load(true);
- p->setText(data->m_hwnd);
+ p->setText();
InvalidateRect(hwnd, 0, FALSE);
}
break;
@@ -1207,40 +1220,14 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
we'll just ignore them */
if (IsWindowVisible(hwnd)) {
PAINTSTRUCT ps;
- HDC hdcWindow = BeginPaint(hwnd, &ps);
-
- RECT rc;
- GetClientRect(hwnd, &rc);
-
- HDC hdc = CreateCompatibleDC(hdcWindow);
- HBITMAP hbmSave = (HBITMAP)SelectObject(hdc, CreateCompatibleBitmap(hdcWindow, rc.right - rc.left, rc.bottom - rc.top));
-
- int height = rc.bottom - rc.top;
- int width = rc.right - rc.left;
- int top = data->scrollTopPixel;
-
- for (idx = data->scrollTopItem; top < height && idx < data->totalCount; idx++)
- top += data->PaintItem(hdc, data->LoadItem(idx), top, width, !data->hwndEditBox || data->caret != idx);
-
- data->cachedMaxDrawnItem = idx;
-
- if (top <= height) {
- RECT rc2;
- SetRect(&rc2, 0, top, width, height);
+ HDC hdc = BeginPaint(hwnd, &ps);
- HBRUSH hbr = CreateSolidBrush(g_colorTable[COLOR_BACK].cl);
- FillRect(hdc, &rc2, hbr);
- DeleteObject(hbr);
- }
+ data->Paint(data->dib, &ps.rcPaint);
- if (g_plugin.bOptVScroll)
- data->RecalcScrollBar();
- if (g_plugin.bDrawEdge)
- DrawEdge(hdc, &rc, BDR_SUNKENOUTER, BF_RECT);
+ BitBlt(hdc, ps.rcPaint.left, ps.rcPaint.top,
+ ps.rcPaint.right - ps.rcPaint.left,
+ ps.rcPaint.bottom - ps.rcPaint.top, data->dib, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
- BitBlt(hdcWindow, 0, 0, rc.right, rc.bottom, hdc, 0, 0, SRCCOPY);
- DeleteObject(SelectObject(hdc, hbmSave));
- DeleteDC(hdc);
EndPaint(hwnd, &ps);
}
break;
@@ -1391,12 +1378,6 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
else {
pt.y -= pItem->savedTop;
- CMStringW wszUrl;
- if (pItem->isLink(hwnd, pt, &wszUrl)) {
- Utils_OpenUrlW(wszUrl);
- return 0;
- }
-
data->selStart = idx;
data->SetSelection(idx, idx);
data->SetCaret(idx);
@@ -1440,14 +1421,6 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
idx = data->GetItemFromPixel(pt.y);
if (idx >= 0) {
- auto *pItem = data->LoadItem(idx);
- MTextSendMessage(hwnd, pItem->data, msg, wParam, lParam);
-
- HCURSOR hOldCursor = GetCursor();
- HCURSOR hNewCursor = LoadCursor(0, (pItem->isLink(hwnd, pt) || pItem->m_bOfflineFile) ? IDC_HAND : IDC_ARROW);
- if (hOldCursor != hNewCursor)
- SetCursor(hNewCursor);
-
if (data->selStart != -1) {
data->SetSelection(data->selStart, idx);
InvalidateRect(hwnd, 0, FALSE);
@@ -1541,7 +1514,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
void InitNewstoryControl()
{
- htuLog = MTextRegister("Newstory", MTEXT_FANCY_DEFAULT | MTEXT_SYSTEM_HICONS | MTEXT_FANCY_SMILEYS);
+ InitializeCriticalSection(&cairo_font::m_sync);
WNDCLASS wndclass = {};
wndclass.style = /*CS_HREDRAW | CS_VREDRAW | */CS_DBLCLKS | CS_GLOBALCLASS;
diff --git a/plugins/NewStory/src/history_control.h b/plugins/NewStory/src/history_control.h
index 95cfc44dc7..188e39f037 100644
--- a/plugins/NewStory/src/history_control.h
+++ b/plugins/NewStory/src/history_control.h
@@ -3,6 +3,31 @@
#define NEWSTORYLIST_CLASS "NewstoryList"
+struct NewstoryListData;
+
+class NSWebPage : public windows_container
+{
+ NewstoryListData &ctrl;
+
+ cairo_surface_t *get_image(const std::string &url) override;
+
+ void get_client_rect(litehtml::position &client) const override;
+ void import_css(litehtml::string &text, const litehtml::string &url, litehtml::string &baseurl) override;
+ void load_image(const char *src, const char *baseurl, bool redraw_on_ready) override;
+ void on_anchor_click(const char *url, const litehtml::element::ptr &el) override;
+ void set_base_url(const char *base_url) override;
+ void set_caption(const char *caption) override;
+ void set_clip(const litehtml::position &pos, const litehtml::border_radiuses &bdr_radius) override;
+ void set_cursor(const char *cursor) override;
+
+public:
+ NSWebPage(NewstoryListData &_1) :
+ ctrl(_1)
+ {}
+
+ litehtml::uint_ptr getRC() const { return (litehtml::uint_ptr)m_temp_cr; }
+};
+
struct NewstoryListData : public MZeroedObject
{
NewstoryListData(HWND);
@@ -32,6 +57,9 @@ struct NewstoryListData : public MZeroedObject
CTimer redrawTimer;
CSrmmBaseDialog *pMsgDlg = nullptr;
+ NSWebPage webPage;
+ simpledib::dib dib;
+
void OnContextMenu(int index, POINT pt);
void OnResize(int newWidth, int newHeight);
@@ -76,7 +104,7 @@ struct NewstoryListData : public MZeroedObject
void OpenFolder();
void PageUp();
void PageDown();
- int PaintItem(HDC hdc, ItemData* pItem, int top, int width, bool bDraw);
+ void Paint(simpledib::dib &dib, RECT *rcDraw);
void Quote();
void RecalcScrollBar();
void Reply();
diff --git a/plugins/NewStory/src/main.cpp b/plugins/NewStory/src/main.cpp
index c45312d809..6ce6d2134c 100644
--- a/plugins/NewStory/src/main.cpp
+++ b/plugins/NewStory/src/main.cpp
@@ -158,7 +158,7 @@ void CMPlugin::LoadOptions()
bDrawEdge = g_bOptDrawEdge;
bHppCompat = g_bOptHppCompat;
bMsgGrouping = g_bOptGrouping;
- bShowDirecction = g_bShowDirection;
+ bShowDirection = g_bShowDirection;
clCustom[0] = g_clCustom0;
clCustom[1] = g_clCustom1;
diff --git a/plugins/NewStory/src/options.cpp b/plugins/NewStory/src/options.cpp
index 7decb0d967..b83ff73fb5 100644
--- a/plugins/NewStory/src/options.cpp
+++ b/plugins/NewStory/src/options.cpp
@@ -93,16 +93,6 @@ class CTemplateOptsDlg : public CBaseOptsDlg
CCtrlMButton btnDiscard, bthVarHelp, btnReset;
CCtrlTreeView m_tree;
- UI_MESSAGE_MAP(CTemplateOptsDlg, CBaseOptsDlg);
- UI_MESSAGE(UM_REDRAWLISTH, OnColorChanged);
- UI_MESSAGE_MAP_END();
-
- LRESULT OnColorChanged(UINT, WPARAM, LPARAM)
- {
- gpreview.SendMsg(MTM_SETBKCOLOR, g_colorTable[COLOR_BACK].cl, 0);
- return 0;
- }
-
public:
CTemplateOptsDlg() :
CBaseOptsDlg(IDD_OPT_TEMPLATES),
@@ -186,7 +176,6 @@ public:
m_tree.EnsureVisible(hFirst);
WindowList_Add(g_hNewstoryWindows, m_hwnd);
- OnColorChanged(0, 0, 0);
return true;
}
@@ -278,7 +267,7 @@ public:
CMStringW wszText(m_tempItem.formatStringEx(m_curr->tmpValue));
preview.SetText(wszText);
- gpreview.SendMsg(MTM_UPDATEEX, MTEXT_FLG_RTF, LPARAM(m_tempItem.formatRtf(wszText).c_str()));
+ // gpreview.SendMsg(MTM_UPDATEEX, MTEXT_FLG_RTF, LPARAM(m_tempItem.formatRtf(wszText).c_str()));
}
void onSelChanged(CCtrlTreeView::TEventInfo *)
diff --git a/plugins/NewStory/src/stdafx.cxx b/plugins/NewStory/src/stdafx.cxx
index b5e6ba190b..d714e70110 100644
--- a/plugins/NewStory/src/stdafx.cxx
+++ b/plugins/NewStory/src/stdafx.cxx
@@ -16,4 +16,6 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "stdafx.h" \ No newline at end of file
+#include "stdafx.h"
+
+#pragma comment(lib, "cairo.lib")
diff --git a/plugins/NewStory/src/stdafx.h b/plugins/NewStory/src/stdafx.h
index f1750a365b..dbdc97963e 100644
--- a/plugins/NewStory/src/stdafx.h
+++ b/plugins/NewStory/src/stdafx.h
@@ -17,8 +17,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
+#pragma warning(disable: 4458)
-//Windows headers
+#define NOMINMAX
+
+// Windows headers
#include <windows.h>
#include <windowsx.h>
#include <process.h>
@@ -53,7 +56,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <m_protosvc.h>
#include <m_skin.h>
#include <m_srmm_int.h>
-#include <m_text.h>
#include <m_timezones.h>
#include <m_toptoolbar.h>
#include <m_userinfo.h>
@@ -62,10 +64,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "m_NewStory.h"
#include "m_PluginUpdater.h"
#include "m_smileyadd.h"
-#ifndef MTEXT_NOHELPERS
-#define MTEXT_NOHELPERS
-#endif // MTEXT_NOHELPERS
-#include "m_text.h"
+
+#include "../../Libs/litehtml/include/cairo.h"
+#include "../../Libs/litehtml/include/litehtml.h"
+#include "../../Libs/litehtml/containers/windows/cairo/cairo_font.h"
+#include "../../Libs/litehtml/containers/windows/cairo/windows_container.h"
+#include "dib.h"
#include "resource.h"
#include "version.h"
@@ -102,7 +106,7 @@ struct CMPlugin : public PLUGIN<CMPlugin>
// thesw options are a copy of static CMOption to keep performance high
bool bMsgGrouping, bDrawEdge, bHppCompat, bDisableDelete = false;
- bool bShowType, bShowDirecction;
+ bool bShowType, bShowDirection;
COLORREF clCustom[5];
diff --git a/plugins/NewStory/src/templates.cpp b/plugins/NewStory/src/templates.cpp
index 8006d2db4d..a5fe44bd72 100644
--- a/plugins/NewStory/src/templates.cpp
+++ b/plugins/NewStory/src/templates.cpp
@@ -29,6 +29,124 @@ wchar_t *months[12] =
};
///////////////////////////////////////////////////////////////////////////////
+// HTML generator
+
+static uint32_t color2html(COLORREF clr)
+{
+ return (((clr & 0xFF) << 16) | (clr & 0xFF00) | ((clr & 0xFF0000) >> 16));
+}
+
+static char* font2html(LOGFONTA &lf, char *dest)
+{
+ mir_snprintf(dest, 100, "font-family: %s; font-size: %dpt; font-weight: %s; %s",
+ lf.lfFaceName, abs((signed char)lf.lfHeight) * 74 / g_iPixelY,
+ lf.lfWeight >= FW_BOLD ? "bold" : "normal",
+ lf.lfItalic ? "font-style: italic;" : "");
+ return dest;
+}
+
+static void AppendString(CMStringA &buf, const char *p)
+{
+ bool wasSpace = false;
+
+ for (; *p; p++) {
+ if (*p == ' ') {
+ if (wasSpace)
+ buf.Append("&nbsp;");
+ else {
+ buf.AppendChar(' ');
+ wasSpace = true;
+ }
+ continue;
+ }
+
+ wasSpace = false;
+ if (*p == '\r' && p[1] == '\n') {
+ buf.Append("<br>");
+ p++;
+ }
+ else if (*p == '\n') buf.Append("<br>");
+ else if (*p == '&') buf.Append("&amp;");
+ else if (*p == '>') buf.Append("&gt;");
+ else if (*p == '<') buf.Append("&lt;");
+ else if (*p == '&') buf.Append("&quot;");
+ else if (*p == '[') {
+ p++;
+ if (*p == 'c') {
+ int colorId = -1;
+ if (p[2] == ']') {
+ colorId = atoi(p + 1);
+ p += 2;
+ }
+ else if (p[3] == ']') {
+ colorId = atoi(p + 1);
+ p += 3;
+ }
+
+ switch (colorId) {
+ case 0: buf.Append("</font>"); continue;
+ case 1: buf.Append("<font class=\"nick\">"); continue;
+ case 2: case 3: case 4: case 5: case 6:
+ buf.AppendFormat("<font color=%06X>", color2html(g_plugin.clCustom[colorId-2]));
+ continue;
+ }
+ }
+
+ char *pEnd = "";
+ if (*p == '/') {
+ pEnd = "/";
+ p++;
+ }
+ if (*p == 'b' && p[1] == ']') {
+ buf.AppendFormat("<%sb>", pEnd);
+ p++;
+ }
+ else if (*p == 'i' && p[1] == ']') {
+ buf.AppendFormat("<%si>", pEnd);
+ p++;
+ }
+ else if (*p == 'u' && p[1] == ']') {
+ buf.AppendFormat("<%su>", pEnd);
+ p++;
+ }
+ else if (*p == 's' && p[1] == ']') {
+ buf.AppendFormat("<%ss>", pEnd);
+ p++;
+ }
+ else {
+ buf.AppendChar('[');
+ if (*pEnd == '/')
+ p--;
+ p--;
+ }
+ }
+ else buf.AppendChar(*p);
+ }
+}
+
+CMStringA ItemData::formatHtml(const wchar_t *pwszStr)
+{
+ CMStringA str;
+ str.Append("<html><head>");
+ str.Append("<style type=\"text/css\">\n");
+
+ int fontID, colorID;
+ getFontColor(fontID, colorID);
+ auto &F = g_fontTable[fontID];
+
+ char szFont[100];
+ str.AppendFormat("body {margin: 0px; text-align: left; %s; overflow: auto;}\n", font2html(F.lf, szFont));
+ str.AppendFormat(".nick {color: #%06X }\n", color2html(g_colorTable[(dbe.flags & DBEF_SENT) ? COLOR_OUTNICK : COLOR_INNICK].cl));
+
+ str.Append("</style></head><body class=\"body\">\n");
+ AppendString(str, T2Utf((pwszStr) ? pwszStr : formatString()));
+
+ str.Append("</body></html>");
+ // Netlib_Logf(0, str);
+ return str;
+}
+
+///////////////////////////////////////////////////////////////////////////////
// RTF generator
static void AppendUnicodeToBuffer(CMStringA &buf, const wchar_t *p)
@@ -100,34 +218,6 @@ static void AppendUnicodeToBuffer(CMStringA &buf, const wchar_t *p)
}
}
-CMStringA ItemData::formatRtf(const wchar_t *pwszStr)
-{
- CMStringA buf;
- buf.Append("{\\rtf1\\ansi\\deff0");
-
- int fontID, colorID;
- getFontColor(fontID, colorID);
- auto &F = g_fontTable[fontID];
- buf.AppendFormat("{\\fonttbl{\\f0\\fnil\\fcharset0 %s;}}", F.lf.lfFaceName);
-
- COLORREF cr = F.cl;
- buf.AppendFormat("{\\colortbl \\red%u\\green%u\\blue%u;", GetRValue(cr), GetGValue(cr), GetBValue(cr));
- cr = g_colorTable[(dbe.flags & DBEF_SENT) ? COLOR_OUTNICK : COLOR_INNICK].cl;
- buf.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(cr), GetGValue(cr), GetBValue(cr));
-
- for (auto cl : g_plugin.clCustom) {
- cr = (cl == -1) ? 0 : cl;
- buf.AppendFormat("\\red%u\\green%u\\blue%u;", GetRValue(cr), GetGValue(cr), GetBValue(cr));
- }
-
- buf.AppendFormat("}\\uc1\\pard \\cf0\\f0\\b0\\i0\\fs%d ", GetFontHeight(F.lf));
- AppendUnicodeToBuffer(buf, (pwszStr) ? pwszStr : formatString());
-
- buf.Append("}");
- // Netlib_Logf(0, buf);
- return buf;
-}
-
CMStringA NewstoryListData::GatherSelectedRtf()
{
CMStringA buf;
diff --git a/plugins/NewStory/src/webpage.cpp b/plugins/NewStory/src/webpage.cpp
new file mode 100644
index 0000000000..b3f2b70b0a
--- /dev/null
+++ b/plugins/NewStory/src/webpage.cpp
@@ -0,0 +1,63 @@
+/*
+Copyright (c) 2005 Victor Pavlychko (nullbyte@sotline.net.ua)
+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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "stdafx.h"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Litehtml interface
+
+CRITICAL_SECTION cairo_font::m_sync;
+
+cairo_surface_t* NSWebPage::get_image(const std::string &)
+{
+ return 0;
+}
+
+void NSWebPage::get_client_rect(litehtml::position &pos) const
+{
+ pos = litehtml::size(ctrl.cachedWindowWidth, ctrl.cachedWindowHeight);
+
+}
+
+void NSWebPage::import_css(litehtml::string &, const litehtml::string &, litehtml::string &)
+{
+}
+
+void NSWebPage::load_image(const char *, const char *, bool)
+{
+}
+
+void NSWebPage::on_anchor_click(const char *, const litehtml::element::ptr &)
+{
+}
+
+void NSWebPage::set_base_url(const char *)
+{
+}
+
+void NSWebPage::set_caption(const char *)
+{
+}
+
+void NSWebPage::set_clip(const litehtml::position &, const litehtml::border_radiuses &)
+{
+}
+
+void NSWebPage::set_cursor(const char *)
+{
+}