diff options
author | George Hazan <ghazan@miranda.im> | 2021-03-17 21:07:56 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2021-03-17 21:07:56 +0300 |
commit | 9df250ccbd2192ad3f0906e3714e97fa880f9882 (patch) | |
tree | 8b5120d8fccc75fd84a70802592ceccd59d7b1bb /plugins/NotesAndReminders/src | |
parent | 2d712275e2ecf08e106fa93783767a6587a31e5a (diff) |
fixes #2778 (Notes and Reminders: плагину требуется доза Unicode)
Diffstat (limited to 'plugins/NotesAndReminders/src')
-rw-r--r-- | plugins/NotesAndReminders/src/notes.cpp | 84 | ||||
-rw-r--r-- | plugins/NotesAndReminders/src/reminders.cpp | 32 | ||||
-rw-r--r-- | plugins/NotesAndReminders/src/stdafx.h | 2 |
3 files changed, 56 insertions, 62 deletions
diff --git a/plugins/NotesAndReminders/src/notes.cpp b/plugins/NotesAndReminders/src/notes.cpp index 2b2e91b126..8e86a1ae6d 100644 --- a/plugins/NotesAndReminders/src/notes.cpp +++ b/plugins/NotesAndReminders/src/notes.cpp @@ -72,7 +72,7 @@ struct STICKYNOTE : public MZeroedObject { HWND SNHwnd, REHwnd; BOOL bVisible, bOnTop; - CMStringA szText; + CMStringW wszText; ULONGLONG ID; // FILETIME in UTC wchar_t *pwszTitle; BOOL CustomTitle; @@ -251,9 +251,6 @@ static void JustSaveNotes(STICKYNOTE *pModified = nullptr) g_plugin.setDword("NotesData", NotesCount); for (auto &pNote : g_arStickies) { - int scrollV = 0; - char *tData = nullptr; - // window pos and size WINDOWPLACEMENT wp; wp.length = sizeof(WINDOWPLACEMENT); @@ -268,30 +265,24 @@ static void JustSaveNotes(STICKYNOTE *pModified = nullptr) if (pNote->bVisible) flags |= 1; if (pNote->bOnTop) flags |= 2; - // get note text - int SzT = GetWindowTextLength(pNote->REHwnd); - if (SzT) { // TODO: change to support unicode and rtf, use EM_STREAMOUT - if (SzT > MAX_NOTE_LEN) - SzT = MAX_NOTE_LEN; // we want to be far below the 64k limit - tData = (char*)malloc(SzT + 1); - if (tData) - GetWindowTextA(pNote->REHwnd, tData, SzT + 1); - } - // update the data of the modified note - if (pNote == pModified) - pNote->szText = tData ? tData : ""; - - if (!tData) // empty note - SzT = 0; - else // get current scroll position - scrollV = SendMessage(pNote->REHwnd, EM_GETFIRSTVISIBLELINE, 0, 0); + if (pNote == pModified) { + int SzT = GetWindowTextLengthW(pNote->REHwnd); + if (SzT) { // TODO: change to support unicode and rtf, use EM_STREAMOUT + if (SzT > MAX_NOTE_LEN) + SzT = MAX_NOTE_LEN; // we want to be far below the 64k limit + pNote->wszText.Preallocate(SzT + 1); + GetWindowTextW(pNote->REHwnd, pNote->wszText.GetBuffer(), SzT + 1); + } + else pNote->wszText.Empty(); + } // data header CMStringA szValue; szValue.AppendFormat("X%I64x:%d:%d:%d:%d:%x", pNote->ID, TX, TY, TW, TH, flags); // scroll pos + int scrollV = (pNote->wszText.IsEmpty()) ? 0 : SendMessage(pNote->REHwnd, EM_GETFIRSTVISIBLELINE, 0, 0); if (scrollV > 0) szValue.AppendFormat("\033""%u:%u", DATATAG_SCROLLPOS, (UINT)scrollV); @@ -314,14 +305,12 @@ static void JustSaveNotes(STICKYNOTE *pModified = nullptr) szValue.AppendFormat("\033""%u:%s", DATATAG_TITLE, pNote->pwszTitle); // note text (ALWAYS PUT THIS PARAM LAST) - if (tData) - szValue.AppendFormat("\033""%u:%s", DATATAG_TEXT, tData); + if (!pNote->wszText.IsEmpty()) + szValue.AppendFormat("\033""%u:%s", DATATAG_TEXT, ptrA(mir_utf8encodeW(pNote->wszText)).get()); mir_snprintf(ValueName, "NotesData%d", i++); // we do not reverse notes in DB db_set_blob(0, MODULENAME, ValueName, szValue.GetBuffer(), szValue.GetLength() + 1); - free(tData); - // make no save is queued for the note if (pNote->SNHwnd) KillTimer(pNote->SNHwnd, 1025); @@ -548,7 +537,7 @@ static void SetNoteTextControl(STICKYNOTE *SN) CF.crTextColor = SN->FgColor ? (SN->FgColor & 0xffffff) : BodyFontColor; SendMessage(SN->REHwnd, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&CF); - SetWindowTextA(SN->REHwnd, SN->szText); + SetWindowTextW(SN->REHwnd, SN->wszText); } @@ -1062,7 +1051,7 @@ LRESULT CALLBACK StickyNoteWndProc(HWND hdlg, UINT message, WPARAM wParam, LPARA return FALSE; } -static STICKYNOTE* NewNoteEx(int Ax, int Ay, int Aw, int Ah, const char *pszText, ULONGLONG *ID, BOOL bVisible, BOOL bOnTop, int scrollV, COLORREF bgClr, COLORREF fgClr, wchar_t *Title, STICKYNOTEFONT *pCustomFont, BOOL bLoading) +static STICKYNOTE* NewNoteEx(int Ax, int Ay, int Aw, int Ah, const wchar_t *pwszText, ULONGLONG *ID, BOOL bVisible, BOOL bOnTop, int scrollV, COLORREF bgClr, COLORREF fgClr, wchar_t *Title, STICKYNOTEFONT *pCustomFont, BOOL bLoading) { WNDCLASSEX TWC = {0}; WINDOWPLACEMENT TWP; @@ -1087,7 +1076,7 @@ static STICKYNOTE* NewNoteEx(int Ax, int Ay, int Aw, int Ah, const char *pszText if (!RegisterClassEx(&TWC)) return nullptr; } - if (!pszText || Aw < 0 || Ah < 0) { + if (!pwszText || Aw < 0 || Ah < 0) { TWP.length = sizeof(WINDOWPLACEMENT); GetWindowPlacement(GetDesktopWindow(), &TWP); Aw = g_NoteWidth; Ah = g_NoteHeight; @@ -1108,8 +1097,8 @@ static STICKYNOTE* NewNoteEx(int Ax, int Ay, int Aw, int Ah, const char *pszText g_arStickies.insert(TSN); - if (pszText) - TSN->szText = pszText; + if (pwszText) + TSN->wszText = pwszText; // init note title (time-stamp) if (Title) { @@ -1143,7 +1132,7 @@ static STICKYNOTE* NewNoteEx(int Ax, int Ay, int Aw, int Ah, const char *pszText // ensure that window is not placed off-screen (if previous session had different monitor count or resolution) // NOTE: SetWindowPlacement should do this, but it's extremly flakey - if (pszText) { + if (pwszText) { if (!MonitorFromWindow(TSN->SNHwnd, MONITOR_DEFAULTTONULL)) { TWP.length = sizeof(WINDOWPLACEMENT); GetWindowPlacement(GetDesktopWindow(), &TWP); @@ -1162,7 +1151,7 @@ static STICKYNOTE* NewNoteEx(int Ax, int Ay, int Aw, int Ah, const char *pszText ShowWindow(TSN->SNHwnd, SW_SHOWNA); // when loading notes (only at startup), place all non-top notes at the bottom so they don't cover other windows - if (pszText && !bOnTop && bIsStartup) + if (pwszText && !bOnTop && bIsStartup) SetWindowPos(TSN->SNHwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS); } @@ -1178,9 +1167,9 @@ static STICKYNOTE* NewNoteEx(int Ax, int Ay, int Aw, int Ah, const char *pszText return TSN; } -void NewNote(int Ax, int Ay, int Aw, int Ah, const char *pszText, ULONGLONG *ID, BOOL bVisible, BOOL bOnTop, int scrollV) +void NewNote(int Ax, int Ay, int Aw, int Ah, const wchar_t *pwszText, ULONGLONG *ID, BOOL bVisible, BOOL bOnTop, int scrollV) { - auto *PSN = NewNoteEx(Ax, Ay, Aw, Ah, pszText, ID, bVisible, bOnTop, scrollV, 0, 0, nullptr, nullptr, FALSE); + auto *PSN = NewNoteEx(Ax, Ay, Aw, Ah, pwszText, ID, bVisible, bOnTop, scrollV, 0, 0, nullptr, nullptr, FALSE); if (PSN) SetFocus(PSN->REHwnd); } @@ -1224,7 +1213,7 @@ static void LoadNote(char *Value, bool bIsStartup) bOnTop = TRUE; // optional \033 separated params - char *data = 0; + CMStringW wszText; ptrW title; COLORREF BgColor = 0, FgColor = 0; @@ -1245,7 +1234,11 @@ static void LoadNote(char *Value, bool bIsStartup) switch (tag) { case DATATAG_TEXT: - data = _strdup(TVal); + if (auto *pwszTmp = mir_utf8decodeW(TVal)) { + wszText = pwszTmp; + delete pwszTmp; + } + else wszText = _A2T(TVal); break; case DATATAG_SCROLLPOS: @@ -1310,14 +1303,11 @@ static void LoadNote(char *Value, bool bIsStartup) } } - if (!data) - data = _strdup(""); - bVisible = bVisible && (!bIsStartup || g_plugin.bShowNotesAtStart); if (bIsStartup) bVisible |= 0x10000; - NewNoteEx(rect[0], rect[1], rect[2], rect[3], data, &id, bVisible, bOnTop, scrollV, BgColor, FgColor, title, pCustomFont, TRUE); + NewNoteEx(rect[0], rect[1], rect[2], rect[3], wszText, &id, bVisible, bOnTop, scrollV, BgColor, FgColor, title, pCustomFont, TRUE); } void LoadNotes(bool bIsStartup) @@ -1368,7 +1358,7 @@ static void EditNote(STICKYNOTE *SN) SetFocus(SN->REHwnd); } -wchar_t* GetPreviewString(const char *lpsz) +wchar_t* GetPreviewString(const wchar_t *lpsz) { const int MaxLen = 80; static wchar_t s[MaxLen + 8]; @@ -1377,18 +1367,18 @@ wchar_t* GetPreviewString(const char *lpsz) return L""; // trim leading spaces - while (isspace(*lpsz)) + while (iswspace(*lpsz)) lpsz++; - size_t l = mir_strlen(lpsz); + size_t l = mir_wstrlen(lpsz); if (!l) return L""; if (l <= MaxLen) { - mir_wstrcpy(s, _A2T(lpsz)); + mir_wstrcpy(s, lpsz); } else { - mir_wstrncpy(s, _A2T(lpsz), MaxLen); + mir_wstrncpy(s, lpsz, MaxLen); s[MaxLen] = '.'; s[MaxLen + 1] = '.'; s[MaxLen + 2] = '.'; @@ -1450,7 +1440,7 @@ class CNotesListDlg : public CDlgBase lvTIt.iItem = i; lvTIt.iSubItem = 3; - lvTIt.pszText = GetPreviewString(pNote->szText); + lvTIt.pszText = GetPreviewString(pNote->wszText); m_list.SetItem(&lvTIt); i++; @@ -1640,7 +1630,7 @@ public: void list_onItemChanged(CCtrlListView::TEventInfo *ev) { - SetDlgItemTextA(m_hwnd, IDC_REMINDERDATA, g_arStickies[ev->nmlv->iItem].szText); + SetDlgItemTextW(m_hwnd, IDC_REMINDERDATA, g_arStickies[ev->nmlv->iItem].wszText); } void list_onDblClick(CCtrlListView::TEventInfo*) diff --git a/plugins/NotesAndReminders/src/reminders.cpp b/plugins/NotesAndReminders/src/reminders.cpp index 2ec9369fcd..d7b72dc93d 100644 --- a/plugins/NotesAndReminders/src/reminders.cpp +++ b/plugins/NotesAndReminders/src/reminders.cpp @@ -21,7 +21,7 @@ struct REMINDERDATA : public MZeroedObject {
HWND handle;
DWORD uid;
- CMStringA szText;
+ CMStringW wszText;
ULONGLONG When; // FILETIME in UTC
UINT RepeatSound;
UINT RepeatSoundTTL;
@@ -61,7 +61,7 @@ int WS_Send(SOCKET s, char *data, int datalen); unsigned long WS_ResolveName(char *name, WORD *port, int defaultPort);
void Send(char *user, char *host, const char *Msg, char* server);
-wchar_t* GetPreviewString(const char *lpsz);
+wchar_t* GetPreviewString(const wchar_t *lpsz);
static void NotifyList();
@@ -165,8 +165,8 @@ void JustSaveReminders(void) szValue.AppendFormat("\033""%u:%d", DATATAG_SNDSEL, pReminder->SoundSel);
// reminder text/note (ALWAYS PUT THIS PARAM LAST)
- if (!pReminder->szText.IsEmpty())
- szValue.AppendFormat("\033""%u:%s", DATATAG_TEXT, pReminder->szText.c_str());
+ if (!pReminder->wszText.IsEmpty())
+ szValue.AppendFormat("\033""%u:%s", DATATAG_TEXT, ptrA(mir_utf8encodeW(pReminder->wszText)).get());
char ValueName[32];
mir_snprintf(ValueName, "RemindersData%d", i++);
@@ -215,7 +215,11 @@ static bool LoadReminder(char *Value) switch (tag) {
case DATATAG_TEXT:
- TempRem->szText = TVal;
+ if (auto *szText = mir_utf8decodeW(TVal)) {
+ TempRem->wszText = szText;
+ mir_free(szText);
+ }
+ else TempRem->wszText = _A2T(TVal);
break;
case DATATAG_SNDREPEAT:
@@ -1096,7 +1100,7 @@ public: mir_snwprintf(S2, L"%s! - %s", TranslateT("Reminder"), S1);
SetCaption(S2);
- edtText.SetTextA(m_pReminder->szText);
+ edtText.SetText(m_pReminder->wszText);
return true;
}
@@ -1223,7 +1227,7 @@ public: }
// update reminder text
- m_pReminder->szText = ptrA(edtText.GetTextA());
+ m_pReminder->wszText = ptrW(edtText.GetText());
m_pReminder->bVisible = false;
m_pReminder->handle = nullptr;
@@ -1236,7 +1240,7 @@ public: void onClick_None(CCtrlButton*)
{
// create note from reminder
- NewNote(0, 0, -1, -1, ptrA(edtText.GetTextA()), nullptr, TRUE, TRUE, 0);
+ NewNote(0, 0, -1, -1, ptrW(edtText.GetText()), nullptr, TRUE, TRUE, 0);
}
};
@@ -1334,7 +1338,7 @@ public: else
cmbTime.SetText(s);
- edtText.SetTextA(m_pReminder->szText);
+ edtText.SetText(m_pReminder->wszText);
}
else cmbTime.SetCurSel(0);
@@ -1423,7 +1427,7 @@ public: REMINDERDATA *TempRem = new REMINDERDATA();
TempRem->uid = CreateUid();
SystemTimeToFileTime(&Date, (FILETIME*)&TempRem->When);
- TempRem->szText = edtText.GetTextA();
+ TempRem->wszText = ptrW(edtText.GetText());
TempRem->bRepeat = chkRepeat.GetState();
TempRem->SoundSel = cmbSound.GetItemData(cmbSound.GetCurSel());
TempRem->RepeatSound = TempRem->SoundSel < 0 ? 0 : (UINT)RepeatSound;
@@ -1434,7 +1438,7 @@ public: arReminders.remove(m_pReminder);
SystemTimeToFileTime(&Date, (FILETIME*)&m_pReminder->When);
- m_pReminder->szText = ptrA(edtText.GetTextA());
+ m_pReminder->wszText = ptrW(edtText.GetText());
m_pReminder->bRepeat = chkRepeat.GetState();
m_pReminder->SoundSel = cmbSound.GetItemData(cmbSound.GetCurSel());
m_pReminder->RepeatSound = m_pReminder->SoundSel < 0 ? 0 : (UINT)RepeatSound;
@@ -1540,7 +1544,7 @@ class CReminderListDlg : public CDlgBase m_list.InsertItem(&lvTIt);
lvTIt.mask = LVIF_TEXT;
- wchar_t *S2 = GetPreviewString(pReminder->szText);
+ wchar_t *S2 = GetPreviewString(pReminder->wszText);
lvTIt.iItem = i;
lvTIt.iSubItem = 1;
lvTIt.pszText = S2;
@@ -1697,7 +1701,7 @@ public: void list_onItemChanged(CCtrlListView::TEventInfo *ev)
{
- SetDlgItemTextA(m_hwnd, IDC_REMINDERDATA, arReminders[ev->nmlv->iItem]->szText);
+ SetDlgItemTextW(m_hwnd, IDC_REMINDERDATA, arReminders[ev->nmlv->iItem]->wszText);
}
void list_onDblClick(CCtrlListView::TEventInfo*)
@@ -1793,7 +1797,7 @@ bool CheckRemindersAndStart(void) else {
char *p = strchr(g_RemindSMS, '@');
if (p) {
- Send(g_RemindSMS, p + 1, pReminder->szText, NULL);
+ Send(g_RemindSMS, p + 1, _T2A(pReminder->wszText), NULL);
*p = '@';
DeleteReminder(pReminder);
diff --git a/plugins/NotesAndReminders/src/stdafx.h b/plugins/NotesAndReminders/src/stdafx.h index 37d4382e78..c7107e60a0 100644 --- a/plugins/NotesAndReminders/src/stdafx.h +++ b/plugins/NotesAndReminders/src/stdafx.h @@ -61,7 +61,7 @@ struct CMPlugin : public PLUGIN<CMPlugin> extern void CreateMsgWindow(void); extern void DestroyMsgWindow(void); -void NewNote(int Ax, int Ay, int Aw, int Ah, const char *pszText, ULONGLONG *ID, BOOL Visible, BOOL bOnTop, int scrollV); +void NewNote(int Ax, int Ay, int Aw, int Ah, const wchar_t *pwszText, ULONGLONG *ID, BOOL Visible, BOOL bOnTop, int scrollV); void LoadNotes(bool bIsStartup); void SaveNotes(void); void DeleteNotes(void); |