diff options
author | George Hazan <george.hazan@gmail.com> | 2024-03-20 17:15:58 +0300 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2024-03-20 17:15:58 +0300 |
commit | 210010f8ec3aaa180d29937ca22119fba5ecaeed (patch) | |
tree | eca09f815f62d61de722b5084a1b631abb615a0b /plugins | |
parent | 78b05a9a69927af0bcad6d88036bc8b9d58dc152 (diff) |
NewStory: first html-based version which looks more or less like RTF version
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/NewStory/NewStory.vcxproj | 30 | ||||
-rw-r--r-- | plugins/NewStory/NewStory.vcxproj.filters | 23 | ||||
-rw-r--r-- | plugins/NewStory/src/dib.cpp | 176 | ||||
-rw-r--r-- | plugins/NewStory/src/dib.h | 40 | ||||
-rw-r--r-- | plugins/NewStory/src/history_array.cpp | 118 | ||||
-rw-r--r-- | plugins/NewStory/src/history_array.h | 17 | ||||
-rw-r--r-- | plugins/NewStory/src/history_control.cpp | 309 | ||||
-rw-r--r-- | plugins/NewStory/src/history_control.h | 30 | ||||
-rw-r--r-- | plugins/NewStory/src/main.cpp | 2 | ||||
-rw-r--r-- | plugins/NewStory/src/options.cpp | 13 | ||||
-rw-r--r-- | plugins/NewStory/src/stdafx.cxx | 4 | ||||
-rw-r--r-- | plugins/NewStory/src/stdafx.h | 18 | ||||
-rw-r--r-- | plugins/NewStory/src/templates.cpp | 146 | ||||
-rw-r--r-- | plugins/NewStory/src/webpage.cpp | 63 |
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(" ");
+ 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("&");
+ else if (*p == '>') buf.Append(">");
+ else if (*p == '<') buf.Append("<");
+ else if (*p == '&') buf.Append(""");
+ 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 *) +{ +} |