From ccde738e49d3102681ab38c6b3e250e9fb57c8bb Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 16 Sep 2024 19:21:57 +0300 Subject: =?UTF-8?q?fixes=20#4675=20(=D0=9D=D0=B5=20=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=B0=D1=8E=D1=82=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BA?= =?UTF-8?q?=D0=B8=20=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=B2=20StdMsg/Scriver)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/m_chat_int.h | 1 - include/m_srmm_int.h | 5 +- libs/win32/mir_app.lib | Bin 298458 -> 299036 bytes libs/win64/mir_app.lib | Bin 298470 -> 299058 bytes plugins/Scriver/res/resource.rc | 19 ++-- plugins/Scriver/scriver.vcxproj | 52 +++++++++ plugins/Scriver/scriver.vcxproj.filters | 148 ++++++++++++++++++++++++ plugins/Scriver/src/msgdialog.cpp | 3 +- plugins/Scriver/src/msgoptions.cpp | 4 +- plugins/Scriver/src/msgs.h | 1 + plugins/Scriver/src/msgutils.cpp | 6 + plugins/Scriver/src/resource.h | 2 + plugins/Scriver/src/srmm.cpp | 1 + plugins/Scriver/src/stdafx.h | 2 +- plugins/TabSRMM/src/msgdlgother.cpp | 192 ++------------------------------ plugins/TabSRMM/src/msgs.h | 3 +- src/core/stdmsg/res/resource.rc | 47 ++++---- src/core/stdmsg/src/msgdialog.cpp | 9 +- src/core/stdmsg/src/msgoptions.cpp | 4 +- src/core/stdmsg/src/msgs.h | 1 + src/core/stdmsg/src/resource.h | 4 +- src/core/stdmsg/src/srmm.cpp | 1 + src/core/stdmsg/src/stdafx.h | 2 +- src/core/stdmsg/stdmsg.vcxproj | 44 ++++++++ src/core/stdmsg/stdmsg.vcxproj.filters | 124 +++++++++++++++++++++ src/mir_app/src/chat_manager.cpp | 1 - src/mir_app/src/chat_rtf.cpp | 126 +++++++++++---------- src/mir_app/src/mir_app.def | 2 + src/mir_app/src/mir_app64.def | 2 + src/mir_app/src/srmm_base.cpp | 1 + 30 files changed, 521 insertions(+), 286 deletions(-) diff --git a/include/m_chat_int.h b/include/m_chat_int.h index f8fc7ce950..c5f0d163f2 100644 --- a/include/m_chat_int.h +++ b/include/m_chat_int.h @@ -308,7 +308,6 @@ struct CHAT_MANAGER wchar_t* (*RemoveFormatting)(const wchar_t *pszText); void (*ReloadSettings)(void); - int (*DoRtfToTags)(CMStringW &pszText, int iNumColors, COLORREF *pColors); void (*CreateNick)(const SESSION_INFO *si, const LOGINFO *lin, CMStringW &dest); int logPixelSY, logPixelSX; diff --git a/include/m_srmm_int.h b/include/m_srmm_int.h index 00f701bc44..b33980c301 100644 --- a/include/m_srmm_int.h +++ b/include/m_srmm_int.h @@ -306,6 +306,7 @@ protected: #endif bool ProcessHotkeys(int key, bool bShift, bool bCtrl, bool bAlt); void RefreshButtonStatus(void); + bool DoRtfToTags(CMStringW &pszText) const; void RunUserMenu(HWND hwndOwner, struct USERINFO *ui, const POINT &pt); void UpdateChatLog(void); @@ -347,9 +348,10 @@ public: MCONTACT m_hContact; MEVENT m_hDbEventFirst, m_hQuoteEvent = 0; int m_iLogFilterFlags; - bool m_bFilterEnabled, m_bNicklistEnabled, m_bReadOnly = false; + bool m_bFilterEnabled, m_bNicklistEnabled, m_bReadOnly = false, m_bSendFormat; bool m_bFGSet, m_bBGSet; bool m_bInMenu, m_bActive; + COLORREF m_iFG, m_iBG; CTimer timerFlash, timerType, timerNickList, timerRedraw; @@ -369,6 +371,7 @@ public: virtual void DrawNickList(USERINFO *ui, DRAWITEMSTRUCT *dis) = 0; virtual void EventAdded(MEVENT, const DB::EventInfo &dbei) = 0; virtual bool GetFirstEvent() = 0; + virtual void GetInputFont(LOGFONTW &lf, COLORREF &bg, COLORREF &fg) const = 0; virtual bool IsActive() const = 0; virtual void LoadSettings() = 0; virtual void OnOptionsApplied(); diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib index c25d680835..fc7ac5fc2a 100644 Binary files a/libs/win32/mir_app.lib and b/libs/win32/mir_app.lib differ diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib index afec140883..3fd991676e 100644 Binary files a/libs/win64/mir_app.lib and b/libs/win64/mir_app.lib differ diff --git a/plugins/Scriver/res/resource.rc b/plugins/Scriver/res/resource.rc index aba7df9289..7f6ef8da39 100644 --- a/plugins/Scriver/res/resource.rc +++ b/plugins/Scriver/res/resource.rc @@ -27,12 +27,12 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL // Dialog // -IDD_OPT_MSGDLG DIALOGEX 2, 0, 304, 147 +IDD_OPT_MSGDLG DIALOGEX 2, 0, 304, 164 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - GROUPBOX "Behavior",IDC_STATIC,0,0,304,143 + GROUPBOX "Behavior",IDC_STATIC,0,0,304,160 CONTROL "Automatically pop up the window when",IDC_AUTOPOPUP, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,12,155,10 CONTROL "Tree1",IDC_POPLIST,"SysTreeView32",TVS_DISABLEDRAGDROP | TVS_NOTOOLTIPS | TVS_NONEVENHEIGHT | WS_BORDER | WS_HSCROLL | WS_TABSTOP,163,12,98,44 @@ -45,10 +45,12 @@ BEGIN CONTROL "Remember unsent messages",IDC_SAVEDRAFTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,103,293,10 CONTROL "Delete temporary contacts on closing",IDC_DELTEMP, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,114,293,10 - LTEXT "Show warning when message has not been received after",IDC_STATIC,6,127,201,8 - EDITTEXT IDC_SECONDS,213,125,35,12,ES_RIGHT | ES_NUMBER - CONTROL "",IDC_SECONDSSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,239,124,11,13 - LTEXT "seconds",IDC_STATIC,253,127,44,8 + CONTROL "Use BBCodes to send format inside messages",IDC_SEND_FORMAT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,126,293,10 + LTEXT "Show warning when message has not been received after",IDC_STATIC,6,145,201,8 + EDITTEXT IDC_SECONDS,213,143,35,12,ES_RIGHT | ES_NUMBER + CONTROL "",IDC_SECONDSSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,239,143,11,13 + LTEXT "seconds",IDC_STATIC,253,145,44,8 END IDD_OPT_MSGTABS DIALOGEX 2, 0, 304, 230 @@ -220,8 +222,8 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN CONTROL "",IDC_SRMM_LOG,"RichEdit50W",WS_CLIPSIBLINGS | WS_VSCROLL | WS_TABSTOP | 0x844,1,41,181,28,WS_EX_STATICEDGE CONTROL "",IDC_SRMM_MESSAGE,"RichEdit50W",WS_VSCROLL | WS_TABSTOP | 0x1144,0,87,181,13,WS_EX_ACCEPTFILES | WS_EX_STATICEDGE - CONTROL "",IDC_SRMM_QUOTE,"RichEdit50W",ES_AUTOHSCROLL | WS_DISABLED | WS_BORDER | WS_TABSTOP,0,95,235,16 - CONTROL "",IDC_SRMM_CLOSEQUOTE,"MButtonClass", WS_TABSTOP,237,97,16,16 + CONTROL "",IDC_SRMM_QUOTE,"RichEdit50W",WS_DISABLED | WS_BORDER | WS_TABSTOP | 0x80,0,95,235,16 + CONTROL "",IDC_SRMM_CLOSEQUOTE,"MButtonClass",WS_TABSTOP,237,97,16,16 CONTROL "",IDC_SPLITTERX,"Static",SS_ENHMETAFILE,172,23,10,73 CONTROL "",IDC_SPLITTERY,"Static",SS_ENHMETAFILE | WS_CLIPSIBLINGS,0,85,183,2 LISTBOX IDC_SRMM_NICKLIST,182,23,69,73,LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | NOT WS_BORDER | WS_VSCROLL | WS_TABSTOP,WS_EX_STATICEDGE @@ -321,6 +323,7 @@ GUIDELINES DESIGNINFO BEGIN IDD_OPT_MSGDLG, DIALOG BEGIN + BOTTOMMARGIN, 147 END IDD_OPT_MSGTABS, DIALOG diff --git a/plugins/Scriver/scriver.vcxproj b/plugins/Scriver/scriver.vcxproj index a92315853a..93f4cd9644 100644 --- a/plugins/Scriver/scriver.vcxproj +++ b/plugins/Scriver/scriver.vcxproj @@ -64,4 +64,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/Scriver/scriver.vcxproj.filters b/plugins/Scriver/scriver.vcxproj.filters index ffe211f657..ac5f862451 100644 --- a/plugins/Scriver/scriver.vcxproj.filters +++ b/plugins/Scriver/scriver.vcxproj.filters @@ -106,4 +106,152 @@ Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/plugins/Scriver/src/msgdialog.cpp b/plugins/Scriver/src/msgdialog.cpp index 47f8893719..69783ba143 100644 --- a/plugins/Scriver/src/msgdialog.cpp +++ b/plugins/Scriver/src/msgdialog.cpp @@ -108,6 +108,7 @@ void CMsgDialog::Init() SetParent(GetParentWindow(m_hContact, isChat())); m_pParent = (ParentWindowData *)GetWindowLongPtr(m_hwndParent, GWLP_USERDATA); + m_bSendFormat = g_plugin.bSendFormat; m_btnOk.OnClick = Callback(this, &CMsgDialog::onClick_Ok); timerType.OnEvent = Callback(this, &CMsgDialog::onType); @@ -329,7 +330,7 @@ void CMsgDialog::onClick_Ok(CCtrlButton *pButton) if (isChat()) { CMStringW ptszText(ptrW(mir_utf8decodeW(msi.sendBuffer))); - g_chatApi.DoRtfToTags(ptszText, 0, nullptr); + DoRtfToTags(ptszText); ptszText.Trim(); if (m_si->pMI->bAckMsg) { diff --git a/plugins/Scriver/src/msgoptions.cpp b/plugins/Scriver/src/msgoptions.cpp index 7e6dddeccb..473929fa5d 100644 --- a/plugins/Scriver/src/msgoptions.cpp +++ b/plugins/Scriver/src/msgoptions.cpp @@ -243,7 +243,7 @@ class CMainOptionsDlg : public CBaseOptionDlg CCtrlSpin spinTimeout; CCtrlCheck chkAutoMin, chkAutoPopup, chkCascade, chkSavePerContact, chkStayMinimized; - CCtrlCheck chkSaveDrafts, chkDelTemp, chkHideContainer; + CCtrlCheck chkSaveDrafts, chkDelTemp, chkHideContainer, chkSendFormat; CCtrlTreeView m_tree; public: @@ -255,6 +255,7 @@ public: chkCascade(this, IDC_CASCADE), chkDelTemp(this, IDC_DELTEMP), chkAutoPopup(this, IDC_AUTOPOPUP), + chkSendFormat(this, IDC_SEND_FORMAT), chkSaveDrafts(this, IDC_SAVEDRAFTS), chkHideContainer(this, IDC_HIDECONTAINERS), chkStayMinimized(this, IDC_STAYMINIMIZED), @@ -264,6 +265,7 @@ public: CreateLink(chkCascade, g_plugin.bCascade); CreateLink(chkAutoMin, g_plugin.bAutoMin); CreateLink(chkAutoPopup, g_plugin.bAutoPopup); + CreateLink(chkSendFormat, g_plugin.bSendFormat); CreateLink(chkSaveDrafts, g_plugin.bSaveDrafts); CreateLink(chkHideContainer, g_plugin.bHideContainer); CreateLink(chkStayMinimized, g_plugin.bStayMinimized); diff --git a/plugins/Scriver/src/msgs.h b/plugins/Scriver/src/msgs.h index 28ec396099..3a71949364 100644 --- a/plugins/Scriver/src/msgs.h +++ b/plugins/Scriver/src/msgs.h @@ -132,6 +132,7 @@ public: void DrawNickList(USERINFO *ui, DRAWITEMSTRUCT *dis) override; void EventAdded(MEVENT, const DB::EventInfo &dbei) override; bool GetFirstEvent() override; + void GetInputFont(LOGFONTW &lf, COLORREF &bg, COLORREF &fg) const override; void LoadSettings() override; void OnOptionsApplied() override; void RemakeLog() override; diff --git a/plugins/Scriver/src/msgutils.cpp b/plugins/Scriver/src/msgutils.cpp index 9167a4f3dd..263afe7da8 100644 --- a/plugins/Scriver/src/msgutils.cpp +++ b/plugins/Scriver/src/msgutils.cpp @@ -170,6 +170,12 @@ bool CMsgDialog::GetFirstEvent() return notifyUnread; } +void CMsgDialog::GetInputFont(LOGFONTW &lf, COLORREF &bg, COLORREF &fg) const +{ + bg = m_clrInputBG; + LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, &lf, &fg); +} + void CMsgDialog::FixTabIcons() { HICON hIcon; diff --git a/plugins/Scriver/src/resource.h b/plugins/Scriver/src/resource.h index 2f97993ce5..7f5bb9ed3d 100644 --- a/plugins/Scriver/src/resource.h +++ b/plugins/Scriver/src/resource.h @@ -127,6 +127,8 @@ #define IDC_NOTIFYTRAY 1607 #define IDC_NOTIFYBALLOON 1608 #define IDC_DELTEMP 1609 +#define IDC_DELTEMP2 1610 +#define IDC_SEND_FORMAT 1610 #define IDC_AVATARSUPPORT 1611 #define IDC_LIMITNAMES 1615 #define IDC_TRANSPARENCY 1616 diff --git a/plugins/Scriver/src/srmm.cpp b/plugins/Scriver/src/srmm.cpp index 242673aefa..268a3bda76 100644 --- a/plugins/Scriver/src/srmm.cpp +++ b/plugins/Scriver/src/srmm.cpp @@ -56,6 +56,7 @@ CMPlugin::CMPlugin() : bAutoClose(SRMM_MODULE, "AutoClose", false), bAutoPopup(SRMM_MODULE, "AutoPopupMsg", false), bSaveDrafts(SRMM_MODULE, "SaveDrafts", false), + bSendFormat(SRMM_MODULE, "SendFormat", false), bTypingUnknown(SRMM_MODULE, "UnknownTyping", false), bHideContainer(SRMM_MODULE, "HideContainers", false), bStayMinimized(SRMM_MODULE, "StayMinimized", false), diff --git a/plugins/Scriver/src/stdafx.h b/plugins/Scriver/src/stdafx.h index 731e44ad23..15de6bab32 100644 --- a/plugins/Scriver/src/stdafx.h +++ b/plugins/Scriver/src/stdafx.h @@ -76,7 +76,7 @@ struct CMPlugin : public PLUGIN CMOption bUseTransparency, bTopmost, bAutoClose, bTypingNew, bTypingUnknown; CMOption bShowTitleBar, bShowStatusBar, bShowToolBar, bShowInfoBar; CMOption bShowAvatar, bShowProgress, bShowIcons, bShowTime, bShowSeconds, bShowDate, bLongDate, bRelativeDate; - CMOption bGroupMessages, bMarkFollowups, bMsgOnNewline, bDrawLines, bHideNames, bIndentText; + CMOption bGroupMessages, bMarkFollowups, bMsgOnNewline, bDrawLines, bHideNames, bIndentText, bSendFormat; CMOption bUseTabs, bLimitTabs, bLimitChatTabs, bLimitNames, bSeparateChats, bTabCloseButton, bHideOneTab, bTabsAtBottom, bSwitchToActive; CMOption bShowTyping, bShowTypingWin, bShowTypingTray, bShowTypingClist, bShowTypingSwitch; CMOption iFlashCount, iHistoryMode; diff --git a/plugins/TabSRMM/src/msgdlgother.cpp b/plugins/TabSRMM/src/msgdlgother.cpp index e94ca1a89d..1317a38f3c 100644 --- a/plugins/TabSRMM/src/msgdlgother.cpp +++ b/plugins/TabSRMM/src/msgdlgother.cpp @@ -185,189 +185,6 @@ void CMsgDialog::DetermineMinHeight() m_pContainer->m_uChildMinHeight = height; } -///////////////////////////////////////////////////////////////////////////////////////// -// convert rich edit code to bbcode (if wanted). Otherwise, strip all RTF formatting -// tags and return plain text - -static wchar_t tszRtfBreaks[] = L" \\\n\r"; - -static void CreateColorMap(const wchar_t *pszText, std::vector &res) -{ - const wchar_t *p1 = wcsstr(pszText, L"\\colortbl"); - if (!p1) - return; - - const wchar_t *pEnd = wcschr(p1, '}'); - - for (const wchar_t *p2 = wcsstr(p1, L"\\red"); p2 && p2 < pEnd; p2 = wcsstr(p1, L"\\red")) { - int iRed, iGreen, iBlue; - if (swscanf(p2, L"\\red%d\\green%d\\blue%d;", &iRed, &iGreen, &iBlue) > 0) - res.push_back(RGB(iRed, iGreen, iBlue)); - - p1 = p2 + 1; - } -} - -BOOL CMsgDialog::DoRtfToTags(CMStringW &pszText) const -{ - if (pszText.IsEmpty()) - return FALSE; - - // used to filter out attributes which are already set for the default message input area font - auto &lf = m_pContainer->m_theme.logFonts[MSGFONTID_MESSAGEAREA]; - - // create an index of colors in the module and map them to - // corresponding colors in the RTF color table - std::vector colorTable; - CreateColorMap(pszText, colorTable); - - // scan the file for rtf commands and remove or parse them - int idx = pszText.Find(L"\\pard"); - if (idx == -1) { - if ((idx = pszText.Find(L"\\ltrpar")) == -1) - return FALSE; - idx += 7; - } - else idx += 5; - - bool bInsideUl = false, bStart = true; - CMStringW res; - - // iterate through all characters, if rtf control character found then take action - for (const wchar_t *p = pszText.GetString() + idx; *p;) { - switch (*p) { - case '\\': - if (p[1] == '\\' || p[1] == '{' || p[1] == '}') { // escaped characters - res.AppendChar(p[1]); - bStart = false; - p += 2; break; - } - if (p[1] == '~') { // non-breaking space - res.AppendChar(0xA0); - bStart = false; - p += 2; break; - } - - if (!wcsncmp(p, L"\\cf", 3)) { // foreground color - COLORREF cr = colorTable[_wtoi(p + 3) - 1]; - if (cr != m_pContainer->m_theme.fontColors[MSGFONTID_MESSAGEAREA]) - res.AppendFormat(L"[color=%08X]", cr); - else if (!bStart) - res.Append(L"[/color]"); - } - else if (!wcsncmp(p, L"\\highlight", 10)) { // background color - COLORREF cr = colorTable[_wtoi(p + 10) - 1]; - if (cr != m_pContainer->m_theme.inputbg) - res.AppendFormat(L"[bkcolor=%08X]", cr); - else if (!bStart) - res.AppendFormat(L"[/bkcolor]"); - } - else if (!wcsncmp(p, L"\\line", 5)) { // soft line break; - res.AppendChar('\n'); - bStart = false; - } - else if (!wcsncmp(p, L"\\endash", 7)) { - res.AppendChar(0x2013); - bStart = false; - } - else if (!wcsncmp(p, L"\\emdash", 7)) { - res.AppendChar(0x2014); - bStart = false; - } - else if (!wcsncmp(p, L"\\bullet", 7)) { - res.AppendChar(0x2022); - bStart = false; - } - else if (!wcsncmp(p, L"\\ldblquote", 10)) { - res.AppendChar(0x201C); - bStart = false; - } - else if (!wcsncmp(p, L"\\rdblquote", 10)) { - res.AppendChar(0x201D); - bStart = false; - } - else if (!wcsncmp(p, L"\\lquote", 7)) { - res.AppendChar(0x2018); - bStart = false; - } - else if (!wcsncmp(p, L"\\rquote", 7)) { - res.AppendChar(0x2019); - bStart = false; - } - else if (!wcsncmp(p, L"\\b", 2)) { //bold - // only allow bold if the font itself isn't a bold one, otherwise just strip it.. - if (lf.lfWeight != FW_BOLD && m_bSendFormat) - res.Append((p[2] != '0') ? L"[b]" : L"[/b]"); - } - else if (!wcsncmp(p, L"\\i", 2)) { // italics - if (!lf.lfItalic && m_bSendFormat) - res.Append((p[2] != '0') ? L"[i]" : L"[/i]"); - } - else if (!wcsncmp(p, L"\\strike", 7)) { // strike-out - if (!lf.lfStrikeOut && m_bSendFormat) - res.Append((p[7] != '0') ? L"[s]" : L"[/s]"); - } - else if (!wcsncmp(p, L"\\ul", 3)) { // underlined - if (!lf.lfUnderline && m_bSendFormat) { - if (p[3] == 0 || wcschr(tszRtfBreaks, p[3])) { - res.Append(L"[u]"); - bInsideUl = true; - } - else if (!wcsncmp(p + 3, L"none", 4)) { - if (bInsideUl) - res.Append(L"[/u]"); - bInsideUl = false; - } - } - } - else if (!wcsncmp(p, L"\\tab", 4)) { // tab - res.AppendChar('\t'); - } - else if (p[1] == '\'') { // special character - if (p[2] != ' ' && p[2] != '\\') { - wchar_t tmp[10]; - - if (p[3] != ' ' && p[3] != '\\') { - wcsncpy(tmp, p + 2, 3); - tmp[3] = 0; - } - else { - wcsncpy(tmp, p + 2, 2); - tmp[2] = 0; - } - - // convert string containing char in hex format to int. - wchar_t *stoppedHere; - res.AppendChar(wcstol(tmp, &stoppedHere, 16)); - bStart = false; - } - } - - p++; // skip initial slash - p += wcscspn(p, tszRtfBreaks); - if (*p == ' ') - p++; - break; - - case '{': // other RTF control characters - case '}': - p++; - break; - - default: // other text that should not be touched - res.AppendChar(*p++); - bStart = false; - break; - } - } - - if (bInsideUl) - res.Append(L"[/u]"); - - pszText = res; - return TRUE; -} - ///////////////////////////////////////////////////////////////////////////////////////// void CMsgDialog::DrawNickList(USERINFO *ui, DRAWITEMSTRUCT *dis) @@ -638,6 +455,15 @@ bool CMsgDialog::GetFirstEvent() return true; } +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::GetInputFont(LOGFONTW &lf, COLORREF &bg, COLORREF &fg) const +{ + lf = m_pContainer->m_theme.logFonts[MSGFONTID_MESSAGEAREA]; + fg = m_pContainer->m_theme.fontColors[MSGFONTID_MESSAGEAREA]; + bg = m_pContainer->m_theme.inputbg; +} + ///////////////////////////////////////////////////////////////////////////////////////// // returns != 0 when one of the installed keyboard layouts belongs to an rtl language // used to find out whether we need to configure the message input box for bidirectional mode diff --git a/plugins/TabSRMM/src/msgs.h b/plugins/TabSRMM/src/msgs.h index 5e6aefbe58..106ae689b6 100644 --- a/plugins/TabSRMM/src/msgs.h +++ b/plugins/TabSRMM/src/msgs.h @@ -413,7 +413,6 @@ class CMsgDialog : public CSrmmBaseDialog void AdjustBottomAvatarDisplay(void); bool CalcDynamicAvatarSize(BITMAP *bminfo); void DetermineMinHeight(void); - BOOL DoRtfToTags(CMStringW &pszText) const; int FindRTLLocale(void); void FlashOnClist(MEVENT hEvent, const DB::EventInfo &dbei); void FlashTab(bool bInvertMode); @@ -465,7 +464,6 @@ class CMsgDialog : public CSrmmBaseDialog bool m_bInsertMode, m_bInitMode = true; bool m_bDeferredScroll; bool m_bWasBackgroundCreate; - bool m_bSendFormat; int m_iRealAvatarHeight; int m_iButtonBarReallyNeeds; @@ -591,6 +589,7 @@ public: void DrawNickList(USERINFO *ui, DRAWITEMSTRUCT *dis) override; void EventAdded(MEVENT, const DB::EventInfo &dbei) override; bool GetFirstEvent() override; + void GetInputFont(LOGFONTW &lf, COLORREF &bg, COLORREF &fg) const override; bool IsActive() const override; void LoadSettings() override; void OnOptionsApplied() override; diff --git a/src/core/stdmsg/res/resource.rc b/src/core/stdmsg/res/resource.rc index fc41cbb773..ef192315c9 100644 --- a/src/core/stdmsg/res/resource.rc +++ b/src/core/stdmsg/res/resource.rc @@ -36,29 +36,31 @@ BEGIN CONTROL "Don't steal focus",IDC_DONOTSTEALFOCUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,21,130,10 LTEXT "Maximum number of flashes (0 = indefinite)",IDC_STATIC,7,35,151,8 EDITTEXT IDC_NFLASHES,160,33,25,12,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "Close the message window on send",IDC_AUTOCLOSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,50,289,10 - CONTROL "Minimize the message window on send",IDC_AUTOMIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,62,289,10 + CONTROL "Close the message window on send",IDC_AUTOCLOSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,50,289,8 + CONTROL "Minimize the message window on send",IDC_AUTOMIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,62,289,8 CONTROL "Use the contact's status icon as the window icon",IDC_STATUSWIN, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,75,290,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,74,290,8 CONTROL "Save the window size and location individually for each contact",IDC_SAVEPERCONTACT, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,88,289,10 - CONTROL "Cascade new windows",IDC_CASCADE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,100,289,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,86,289,8 + CONTROL "Cascade new windows",IDC_CASCADE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,98,289,8 CONTROL "Support Ctrl+Up/Down in message area to show previously sent messages",IDC_CTRLSUPPORT, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,112,289,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,110,289,8 CONTROL "Delete temporary contacts when closing message window",IDC_DELTEMP, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,124,287,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,122,287,8 CONTROL "Enable avatar support in the message window",IDC_AVATARSUPPORT, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,137,289,10 - CONTROL "Limit avatar height to",IDC_LIMITAVATARH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,151,126,10 - EDITTEXT IDC_AVATARHEIGHT,150,150,28,13,ES_AUTOHSCROLL - LTEXT "pixels",IDC_STATIC,183,152,35,8 - CONTROL "Show 'Send' button",IDC_SHOWSENDBTN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,166,135,10 - CONTROL "Show character count",IDC_CHARCOUNT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,179,135,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,135,289,8 + CONTROL "Limit avatar height to",IDC_LIMITAVATARH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,148,126,10 + EDITTEXT IDC_AVATARHEIGHT,150,146,28,13,ES_AUTOHSCROLL + LTEXT "pixels",IDC_STATIC,183,148,35,8 + CONTROL "Show 'Send' button",IDC_SHOWSENDBTN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,161,289,8 + CONTROL "Show character count",IDC_CHARCOUNT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,173,289,8 CONTROL "Show toolbar buttons on top row",IDC_SHOWBUTTONLINE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,192,139,10 - LTEXT "Show warning when message has not been received after",IDC_STATIC,8,208,211,8 - EDITTEXT IDC_SECONDS,223,206,25,12,ES_AUTOHSCROLL - LTEXT "seconds",IDC_STATIC,253,208,44,8 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,185,289,8 + CONTROL "Use BBCodes to send format inside messages",IDC_SEND_FORMAT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,198,289,8 + LTEXT "Show warning when message has not been received after",IDC_STATIC,8,213,211,8 + EDITTEXT IDC_SECONDS,223,211,25,12,ES_AUTOHSCROLL + LTEXT "seconds",IDC_STATIC,253,213,44,8 END IDD_MSGSENDERROR DIALOGEX 0, 0, 187, 110 @@ -243,12 +245,6 @@ GUIDELINES DESIGNINFO BEGIN IDD_OPT_MSGDLG, DIALOG BEGIN - VERTGUIDE, 7 - VERTGUIDE, 22 - VERTGUIDE, 51 - VERTGUIDE, 148 - VERTGUIDE, 297 - VERTGUIDE, 300 BOTTOMMARGIN, 231 END @@ -519,6 +515,11 @@ BEGIN 0 END +IDD_OPT_MSGDLG AFX_DIALOG_LAYOUT +BEGIN + 0 +END + #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/core/stdmsg/src/msgdialog.cpp b/src/core/stdmsg/src/msgdialog.cpp index eedfacbb33..b7cdfbdc3c 100644 --- a/src/core/stdmsg/src/msgdialog.cpp +++ b/src/core/stdmsg/src/msgdialog.cpp @@ -71,6 +71,7 @@ void CMsgDialog::Init() m_autoClose = 0; m_forceResizable = true; m_bNoActivate = g_plugin.bDoNotStealFocus; + m_bSendFormat = g_plugin.bSendFormat; g_arDialogs.insert(this); @@ -319,7 +320,7 @@ void CMsgDialog::onClick_Ok(CCtrlButton *pButton) if (isChat()) { CMStringW ptszText(ptrW(mir_utf8decodeW(msgText))); - g_chatApi.DoRtfToTags(ptszText, 0, nullptr); + DoRtfToTags(ptszText); ptszText.Trim(); m_cmdList.insert(mir_wstrdup(ptszText)); @@ -1320,6 +1321,12 @@ bool CMsgDialog::GetFirstEvent() return true; } +void CMsgDialog::GetInputFont(LOGFONTW &lf, COLORREF &bg, COLORREF &fg) const +{ + bg = g_plugin.getDword(SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR); + LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, &lf, &fg); +} + void CMsgDialog::NotifyTyping(int mode) { if (!m_hContact) diff --git a/src/core/stdmsg/src/msgoptions.cpp b/src/core/stdmsg/src/msgoptions.cpp index 2eae075286..a73eaf6d40 100644 --- a/src/core/stdmsg/src/msgoptions.cpp +++ b/src/core/stdmsg/src/msgoptions.cpp @@ -147,7 +147,7 @@ class COptionMainDlg : public CDlgBase { CCtrlEdit edtNFlash, edtAvatarH, edtSecs; CCtrlCheck chkAutoMin, chkAutoClose, chkSavePerContact, chkDoNotStealFocus, chkStatusWin; - CCtrlCheck chkDelTemp, chkCascade, chkCharCount, chkCtrlSupport; + CCtrlCheck chkDelTemp, chkCascade, chkCharCount, chkCtrlSupport, chkSendFormat; CCtrlCheck chkAvatar, chkLimitAvatar; CCtrlCheck chkShowSend, chkShowButtons; @@ -199,6 +199,7 @@ public: chkAutoClose(this, IDC_AUTOCLOSE), chkCharCount(this, IDC_CHARCOUNT), chkStatusWin(this, IDC_STATUSWIN), + chkSendFormat(this, IDC_SEND_FORMAT), chkLimitAvatar(this, IDC_LIMITAVATARH), chkShowButtons(this, IDC_SHOWBUTTONLINE), chkCtrlSupport(this, IDC_CTRLSUPPORT), @@ -225,6 +226,7 @@ public: CreateLink(chkAutoClose, g_plugin.bAutoClose); CreateLink(chkShowSend, g_plugin.bSendButton); CreateLink(chkCharCount, g_plugin.bShowReadChar); + CreateLink(chkSendFormat, g_plugin.bSendFormat); CreateLink(chkStatusWin, g_plugin.bUseStatusWinIcon); CreateLink(chkShowButtons, g_plugin.bShowButtons); CreateLink(chkCtrlSupport, g_plugin.bCtrlSupport); diff --git a/src/core/stdmsg/src/msgs.h b/src/core/stdmsg/src/msgs.h index 315709ed02..440d13f7b4 100644 --- a/src/core/stdmsg/src/msgs.h +++ b/src/core/stdmsg/src/msgs.h @@ -138,6 +138,7 @@ public: void DrawNickList(USERINFO *ui, DRAWITEMSTRUCT *dis) override; void EventAdded(MEVENT, const DB::EventInfo &dbei) override; bool GetFirstEvent() override; + void GetInputFont(LOGFONTW &lf, COLORREF &bg, COLORREF &fg) const override; bool IsActive() const override; void LoadSettings() override; void OnOptionsApplied() override; diff --git a/src/core/stdmsg/src/resource.h b/src/core/stdmsg/src/resource.h index dbdb870663..8e5b4ea0d7 100644 --- a/src/core/stdmsg/src/resource.h +++ b/src/core/stdmsg/src/resource.h @@ -79,6 +79,8 @@ #define IDC_LOADCOUNTSPIN 1040 #define IDC_SHOWBUTTONLINE 1042 #define IDC_LOADUNREAD 1043 +#define IDC_SHOWBUTTONLINE2 1043 +#define IDC_SEND_FORMAT 1043 #define IDC_LOADCOUNT 1044 #define IDC_LOADTIMEN 1045 #define IDC_LOADTIMESPIN 1046 @@ -196,7 +198,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 291 +#define _APS_NEXT_RESOURCE_VALUE 293 #define _APS_NEXT_COMMAND_VALUE 40019 #define _APS_NEXT_CONTROL_VALUE 1620 #define _APS_NEXT_SYMED_VALUE 101 diff --git a/src/core/stdmsg/src/srmm.cpp b/src/core/stdmsg/src/srmm.cpp index 63d7e2481f..fef28a5a02 100644 --- a/src/core/stdmsg/src/srmm.cpp +++ b/src/core/stdmsg/src/srmm.cpp @@ -64,6 +64,7 @@ CMPlugin::CMPlugin() : bAutoClose(SRMM_MODULE, "AutoClose", false), bShowNames(SRMM_MODULE, "ShowNames", false), bShowFormat(SRMM_MODULE, "ShowFormatting", true), + bSendFormat(SRMM_MODULE, "SendFormat", false), bSendButton(SRMM_MODULE, "UseSendButton", false), bCtrlSupport(SRMM_MODULE, "SupportCtrlUpDn", true), bShowReadChar(SRMM_MODULE, "ShowCharCount", false), diff --git a/src/core/stdmsg/src/stdafx.h b/src/core/stdmsg/src/stdafx.h index 27a9c076e3..bfdf282fe5 100644 --- a/src/core/stdmsg/src/stdafx.h +++ b/src/core/stdmsg/src/stdafx.h @@ -162,7 +162,7 @@ struct CMPlugin : public PLUGIN // private chat log options CMOption bShowButtons, bSendButton, bShowTyping, bShowTypingWin, bShowTypingTray, bShowTypingClist; CMOption bShowIcons, bShowTime, bShowDate, bShowAvatar, bShowNames, bShowSecs, bShowReadChar; - CMOption bAutoClose, bAutoMin, bTypingNew, bTypingUnknown, bCtrlSupport, bShowFormat; + CMOption bAutoClose, bAutoMin, bTypingNew, bTypingUnknown, bCtrlSupport, bShowFormat, bSendFormat; CMOption bSavePerContact, bDoNotStealFocus, bCascade, bDeleteTempCont, bUseStatusWinIcon, bAutoCopy; CMOption bLimitAvatarHeight; diff --git a/src/core/stdmsg/stdmsg.vcxproj b/src/core/stdmsg/stdmsg.vcxproj index c083c48a66..6e5440ec01 100644 --- a/src/core/stdmsg/stdmsg.vcxproj +++ b/src/core/stdmsg/stdmsg.vcxproj @@ -53,4 +53,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/core/stdmsg/stdmsg.vcxproj.filters b/src/core/stdmsg/stdmsg.vcxproj.filters index 1996b04a19..68c5c47780 100644 --- a/src/core/stdmsg/stdmsg.vcxproj.filters +++ b/src/core/stdmsg/stdmsg.vcxproj.filters @@ -73,4 +73,128 @@ Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/src/mir_app/src/chat_manager.cpp b/src/mir_app/src/chat_manager.cpp index 11be2dc8ae..07e53b5969 100644 --- a/src/mir_app/src/chat_manager.cpp +++ b/src/mir_app/src/chat_manager.cpp @@ -774,7 +774,6 @@ static void ResetApi() g_chatApi.SetOffline = ::SetOffline; g_chatApi.SetAllOffline = ::SetAllOffline; - g_chatApi.DoRtfToTags = ::DoRtfToTags; g_chatApi.LoadMsgDlgFont = ::LoadMsgDlgFont; g_chatApi.MakeTimeStamp = ::MakeTimeStamp; diff --git a/src/mir_app/src/chat_rtf.cpp b/src/mir_app/src/chat_rtf.cpp index e581146cf4..1ba9ed4995 100644 --- a/src/mir_app/src/chat_rtf.cpp +++ b/src/mir_app/src/chat_rtf.cpp @@ -30,58 +30,37 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. static wchar_t tszRtfBreaks[] = L" \\\n\r"; -static void CreateColorMap(CMStringW &Text, int iCount, COLORREF *pSrc, int *pDst) +static void CreateColorMap(const wchar_t *pszText, std::vector &res) { - const wchar_t *pszText = Text; - int iIndex = 1; - - static const wchar_t *lpszFmt = L"\\red%[^ \x5b\\]\\green%[^ \x5b\\]\\blue%[^ \x5b;];"; - wchar_t szRed[10], szGreen[10], szBlue[10]; - const wchar_t *p1 = wcsstr(pszText, L"\\colortbl"); if (!p1) return; const wchar_t *pEnd = wcschr(p1, '}'); - const wchar_t *p2 = wcsstr(p1, L"\\red"); + for (const wchar_t *p2 = wcsstr(p1, L"\\red"); p2 && p2 < pEnd; p2 = wcsstr(p1, L"\\red")) { + int iRed, iGreen, iBlue; + if (swscanf(p2, L"\\red%d\\green%d\\blue%d;", &iRed, &iGreen, &iBlue) > 0) + res.push_back(RGB(iRed, iGreen, iBlue)); - for (int i = 0; i < iCount; i++) - pDst[i] = -1; - - while (p2 && p2 < pEnd) { - if (swscanf(p2, lpszFmt, &szRed, &szGreen, &szBlue) > 0) { - for (int i = 0; i < iCount; i++) { - if (pSrc[i] == RGB(_wtoi(szRed), _wtoi(szGreen), _wtoi(szBlue))) - pDst[i] = iIndex; - } - } - iIndex++; - p1 = p2; - p1++; - - p2 = wcsstr(p1, L"\\red"); + p1 = p2 + 1; } } -static int GetRtfIndex(int iCol, int iCount, int *pIndex) -{ - for (int i = 0; i < iCount; i++) - if (pIndex[i] == iCol) - return i; - - return -1; -} - -int DoRtfToTags(CMStringW &pszText, int iNumColors, COLORREF *pColors) +bool CSrmmBaseDialog::DoRtfToTags(CMStringW &pszText) const { if (pszText.IsEmpty()) return FALSE; + // used to filter out attributes which are already set for the default message input area font + LOGFONTW lf; + COLORREF inputBg, inputFg; + GetInputFont(lf, inputBg, inputFg); + // create an index of colors in the module and map them to // corresponding colors in the RTF color table - int *pIndex = (int*)_alloca(iNumColors * sizeof(int)); - CreateColorMap(pszText, iNumColors, pColors, pIndex); + std::vector colorTable; + CreateColorMap(pszText, colorTable); // scan the file for rtf commands and remove or parse them int idx = pszText.Find(L"\\pard"); @@ -92,7 +71,7 @@ int DoRtfToTags(CMStringW &pszText, int iNumColors, COLORREF *pColors) } else idx += 5; - bool bInsideColor = false, bInsideUl = false; + bool bInsideUl = false, bStart = true; CMStringW res; // iterate through all characters, if rtf control character found then take action @@ -101,65 +80,85 @@ int DoRtfToTags(CMStringW &pszText, int iNumColors, COLORREF *pColors) case '\\': if (p[1] == '\\' || p[1] == '{' || p[1] == '}') { // escaped characters res.AppendChar(p[1]); + bStart = false; p += 2; break; } if (p[1] == '~') { // non-breaking space res.AppendChar(0xA0); + bStart = false; p += 2; break; } if (!wcsncmp(p, L"\\cf", 3)) { // foreground color - int iCol = _wtoi(p + 3); - int iInd = GetRtfIndex(iCol, iNumColors, pIndex); - bInsideColor = iInd > 0; - } - else if (!wcsncmp(p, L"\\highlight", 10)) { //background color - wchar_t szTemp[20]; - int iCol = _wtoi(p + 10); - mir_snwprintf(szTemp, L"%d", iCol); + COLORREF cr = colorTable[_wtoi(p + 3) - 1]; + if (cr != inputFg) + res.AppendFormat(L"[color=%06X]", cr); + else if (!bStart) + res.Append(L"[/color]"); + } + else if (!wcsncmp(p, L"\\highlight", 10)) { // background color + COLORREF cr = colorTable[_wtoi(p + 10) - 1]; + if (cr != inputBg) + res.AppendFormat(L"[bkcolor=%06X]", cr); + else if (!bStart) + res.AppendFormat(L"[/bkcolor]"); } else if (!wcsncmp(p, L"\\line", 5)) { // soft line break; res.AppendChar('\n'); + bStart = false; } else if (!wcsncmp(p, L"\\endash", 7)) { res.AppendChar(0x2013); + bStart = false; } else if (!wcsncmp(p, L"\\emdash", 7)) { res.AppendChar(0x2014); + bStart = false; } else if (!wcsncmp(p, L"\\bullet", 7)) { res.AppendChar(0x2022); + bStart = false; } else if (!wcsncmp(p, L"\\ldblquote", 10)) { res.AppendChar(0x201C); + bStart = false; } else if (!wcsncmp(p, L"\\rdblquote", 10)) { res.AppendChar(0x201D); + bStart = false; } else if (!wcsncmp(p, L"\\lquote", 7)) { res.AppendChar(0x2018); + bStart = false; } else if (!wcsncmp(p, L"\\rquote", 7)) { res.AppendChar(0x2019); + bStart = false; } else if (!wcsncmp(p, L"\\b", 2)) { //bold - res.Append((p[2] != '0') ? L"[b]" : L"[/b]"); + // only allow bold if the font itself isn't a bold one, otherwise just strip it.. + if (lf.lfWeight != FW_BOLD && m_bSendFormat) + res.Append((p[2] != '0') ? L"[b]" : L"[/b]"); } else if (!wcsncmp(p, L"\\i", 2)) { // italics - res.Append((p[2] != '0') ? L"[i]" : L"[/i]"); + if (!lf.lfItalic && m_bSendFormat) + res.Append((p[2] != '0') ? L"[i]" : L"[/i]"); } else if (!wcsncmp(p, L"\\strike", 7)) { // strike-out - res.Append((p[7] != '0') ? L"[s]" : L"[/s]"); + if (!lf.lfStrikeOut && m_bSendFormat) + res.Append((p[7] != '0') ? L"[s]" : L"[/s]"); } else if (!wcsncmp(p, L"\\ul", 3)) { // underlined - if (p[3] == 0 || wcschr(tszRtfBreaks, p[3])) { - res.Append(L"[u]"); - bInsideUl = true; - } - else if (!wcsncmp(p + 3, L"none", 4)) { - if (bInsideUl) - res.Append(L"[/u]"); - bInsideUl = false; + if (!lf.lfUnderline && m_bSendFormat) { + if (p[3] == 0 || wcschr(tszRtfBreaks, p[3])) { + res.Append(L"[u]"); + bInsideUl = true; + } + else if (!wcsncmp(p + 3, L"none", 4)) { + if (bInsideUl) + res.Append(L"[/u]"); + bInsideUl = false; + } } } else if (!wcsncmp(p, L"\\tab", 4)) { // tab @@ -167,15 +166,21 @@ int DoRtfToTags(CMStringW &pszText, int iNumColors, COLORREF *pColors) } else if (p[1] == '\'') { // special character if (p[2] != ' ' && p[2] != '\\') { - wchar_t tmp[10], *t = tmp; - *t++ = p[2]; - if (p[3] != ' ' && p[3] != '\\') - *t++ = p[3]; - *t = 0; + wchar_t tmp[10]; + + if (p[3] != ' ' && p[3] != '\\') { + wcsncpy(tmp, p + 2, 3); + tmp[3] = 0; + } + else { + wcsncpy(tmp, p + 2, 2); + tmp[2] = 0; + } // convert string containing char in hex format to int. wchar_t *stoppedHere; res.AppendChar(wcstol(tmp, &stoppedHere, 16)); + bStart = false; } } @@ -192,6 +197,7 @@ int DoRtfToTags(CMStringW &pszText, int iNumColors, COLORREF *pColors) default: // other text that should not be touched res.AppendChar(*p++); + bStart = false; break; } } diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def index 08e527e0fa..f6235f268c 100644 --- a/src/mir_app/src/mir_app.def +++ b/src/mir_app/src/mir_app.def @@ -985,3 +985,5 @@ g_hevEventSetJson @1109 NONAME ?process@MJsonWebSocket@@EAEXPBEI@Z @1123 NONAME _Proto_CanDeleteHistory@8 @1124 NONAME ?OnCacheInit@PROTO_INTERFACE@@UAEXXZ @1125 NONAME +?DoRtfToTags@CSrmmBaseDialog@@IBE_NAAV?$CMStringT@_WV?$ChTraitsCRT@_W@@@@@Z @1126 NONAME +?bUseGroup@Chat@@3V?$CMOption@_N@@A @1127 NONAME diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def index c4850e24ff..a09d88051d 100644 --- a/src/mir_app/src/mir_app64.def +++ b/src/mir_app/src/mir_app64.def @@ -985,3 +985,5 @@ g_hevEventSetJson @1103 NONAME ?process@MJsonWebSocket@@EEAAXPEBE_K@Z @1117 NONAME Proto_CanDeleteHistory @1118 NONAME ?OnCacheInit@PROTO_INTERFACE@@UEAAXXZ @1119 NONAME +?DoRtfToTags@CSrmmBaseDialog@@IEBA_NAEAV?$CMStringT@_WV?$ChTraitsCRT@_W@@@@@Z @1120 NONAME +?bUseGroup@Chat@@3V?$CMOption@_N@@A @1121 NONAME diff --git a/src/mir_app/src/srmm_base.cpp b/src/mir_app/src/srmm_base.cpp index ebac38fdb4..6788f1f424 100644 --- a/src/mir_app/src/srmm_base.cpp +++ b/src/mir_app/src/srmm_base.cpp @@ -1114,3 +1114,4 @@ void CSrmmBaseDialog::SetQuoteEvent(MEVENT hEvent) Resize(); } } + -- cgit v1.2.3