mirror of
https://github.com/rizonesoft/Notepad3.git
synced 2026-06-11 21:03:05 +08:00
+ fix: Hyperlink detection for Unicode
+ fix: Insertion handling: keep selection if non empty selection is replaced
This commit is contained in:
parent
ac6a4371ac
commit
5ddfbc08ee
@ -1 +1 @@
|
||||
2607
|
||||
2609
|
||||
|
||||
@ -12,12 +12,18 @@
|
||||
* *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
#if !defined(_WIN32_WINNT)
|
||||
#define _WIN32_WINNT 0x601
|
||||
#if !defined(WINVER)
|
||||
#define WINVER 0x601 /*_WIN32_WINNT_WIN7*/
|
||||
#endif
|
||||
#define VC_EXTRALEAN 1
|
||||
//#define WIN32_LEAN_AND_MEAN 1
|
||||
//#define NOMINMAX 1
|
||||
#if !defined(_WIN32_WINNT)
|
||||
#define _WIN32_WINNT 0x601 /*_WIN32_WINNT_WIN7*/
|
||||
#endif
|
||||
#if !defined(NTDDI_VERSION)
|
||||
#define NTDDI_VERSION 0x06010000 /*NTDDI_WIN7*/
|
||||
#endif
|
||||
//~#define VC_EXTRALEAN 1
|
||||
//~#define WIN32_LEAN_AND_MEAN 1
|
||||
#define NOMINMAX 1
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlwapi.h>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<assemblyIdentity
|
||||
name="Notepad3"
|
||||
processorArchitecture="*"
|
||||
version="5.19.829.2607"
|
||||
version="5.19.830.2609"
|
||||
type="win32"
|
||||
/>
|
||||
<description>Notepad3 BETA</description>
|
||||
|
||||
34
src/Edit.c
34
src/Edit.c
@ -204,12 +204,13 @@ static void CALLBACK MQ_ExecuteNext(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWOR
|
||||
//
|
||||
// EditReplaceSelection()
|
||||
//
|
||||
void EditReplaceSelection(const char* text, bool bReselect)
|
||||
void EditReplaceSelection(const char* text, bool bForceSel)
|
||||
{
|
||||
_BEGIN_UNDO_ACTION_
|
||||
bool const bSelWasEmpty = SciCall_IsSelectionEmpty();
|
||||
DocPos const posSelBeg = SciCall_GetSelectionStart();
|
||||
SciCall_ReplaceSel(text);
|
||||
if (bReselect) {
|
||||
if (bForceSel || !bSelWasEmpty) {
|
||||
SciCall_SetSel(posSelBeg, SciCall_GetCurrentPos());
|
||||
}
|
||||
_END_UNDO_ACTION_
|
||||
@ -1754,30 +1755,26 @@ void EditURLEncode(HWND hwnd)
|
||||
|
||||
const char* pszText = (const char*)SciCall_GetRangePointer(min_p(iCurPos, iAnchorPos), iSelSize);
|
||||
|
||||
LPWSTR pszTextW = AllocMem(iSelSize * sizeof(WCHAR), HEAP_ZERO_MEMORY);
|
||||
if (pszTextW == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*int cchTextW =*/ MultiByteToWideChar(Encoding_SciCP, 0, pszText, (MBWC_DocPos_Cast)(iSelSize-1),
|
||||
pszTextW, (MBWC_DocPos_Cast)iSelSize);
|
||||
WCHAR szTextW[INTERNET_MAX_URL_LENGTH+1];
|
||||
int const cchTextW = MultiByteToWideChar(Encoding_SciCP, 0, pszText, (MBWC_DocPos_Cast)(iSelSize-1), szTextW, INTERNET_MAX_URL_LENGTH);
|
||||
szTextW[cchTextW] = L'\0';
|
||||
|
||||
size_t const cchEscaped = iSelSize * 3;
|
||||
char* pszEscaped = (char*)AllocMem(cchEscaped, HEAP_ZERO_MEMORY);
|
||||
if (pszEscaped == NULL) {
|
||||
FreeMem(pszTextW);
|
||||
return;
|
||||
}
|
||||
|
||||
LPWSTR pszEscapedW = (LPWSTR)AllocMem(cchEscaped * sizeof(WCHAR), HEAP_ZERO_MEMORY);
|
||||
if (pszEscapedW == NULL) {
|
||||
FreeMem(pszTextW);
|
||||
FreeMem(pszEscaped);
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD cchEscapedW = (DWORD)cchEscaped;
|
||||
UrlEscape(pszTextW, pszEscapedW, &cchEscapedW, URL_ESCAPE_SEGMENT_ONLY | URL_ESCAPE_PERCENT | URL_ESCAPE_AS_UTF8);
|
||||
DWORD const flags = (DWORD)(URL_ESCAPE_SEGMENT_ONLY | URL_ESCAPE_PERCENT | URL_ESCAPE_AS_UTF8);
|
||||
|
||||
UrlEscape(szTextW, pszEscapedW, &cchEscapedW, flags);
|
||||
|
||||
DWORD const cchEscapedEnc = WideCharToMultiByte(Encoding_SciCP, 0, pszEscapedW, cchEscapedW,
|
||||
pszEscaped, (MBWC_DocPos_Cast)cchEscaped, NULL, NULL);
|
||||
@ -1807,7 +1804,6 @@ void EditURLEncode(HWND hwnd)
|
||||
|
||||
_END_UNDO_ACTION_;
|
||||
|
||||
FreeMem(pszTextW);
|
||||
FreeMem(pszEscaped);
|
||||
FreeMem(pszEscapedW);
|
||||
}
|
||||
@ -2215,7 +2211,7 @@ void EditModifyNumber(HWND hwnd,bool bIncrease) {
|
||||
StringCchPrintfA(chFormat, COUNTOF(chFormat), "%%#0%ix", iWidth);
|
||||
|
||||
StringCchPrintfA(chNumber, COUNTOF(chNumber), chFormat, iNumber);
|
||||
EditReplaceSelection(chNumber,false);
|
||||
EditReplaceSelection(chNumber, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7151,9 +7147,13 @@ void EditUpdateIndicators(HWND hwnd, DocPos startPos, DocPos endPos, bool bClear
|
||||
|
||||
if (Settings.HyperlinkHotspot)
|
||||
{
|
||||
static const char* pUrlRegEx = "\\b(?:(?:https?|ftp|file)://|www\\.|ftp\\.)"
|
||||
"(?:\\([-A-Z0-9+&@#/%=~_|$?!:,.]*\\)|[-A-Z0-9+&@#/%=~_|$?!:,.])*"
|
||||
"(?:\\([-A-Z0-9+&@#/%=~_|$?!:,.]*\\)|[A-Z0-9+&@#/%=~_|$])";
|
||||
//static const char* pUrlRegEx = "\\b(?:(?:https?|ftp|file)://|www\\.|ftp\\.)"
|
||||
// "(?:\\([-a-z\\u00a1-\\uffff0-9+&@#/%=~_|$?!:,.]*\\)|[-a-z\\u00a1-\\uffff0-9+&@#/%=~_|$?!:,.])*"
|
||||
// "(?:\\([-a-z\\u00a1-\\uffff0-9+&@#/%=~_|$?!:,.]*\\)|[a-z\\u00a1-\\uffff0-9+&@#/%=~_|$])";
|
||||
|
||||
// https://mathiasbynens.be/demo/url-regex : @stephenhay
|
||||
static const char* pUrlRegEx = "\\b(?:(?:https?|ftp|file)://|www\\.|ftp\\.)[^\\s/$.?#].[^\\s]*";
|
||||
|
||||
_UpdateIndicators(hwnd, INDIC_NP3_HYPERLINK, INDIC_NP3_HYPERLINK_U, pUrlRegEx, startPos, endPos);
|
||||
}
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
#include "TypeDefs.h"
|
||||
|
||||
void EditInitializeSciCtrl(HWND);
|
||||
void EditReplaceSelection(const char* text, bool bReselect);
|
||||
void EditReplaceSelection(const char* text, bool bForceSel);
|
||||
void EditInitWordDelimiter(HWND hwnd);
|
||||
void EditSetNewText(HWND hwnd,const char* lpstrText,DocPos lenText,bool);
|
||||
bool EditConvertText(HWND hwnd, cpi_enc_t encSource, cpi_enc_t encDest,bool);
|
||||
|
||||
@ -4344,7 +4344,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
|
||||
cpi_enc_t const iEncoding = Encoding_Current(CPI_GET);
|
||||
char chEncStrg[128] = { '\0' };
|
||||
WideCharToMultiByte(Encoding_SciCP, 0, Encoding_GetLabel(iEncoding), -1, chEncStrg, COUNTOF(chEncStrg), NULL, NULL);
|
||||
EditReplaceSelection(chEncStrg, true);
|
||||
EditReplaceSelection(chEncStrg, false);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -4428,7 +4428,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
|
||||
StrTrimW(tchMaxPathBuffer, L"{}");
|
||||
char chMaxPathBuffer[MAX_PATH] = { '\0' };
|
||||
if (WideCharToMultiByte(Encoding_SciCP, 0, tchMaxPathBuffer, -1, chMaxPathBuffer, COUNTOF(chMaxPathBuffer), NULL, NULL)) {
|
||||
EditReplaceSelection(chMaxPathBuffer, true);
|
||||
EditReplaceSelection(chMaxPathBuffer, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6498,36 +6498,46 @@ bool HandleHotSpotURLClicked(const DocPos position, const HYPERLINK_OPS operatio
|
||||
|
||||
if (SciCall_IndicatorValueAt(INDIC_NP3_HYPERLINK, position) == 0) { return false; }
|
||||
|
||||
char chURL[HUGE_BUFFER] = { '\0' };
|
||||
|
||||
bool bHandled = false;
|
||||
DocPos const firstPos = SciCall_IndicatorStart(INDIC_NP3_HYPERLINK, position);
|
||||
DocPos const lastPos = SciCall_IndicatorEnd(INDIC_NP3_HYPERLINK, position);
|
||||
DocPos const length = min_p(lastPos - firstPos, COUNTOF(chURL));
|
||||
DocPos const length = min_p(lastPos - firstPos, INTERNET_MAX_URL_LENGTH);
|
||||
|
||||
StringCchCopyNA(chURL, COUNTOF(chURL), SciCall_GetRangePointer(firstPos, length), length);
|
||||
StrTrimA(chURL, " \t\n\r");
|
||||
const char* pszText = (const char*)SciCall_GetRangePointer(firstPos, length);
|
||||
|
||||
if (StrIsEmptyA(chURL)) { return bHandled; }
|
||||
WCHAR szTextW[INTERNET_MAX_URL_LENGTH+1];
|
||||
int const cchTextW = MultiByteToWideChar(Encoding_SciCP, 0, pszText, (MBWC_DocPos_Cast)length, szTextW, COUNTOF(szTextW));
|
||||
szTextW[cchTextW] = L'\0';
|
||||
|
||||
WCHAR wchURL[XHUGE_BUFFER] = { L'\0' };
|
||||
int const lenHypLnk = MultiByteToWideChar(Encoding_SciCP, 0, chURL, -1, wchURL, COUNTOF(wchURL)) - 1;
|
||||
const WCHAR* chkPreFix = L"file://";
|
||||
|
||||
if (operation & COPY_HYPERLINK)
|
||||
{
|
||||
if (lenHypLnk > 0) {
|
||||
SetClipboardTextW(Globals.hwndMain, wchURL, lenHypLnk);
|
||||
if (cchTextW > 0) {
|
||||
|
||||
LPWSTR pszEscapedW = (LPWSTR)AllocMem(length * 3 * sizeof(WCHAR), HEAP_ZERO_MEMORY);
|
||||
if (pszEscapedW == NULL) {
|
||||
return false;
|
||||
}
|
||||
DWORD cchEscapedW = (DWORD)(length * 3);
|
||||
DWORD const flags = (DWORD)(URL_BROWSER_MODE | URL_ESCAPE_AS_UTF8);
|
||||
UrlEscape(szTextW, pszEscapedW, &cchEscapedW, flags);
|
||||
|
||||
//SetClipboardTextW(Globals.hwndMain, szTextW, cchTextW);
|
||||
SetClipboardTextW(Globals.hwndMain, pszEscapedW, cchEscapedW);
|
||||
|
||||
FreeMem(pszEscapedW);
|
||||
bHandled = true;
|
||||
}
|
||||
}
|
||||
else if ((operation & OPEN_WITH_NOTEPAD3) && (StrStrIA(chURL, "file://") == chURL))
|
||||
else if ((operation & OPEN_WITH_NOTEPAD3) && (StrStrI(szTextW, chkPreFix) == szTextW))
|
||||
{
|
||||
const WCHAR* chkPreFix = L"file://";
|
||||
size_t const lenPfx = StringCchLenW(chkPreFix, 0);
|
||||
WCHAR* szFileName = &(wchURL[lenPfx]);
|
||||
WCHAR* szFileName = &(szTextW[lenPfx]);
|
||||
szTextW[lenPfx + MAX_PATH] = L'\0'; // limit length
|
||||
StrTrimW(szFileName, L"/");
|
||||
|
||||
PathCanonicalizeEx(szFileName, (DWORD)(COUNTOF(wchURL) - lenPfx));
|
||||
PathCanonicalizeEx(szFileName, (DWORD)(COUNTOF(szTextW) - lenPfx));
|
||||
if (PathIsDirectory(szFileName))
|
||||
{
|
||||
WCHAR tchFile[MAX_PATH] = { L'\0' };
|
||||
@ -6555,7 +6565,7 @@ bool HandleHotSpotURLClicked(const DocPos position, const HYPERLINK_OPS operatio
|
||||
sei.fMask = SEE_MASK_NOZONECHECKS;
|
||||
sei.hwnd = NULL;
|
||||
sei.lpVerb = NULL;
|
||||
sei.lpFile = wchURL;
|
||||
sei.lpFile = szTextW;
|
||||
sei.lpParameters = NULL;
|
||||
sei.lpDirectory = wchDirectory;
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
|
||||
@ -601,6 +601,12 @@ typedef struct _docviewpos_t
|
||||
|
||||
#define NOTEPAD3_MODULE_DIR_ENV_VAR L"NOTEPAD3MODULEDIR"
|
||||
|
||||
// from <wininet.h>
|
||||
#define INTERNET_MAX_PATH_LENGTH 2048
|
||||
#define INTERNET_MAX_SCHEME_LENGTH 32 // longest protocol name length
|
||||
#define INTERNET_MAX_URL_LENGTH (INTERNET_MAX_SCHEME_LENGTH \
|
||||
+ sizeof("://") \
|
||||
+ INTERNET_MAX_PATH_LENGTH)
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
@ -7,8 +7,8 @@
|
||||
#define SAPPNAME "Notepad3"
|
||||
#define VERSION_MAJOR 5
|
||||
#define VERSION_MINOR 19
|
||||
#define VERSION_REV 829
|
||||
#define VERSION_BUILD 2607
|
||||
#define VERSION_REV 830
|
||||
#define VERSION_BUILD 2609
|
||||
#define SCINTILLA_VER 420
|
||||
#define ONIGURUMA_REGEX_VER 6.9.3
|
||||
#define UCHARDET_VER 2018.09.27
|
||||
|
||||
@ -2,6 +2,11 @@
|
||||
# https://github.com/toml-lang/toml
|
||||
#
|
||||
|
||||
# https://fr.wikipedia.org/wiki/Caractères_de_civilité
|
||||
# https://fr.wikipedia.org/wiki/Caract%C3%A8res_de_civilit%C3%A9
|
||||
#
|
||||
|
||||
|
||||
title = "TOML Example"
|
||||
|
||||
[owner]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user