diff --git a/src/Edit.c b/src/Edit.c index 308c00aec..92da95cac 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -1034,13 +1034,11 @@ bool EditLoadFile( // -------------------------------------------------------------------------- bool bIsReliable = false; - int const iAnalyzedEncoding_CED = Encoding_Analyze_CED(lpData, cbNbytes4Analysis, iPreferedEncoding, &bIsReliable); - char origUCHARDET[256] = { '\0' }; float confidence = 0.50f; // reliable ? - int iAnalyzedEncoding = Encoding_Analyze_UCHARDET(lpData, cbNbytes4Analysis, iPreferedEncoding, &confidence, origUCHARDET, 256); - + int iAnalyzedEncoding = Encoding_Analyze_UCHARDET(lpData, cbNbytes4Analysis, &confidence, origUCHARDET, 256); + int const iAnalyzedEncoding_CED = Encoding_Analyze_CED(lpData, cbNbytes4Analysis, iPreferedEncoding, &bIsReliable); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1077,11 +1075,40 @@ bool EditLoadFile( /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // ------------------------------------------------------ + // calculate reliability + float const reliability_threshold = 0.50f; + float const ced_confidence = bIsReliable ? reliability_threshold + 0.25f : 0.25f; + if (iAnalyzedEncoding == iAnalyzedEncoding_CED) { + if (!Encoding_IsNONE(iAnalyzedEncoding)) { + confidence = (confidence + ced_confidence + 0.25f) / 2.0f; + } + } + else { // ambiguous results + if (Encoding_IsNONE(iAnalyzedEncoding)) { + // no UCHARDET rely on CED + iAnalyzedEncoding = iAnalyzedEncoding_CED; + confidence = ced_confidence; + } + else { // have UCHARDET result + if (!Encoding_IsNONE(iAnalyzedEncoding_CED)) + { + if (confidence < ced_confidence) { + iAnalyzedEncoding = iAnalyzedEncoding_CED; + confidence = ced_confidence; + } + else if ((confidence < ced_confidence) && bIsReliable) { + iAnalyzedEncoding = iAnalyzedEncoding_CED; // prefer CED + confidence = (confidence + ced_confidence) / 2.0f; + } + } + } + } + bIsReliable = (confidence >= reliability_threshold); + // ------------------------------------------------------ - bIsReliable = (confidence >= 0.50f); - if (!g_bForceCompEncDetection) { bool const bIsUnicode = Encoding_IsUTF8(iAnalyzedEncoding) || Encoding_IsUNICODE(iAnalyzedEncoding); diff --git a/src/Encoding.h b/src/Encoding.h index 6d041ad84..9077b6b26 100644 --- a/src/Encoding.h +++ b/src/Encoding.h @@ -126,7 +126,7 @@ bool IsValidUTF8(const char* pTest, size_t nLength); extern NP2ENCODING g_Encodings[]; void ChangeEncodingCodePage(int cpi, UINT newCP); int Encoding_Analyze_CED(const char* text, size_t len, int encodingHint, bool* pIsReliable); -int Encoding_Analyze_UCHARDET(const char* text, size_t len, int encodingHint, float* pConfidence, char* origUCHARDET, int cch); +int Encoding_Analyze_UCHARDET(const char* text, size_t len, float* pConfidence, char* origUCHARDET, int cch); // 932 Shift-JIS, 936 GBK, 949 UHC, 950 Big5, 1361 Johab inline bool IsDBCSCodePage(UINT cp) { diff --git a/src/EncodingDetection.cpp b/src/EncodingDetection.cpp index 30f9dc530..af6f6ca71 100644 --- a/src/EncodingDetection.cpp +++ b/src/EncodingDetection.cpp @@ -554,18 +554,18 @@ extern "C" int Encoding_Analyze_CED(const char* const text, const size_t len, co // UCHARDET // ============================================================================ -static int _MapUCARDETEncoding2CPI(const char* const text, const size_t len, - const int encodingHint, const char* charset, float* pConfidence) +static int _MapUCARDETEncoding2CPI(const char* const text, const size_t len, const char* charset, float* pConfidence) { (void)text; // UNUSED (void)len; // UNUSED + int cpiEncoding = CPI_NONE; + if (!charset || (charset[0] == '\0')) { *pConfidence = 0.0f; - return encodingHint; + return cpiEncoding; } - int cpiEncoding = CPI_NONE; // preprocessing: special cases if (_stricmp(charset, "ascii") == 0) { @@ -587,16 +587,16 @@ static int _MapUCARDETEncoding2CPI(const char* const text, const size_t len, if (cpiEncoding == CPI_NONE) { *pConfidence = 0.0f; - cpiEncoding = encodingHint; } + *pConfidence = 0.0f; return cpiEncoding; } // ============================================================================ extern "C" int Encoding_Analyze_UCHARDET(const char* const text, const size_t len, - const int encodingHint, float* pConfidence, char* origUCHARDET, int cch) + float* pConfidence, char* origUCHARDET, int cch) { int encoding = CPI_NONE; float confidence = 0.0f; @@ -616,7 +616,7 @@ extern "C" int Encoding_Analyze_UCHARDET(const char* const text, const size_t le StringCchCopyA(origUCHARDET, cch, charset); // UCHARDET confidence = uchardet_get_confidence(hUcharDet); - encoding = _MapUCARDETEncoding2CPI(text, len, encodingHint, charset, &confidence); + encoding = _MapUCARDETEncoding2CPI(text, len, charset, &confidence); } break; diff --git a/src/Notepad3.c b/src/Notepad3.c index 5461c6147..bbeee01f3 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -3371,7 +3371,9 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) if (s_flagPasteBoard) { s_bLastCopyFromMe = true; } - SciCall_CopyAllowLine(); + if (!HandleHotSpotURL(SciCall_GetCurrentPos(), COPY_HYPERLINK)) { + SciCall_CopyAllowLine(); + } UpdateToolbar(); break; @@ -5568,7 +5570,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) case CMD_OPEN_HYPERLINK: - OpenHotSpotURL(SciCall_GetCurrentPos(), false); + HandleHotSpotURL(SciCall_GetCurrentPos(), OPEN_WITH_BROWSER); break; @@ -5843,15 +5845,17 @@ LRESULT MsgSysCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) //============================================================================= // -// OpenHotSpotURL() +// HandleHotSpotURL() // // -void OpenHotSpotURL(DocPos position, bool bForceBrowser) +bool HandleHotSpotURL(DocPos position, HYPERLINK_OPS operation) { + bool bHandled = false; + char const cStyle = SciCall_GetStyleAt(position); int const iStyleID = Style_GetHotspotStyleID(); - if (!SciCall_StyleGetHotspot(iStyleID) || (cStyle != (char)iStyleID)) { return; } + if (!SciCall_StyleGetHotspot(iStyleID) || (cStyle != (char)iStyleID)) { return bHandled; } // get left most position of style DocPos pos = position; @@ -5878,20 +5882,27 @@ void OpenHotSpotURL(DocPos position, bool bForceBrowser) StringCchCopyNA(chURL, XHUGE_BUFFER, SciCall_GetRangePointer(firstPos, length), length); StrTrimA(chURL, " \t\n\r"); - if (!StringCchLenA(chURL, COUNTOF(chURL))) { return; } + if (!StringCchLenA(chURL, COUNTOF(chURL))) { return bHandled; } - WCHAR wchURL[HUGE_BUFFER] = { L'\0' }; - MultiByteToWideChar(Encoding_SciCP, 0, chURL, -1, wchURL, HUGE_BUFFER); + WCHAR wchURL[XHUGE_BUFFER] = { L'\0' }; + int const lenHypLnk = MultiByteToWideChar(Encoding_SciCP, 0, chURL, -1, wchURL, XHUGE_BUFFER) - 1; const WCHAR* chkPreFix = L"file://"; - size_t const len = StringCchLenW(chkPreFix,0); + size_t const lenPfx = StringCchLenW(chkPreFix,0); - if (!bForceBrowser && (StrStrIW(wchURL, chkPreFix) == wchURL)) + if (operation & COPY_HYPERLINK) { - WCHAR* szFileName = &(wchURL[len]); + if (lenHypLnk > 0) { + SetClipboardTextW(Globals.hwndMain, wchURL, lenHypLnk); + bHandled = true; + } + } + if ((operation & OPEN_WITH_NOTEPAD3) && (StrStrIW(wchURL, chkPreFix) == wchURL)) + { + WCHAR* szFileName = &(wchURL[lenPfx]); StrTrimW(szFileName, L"/"); - PathCanonicalizeEx(szFileName, COUNTOF(wchURL) - (int)len); + PathCanonicalizeEx(szFileName, COUNTOF(wchURL) - (int)lenPfx); if (PathIsDirectory(szFileName)) { @@ -5900,12 +5911,13 @@ void OpenHotSpotURL(DocPos position, bool bForceBrowser) if (OpenFileDlg(Globals.hwndMain, tchFile, COUNTOF(tchFile), szFileName)) FileLoad(false, false, false, Settings.SkipUnicodeDetection, Settings.SkipANSICodePageDetection, tchFile); } - else + else { FileLoad(false, false, false, Settings.SkipUnicodeDetection, Settings.SkipANSICodePageDetection, szFileName); - + } + bHandled = true; } - else { // open in web browser - + else if (operation & (OPEN_WITH_NOTEPAD3 | OPEN_WITH_NOTEPAD3)) // open in web browser + { WCHAR wchDirectory[MAX_PATH] = { L'\0' }; if (StringCchLenW(Globals.CurrentFile, COUNTOF(Globals.CurrentFile))) { StringCchCopy(wchDirectory, COUNTOF(wchDirectory), Globals.CurrentFile); @@ -5924,9 +5936,10 @@ void OpenHotSpotURL(DocPos position, bool bForceBrowser) sei.nShow = SW_SHOWNORMAL; ShellExecuteEx(&sei); + bHandled = true; } - } + return bHandled; } @@ -6262,11 +6275,11 @@ LRESULT MsgNotify(HWND hwnd, WPARAM wParam, LPARAM lParam) { if (scn->modifiers & SCMOD_CTRL) { // open in browser - OpenHotSpotURL((int)scn->position, true); + HandleHotSpotURL((int)scn->position, OPEN_WITH_BROWSER); } if (scn->modifiers & SCMOD_ALT) { // open in application, if applicable (file://) - OpenHotSpotURL((int)scn->position, false); + HandleHotSpotURL((int)scn->position, OPEN_WITH_NOTEPAD3); } } break; diff --git a/src/Notepad3.h b/src/Notepad3.h index 5eaf29bdf..e463cabb8 100644 --- a/src/Notepad3.h +++ b/src/Notepad3.h @@ -152,7 +152,7 @@ void RestoreAction(int token, DoAction doAct); #define _END_UNDO_ACTION_ } __finally { EndUndoAction(_token_); } } -void OpenHotSpotURL(DocPos position, bool bForceBrowser); +bool HandleHotSpotURL(DocPos position, HYPERLINK_OPS operation); bool IsFindPatternEmpty(); void SetFindPattern(LPCWSTR wchFindPattern); diff --git a/src/TypeDefs.h b/src/TypeDefs.h index d384f727d..2aa359946 100644 --- a/src/TypeDefs.h +++ b/src/TypeDefs.h @@ -90,6 +90,7 @@ inline RECT RectFromWinInfo(const WININFO* const pWinInfo) { // ---------------------------------------------------------------------------- typedef enum { BACKGROUND_LAYER = 0, FOREGROUND_LAYER = 1 } COLOR_LAYER; // Style_GetColor() +typedef enum { OPEN_WITH_BROWSER = 1, OPEN_WITH_NOTEPAD3 = 2, COPY_HYPERLINK = 4 } HYPERLINK_OPS; // Hyperlink Operations // ----------------------------------------------------------------------------