summaryrefslogtreecommitdiff
path: root/plugins/NotesAndReminders/src
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2021-03-17 21:07:56 +0300
committerGeorge Hazan <ghazan@miranda.im>2021-03-17 21:07:56 +0300
commit9df250ccbd2192ad3f0906e3714e97fa880f9882 (patch)
tree8b5120d8fccc75fd84a70802592ceccd59d7b1bb /plugins/NotesAndReminders/src
parent2d712275e2ecf08e106fa93783767a6587a31e5a (diff)
fixes #2778 (Notes and Reminders: плагину требуется доза Unicode)
Diffstat (limited to 'plugins/NotesAndReminders/src')
-rw-r--r--plugins/NotesAndReminders/src/notes.cpp84
-rw-r--r--plugins/NotesAndReminders/src/reminders.cpp32
-rw-r--r--plugins/NotesAndReminders/src/stdafx.h2
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);