diff --git a/language/common_res.h b/language/common_res.h index 8c1c05f89..6d6cea70d 100644 --- a/language/common_res.h +++ b/language/common_res.h @@ -667,34 +667,35 @@ #define IDM_EDIT_URLDECODE 40361 #define IDM_EDIT_BASE64ENCODE 40362 #define IDM_EDIT_BASE64DECODE 40363 -#define IDM_EDIT_URL2PATH 40364 -#define IDM_EDIT_PATH2URL 40365 -#define IDM_EDIT_INVERTSLASH 40366 -#define IDM_EDIT_INVERTBACKSLASH 40367 -#define IDM_EDIT_ESCAPECCHARS 40368 -#define IDM_EDIT_UNESCAPECCHARS 40369 -#define IDM_EDIT_CHAR2HEX 40370 -#define IDM_EDIT_HEX2CHAR 40371 -#define IDM_EDIT_FINDMATCHINGBRACE 40372 -#define IDM_EDIT_SELTOMATCHINGBRACE 40373 -#define IDM_EDIT_FIND 40374 -#define IDM_EDIT_SAVEFIND 40375 -#define IDM_EDIT_FINDNEXT 40376 -#define IDM_EDIT_FINDPREV 40377 -#define IDM_EDIT_REPLACE 40378 -#define IDM_EDIT_REPLACENEXT 40379 -#define IDM_EDIT_GOTOLINE 40380 -#define IDM_EDIT_SELTONEXT 40381 -#define IDM_EDIT_SELTOPREV 40382 -#define IDM_EDIT_COMPLETEWORD 40383 -#define IDM_EDIT_JOINLN_NOSP 40384 -#define IDM_EDIT_REMOVEDUPLICATELINES 40385 -#define IDM_EDIT_REMOVEEMPTYLINES 40386 -#define IDM_EDIT_MERGEEMPTYLINES 40387 -#define IDM_EDIT_CLEAR_MARKER 40388 -#define IDM_EDIT_CUT_MARKED 40389 -#define IDM_EDIT_COPY_MARKED 40390 -#define IDM_EDIT_DELETE_MARKED 40391 +#define IDM_EDIT_B64DECODESEL 40364 +#define IDM_EDIT_URL2PATH 40365 +#define IDM_EDIT_PATH2URL 40366 +#define IDM_EDIT_INVERTSLASH 40367 +#define IDM_EDIT_INVERTBACKSLASH 40368 +#define IDM_EDIT_ESCAPECCHARS 40369 +#define IDM_EDIT_UNESCAPECCHARS 40370 +#define IDM_EDIT_CHAR2HEX 40371 +#define IDM_EDIT_HEX2CHAR 40372 +#define IDM_EDIT_FINDMATCHINGBRACE 40373 +#define IDM_EDIT_SELTOMATCHINGBRACE 40374 +#define IDM_EDIT_FIND 40375 +#define IDM_EDIT_SAVEFIND 40376 +#define IDM_EDIT_FINDNEXT 40377 +#define IDM_EDIT_FINDPREV 40378 +#define IDM_EDIT_REPLACE 40379 +#define IDM_EDIT_REPLACENEXT 40380 +#define IDM_EDIT_GOTOLINE 40381 +#define IDM_EDIT_SELTONEXT 40382 +#define IDM_EDIT_SELTOPREV 40383 +#define IDM_EDIT_COMPLETEWORD 40384 +#define IDM_EDIT_JOINLN_NOSP 40385 +#define IDM_EDIT_REMOVEDUPLICATELINES 40386 +#define IDM_EDIT_REMOVEEMPTYLINES 40387 +#define IDM_EDIT_MERGEEMPTYLINES 40388 +#define IDM_EDIT_CLEAR_MARKER 40389 +#define IDM_EDIT_CUT_MARKED 40390 +#define IDM_EDIT_COPY_MARKED 40391 +#define IDM_EDIT_DELETE_MARKED 40392 #define IDM_VIEW_SCHEME 41000 #define IDM_VIEW_USE2NDDEFAULT 41001 diff --git a/language/np3_de_de/menu_de_de.rc b/language/np3_de_de/menu_de_de.rc index 701969e84..61f23fcba 100644 --- a/language/np3_de_de/menu_de_de.rc +++ b/language/np3_de_de/menu_de_de.rc @@ -265,6 +265,7 @@ BEGIN MENUITEM SEPARATOR MENUITEM "Base&64 Codierung", IDM_EDIT_BASE64ENCODE MENUITEM "Base6&4 Decodierung", IDM_EDIT_BASE64DECODE + MENUITEM "Base64 Decodiere als ...", IDM_EDIT_B64DECODESEL MENUITEM SEPARATOR MENUITEM "&URL Codierung\tCtrl+Shift+E", IDM_EDIT_URLENCODE MENUITEM "URL Decodierung\tCtrl+Shift+R", IDM_EDIT_URLDECODE diff --git a/language/np3_en_us/menu_en_us.rc b/language/np3_en_us/menu_en_us.rc index ba28b7cdb..4b688ee83 100644 --- a/language/np3_en_us/menu_en_us.rc +++ b/language/np3_en_us/menu_en_us.rc @@ -265,6 +265,7 @@ BEGIN MENUITEM SEPARATOR MENUITEM "Base&64 Encode", IDM_EDIT_BASE64ENCODE MENUITEM "Base6&4 Decode", IDM_EDIT_BASE64DECODE + MENUITEM "Base64 Decode to codepage ...", IDM_EDIT_B64DECODESEL MENUITEM SEPARATOR MENUITEM "URL &Encode\tCtrl+Shift+E", IDM_EDIT_URLENCODE MENUITEM "URL &Decode\tCtrl+Shift+R", IDM_EDIT_URLDECODE diff --git a/src/Edit.c b/src/Edit.c index dae7f1827..8f8a574d4 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -1981,8 +1981,9 @@ void EditReplaceAllChr(const WCHAR chSearch, const WCHAR chReplace) { //============================================================================= // // EditBase64Code() +// Base64 encoding is within 7-bit-ASCII identical to UTF-8 code-page // -void EditBase64Code(HWND hwnd, const bool bEncode) { +void EditBase64Code(HWND hwnd, const bool bEncode, cpi_enc_t cpi) { UNREFERENCED_PARAMETER(hwnd); @@ -1993,24 +1994,79 @@ void EditBase64Code(HWND hwnd, const bool bEncode) { InfoBoxLng(MB_ICONWARNING, NULL, IDS_MUI_SELRECTORMULTI); return; } - - _SAVE_TARGET_RANGE_; + bool const bDecode = !bEncode; + UINT const codePage = Encoding_GetCodePage(cpi); DocPos const iSelStart = SciCall_GetSelectionStart(); //DocPos const iSelEnd = SciCall_GetSelectionEnd(); - size_t const iSelSize = SciCall_GetSelText(NULL) - 1; // w/o terminating zero bool const bStraightSel = (SciCall_GetAnchor() <= SciCall_GetCurrentPos()); - const unsigned char *pchText = (unsigned char *)SciCall_GetRangePointer(iSelStart, (DocPos)iSelSize); + size_t iSelSize = SciCall_GetSelText(NULL) - 1; // w/o terminating zero + unsigned char * pchText = (unsigned char *)SciCall_GetRangePointer(iSelStart, (DocPos)iSelSize); + bool bAllocatedText = false; - size_t coded_size = 0; - char *const pBase64CodedTxt = (char *)(bEncode ? Encoding_Base64Encode(pchText, iSelSize, &coded_size) : - Encoding_Base64Decode(pchText, iSelSize, &coded_size)); + if (bEncode && (codePage != Encoding_SciCP)) { + // TODO: convert to WCHAR, convert to cpi encoding, encode base64 + WCHAR * wchText = (WCHAR *)AllocMem((iSelSize + 1) * sizeof(WCHAR), HEAP_ZERO_MEMORY); // should be large enough + if (wchText) { + int const cwchTxt = MultiByteToWideChar(Encoding_SciCP, 0, (LPCCH)pchText, (int)iSelSize, wchText, (int)iSelSize); + // allocate conversion buffer for desired encoding + int const cmbchTxt = WideCharToMultiByte(codePage, 0, wchText, cwchTxt, NULL, 0, NULL, NULL); + pchText = (unsigned char *)AllocMem(cmbchTxt + 1, HEAP_ZERO_MEMORY); + if (pchText) { + iSelSize = (size_t)WideCharToMultiByte(codePage, 0, wchText, cwchTxt, (LPCH)pchText, cmbchTxt, NULL, NULL); + bAllocatedText = true; + } else { + iSelSize = 0ULL; + } + FreeMem(wchText); + } else { + iSelSize = 0ULL; + } + } + if (iSelSize == 0) { + if (bAllocatedText) { + FreeMem(pchText); + } + return; + } + + size_t base64Size = 0; + char * pBase64CodedTxt = (char *)(bEncode ? Encoding_Base64Encode(pchText, iSelSize, &base64Size) : + Encoding_Base64Decode(pchText, iSelSize, &base64Size)); + + if (bAllocatedText) { + FreeMem(pchText); + } + + if (bDecode && (codePage != Encoding_SciCP)) { + // don't care if input is really a valid Base64 encoded byte-stream + WCHAR *wchText = (WCHAR *)AllocMem((base64Size + 1) * sizeof(WCHAR), HEAP_ZERO_MEMORY); // should be large enough + if (wchText) { + int const cwchTxt = MultiByteToWideChar(codePage, 0, pBase64CodedTxt, (int)base64Size, wchText, (int)base64Size); + // convert to SCI Encoding (UTF-8) + int const cmbchTxt = WideCharToMultiByte(Encoding_SciCP, 0, wchText, cwchTxt, NULL, 0, NULL, NULL); + FreeMem(pBase64CodedTxt); + pBase64CodedTxt = (char *)AllocMem(cmbchTxt + 1, HEAP_ZERO_MEMORY); + if (pBase64CodedTxt) { + base64Size = (size_t)WideCharToMultiByte(Encoding_SciCP, 0, wchText, cwchTxt, pBase64CodedTxt, cmbchTxt, NULL, NULL); + } else { + base64Size = 0ULL; + } + FreeMem(wchText); + } else { + base64Size = 0ULL; + } + } + + _SAVE_TARGET_RANGE_; UndoTransActionBegin(); SciCall_TargetFromSelection(); - DocPos const len = SciCall_ReplaceTarget((DocPos)coded_size, pBase64CodedTxt); + + DocPos const len = (base64Size ? SciCall_ReplaceTarget(base64Size, pBase64CodedTxt) : SciCall_ReplaceTarget(0, "")); + FreeMem(pBase64CodedTxt); SciCall_SetSelectionStart(iSelStart); SciCall_SetSelectionEnd(iSelStart + len); @@ -2023,7 +2079,6 @@ void EditBase64Code(HWND hwnd, const bool bEncode) { _RESTORE_TARGET_RANGE_; - FreeMem(pBase64CodedTxt); } diff --git a/src/Edit.h b/src/Edit.h index 782d4f096..d1b4818bc 100644 --- a/src/Edit.h +++ b/src/Edit.h @@ -48,7 +48,7 @@ void EditSentenceCase(HWND hwnd); void EditURLEncode(const bool isPathConvert); void EditURLDecode(const bool isPathConvert); void EditReplaceAllChr(const WCHAR chSearch, const WCHAR chReplace); -void EditBase64Code(HWND hwnd, const bool bEncode); +void EditBase64Code(HWND hwnd, const bool bEncode, cpi_enc_t cpi); void EditEscapeCChars(HWND hwnd); void EditUnescapeCChars(HWND hwnd); void EditChar2Hex(HWND hwnd); diff --git a/src/Notepad3.c b/src/Notepad3.c index d6812f59c..90017b2c1 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -3626,6 +3626,7 @@ LRESULT MsgInitMenu(HWND hwnd, WPARAM wParam, LPARAM lParam) EnableCmd(hmenu, IDM_EDIT_URLDECODE, !se && !ro); EnableCmd(hmenu, IDM_EDIT_BASE64ENCODE, !se && !ro); EnableCmd(hmenu, IDM_EDIT_BASE64DECODE, !se && !ro); + EnableCmd(hmenu, IDM_EDIT_B64DECODESEL, !se && !ro); EnableCmd(hmenu, IDM_EDIT_PATH2URL, !se && !ro); EnableCmd(hmenu, IDM_EDIT_URL2PATH, !se && !ro); EnableCmd(hmenu, IDM_EDIT_INVERTBACKSLASH, !se && !ro); @@ -4882,17 +4883,28 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) case IDM_EDIT_URLDECODE: { EditURLDecode(false); - } break; + } + break; case IDM_EDIT_BASE64ENCODE: { - EditBase64Code(Globals.hwndEdit, true); + EditBase64Code(Globals.hwndEdit, true, Encoding_GetCurrent()); } break; case IDM_EDIT_BASE64DECODE: { - EditBase64Code(Globals.hwndEdit, false); - } break; + EditBase64Code(Globals.hwndEdit, false, Encoding_GetCurrent()); + } + break; + + case IDM_EDIT_B64DECODESEL: { + cpi_enc_t iEncoding = Encoding_GetCurrent(); + if (!SelectEncodingDlg(hwnd, &iEncoding)) { + break; // no selection + } + EditBase64Code(Globals.hwndEdit, false, iEncoding); + } + break; case IDM_EDIT_URL2PATH: {