+ feature: URL Hotspot (first version)

This commit is contained in:
Rainer Kottenhoff 2017-12-07 15:13:29 +01:00
parent f5d9515da3
commit f8111bce7a
5 changed files with 152 additions and 3 deletions

View File

@ -189,7 +189,6 @@ HWND EditCreate(HWND hwndParent)
SendMessage(hwnd, SCI_INDICSETALPHA, INDIC_NP3_BAD_BRACE, 120);
SendMessage(hwnd, SCI_INDICSETOUTLINEALPHA, INDIC_NP3_BAD_BRACE, 120);
// word delimiter handling
EditInitWordDelimiter(hwnd);
EditSetAccelWordNav(hwnd,bAccelWordNavigation);
@ -5793,6 +5792,57 @@ void EditCompleteWord(HWND hwnd, BOOL autoInsert) {
}
//=============================================================================
//
// EditUpdateUrlHotspots()
// Find and mark all URL hot-spots
//
void EditUpdateUrlHotspots(HWND hwnd, tPos startPos, tPos endPos)
{
const char* pszUrlRegEx = "\\b(?:(?:https?|ftp|file)://|www\\.|ftp\\.)"
"(?:\\([-A-Z0-9+&@#/%=~_|$?!:,.]*\\)|[-A-Z0-9+&@#/%=~_|$?!:,.])*"
"(?:\\([-A-Z0-9+&@#/%=~_|$?!:,.]*\\)|[A-Z0-9+&@#/%=~_|$])";
const int iRegExLen = (int)strlen(pszUrlRegEx);
tPos posCurr = (tPos)SendMessage(hwnd, SCI_GETCURRENTPOS, 0, 0);
tPos posTextLength = (tPos)SendMessage(hwnd, SCI_GETTEXTLENGTH, 0, 0);
if ((startPos < 0) || (startPos >= posTextLength))
{
tPos cln = (tPos)SendMessage(hwnd, SCI_LINEFROMPOSITION, posCurr, 0);
startPos = (tPos)SendMessage(hwnd, SCI_POSITIONFROMLINE, cln-1, 0);
}
if ((endPos < 0) || (endPos >= posTextLength)) {
tPos cln = (tPos)SendMessage(hwnd, SCI_LINEFROMPOSITION, posCurr, 0);
endPos = (tPos)SendMessage(hwnd, SCI_GETLINEENDPOSITION, cln+1, 0);
}
int start = (int)startPos;
int end = (int)endPos;
int flags = SCFIND_NP3_REGEX;
while (TRUE)
{
int iPos = EditFindInTarget(hwnd, pszUrlRegEx, iRegExLen, flags, &start, &end, (end == start));
if (iPos < 0)
break; // not found
// mark this match
SendMessage(hwnd, SCI_STARTSTYLING, iPos, 0);
SendMessage(hwnd, SCI_SETSTYLING, (end - start), STYLE_NP3_ID_HOTSPOT);
start = end;
end = (int)endPos;
if (start >= end)
break;
}
}
//=============================================================================
//
// EditHighlightIfBrace()

View File

@ -20,6 +20,11 @@
BOOL Scintilla_RegisterClasses(void*);
BOOL Scintilla_ReleaseResources();
//typedef Sci_Position tPos;
typedef ptrdiff_t tPos;
#define FNDRPL_BUFFER 512
typedef struct _editfindreplace
{
@ -51,6 +56,9 @@ typedef struct _editfindreplace
#define INDIC_NP3_MATCH_BRACE 2
#define INDIC_NP3_BAD_BRACE 3
#define STYLE_NP3_ID_HOTSPOT 222
HWND EditCreate(HWND);
void EditInitWordDelimiter(HWND);
void EditSetNewText(HWND,char*,DWORD);
@ -119,6 +127,7 @@ void EditPrintInit();
void EditMatchBrace(HWND);
void EditClearAllMarks(HWND);
void EditMarkAll(HWND,char*,int,BOOL,BOOL);
void EditUpdateUrlHotspots(HWND, tPos, tPos);
void EditSetAccelWordNav(HWND,BOOL);
void EditCompleteWord(HWND,BOOL);
void EditGetBookmarkList(HWND,LPWSTR,int);

View File

@ -439,7 +439,6 @@ inline HRESULT PathCchCanonicalize(PWSTR p,size_t l,PCWSTR a) { UNUSED(l); re
inline HRESULT PathCchRenameExtension(PWSTR p,size_t l,PCWSTR a) { UNUSED(l); return (PathRenameExtension(p,a) ? S_OK : E_FAIL); }
inline HRESULT PathCchRemoveFileSpec(PWSTR p,size_t l) { UNUSED(l); return (PathRemoveFileSpec(p) ? S_OK : E_FAIL); }
// special Drag and Drop Handling
typedef struct tDROPDATA

View File

@ -5340,6 +5340,74 @@ LRESULT MsgCommand(HWND hwnd,WPARAM wParam,LPARAM lParam)
}
//=============================================================================
//
// OpenHotSpotURL() - Handles WM_NOTIFY
//
//
void OpenHotSpotURL(tPos position)
{
int iStyle = (int)SendMessage(hwndEdit, SCI_GETSTYLEAT, position, 0);
int iNewStyle = iStyle;
// get left most position of style
tPos pos = position;
while ((iNewStyle == iStyle) && (--pos > 0)) {
iNewStyle = (int)SendMessage(hwndEdit, SCI_GETSTYLEAT, pos, 0);
}
tPos firstPos = (pos != 0) ? (pos + 1) : 0;
// get right most position of style
pos = position;
iNewStyle = iStyle;
tPos posTextLength = (tPos)SendMessage(hwndEdit, SCI_GETTEXTLENGTH, 0, 0);
while ((iNewStyle == iStyle) && (++pos < posTextLength)) {
iNewStyle = (int)SendMessage(hwndEdit, SCI_GETSTYLEAT, pos, 0);
}
tPos lastPos = (pos - 1);
tPos length = lastPos - firstPos;
if ((length > 0) && (length < HUGE_BUFFER))
{
char chURL[HUGE_BUFFER] = { '\0' };
struct Sci_TextRange tr = { { 0, -1 }, NULL };
tr.chrg.cpMin = (Sci_PositionCR)firstPos;
tr.chrg.cpMax = (Sci_PositionCR)lastPos;
tr.lpstrText = chURL;
SendMessage(hwndEdit, SCI_GETTEXTRANGE, 0, (LPARAM)&tr);
StrTrimA(chURL, " \t\n\r");
if (StringCchLenA(chURL, COUNTOF(chURL)))
{
WCHAR wchURL[HUGE_BUFFER] = { L'\0' };
WCHAR wchDirectory[MAX_PATH] = { L'\0' };
MultiByteToWideCharStrg(Encoding_SciGetCodePage(hwndEdit), chURL, wchURL);
if (StringCchLenW(szCurFile, COUNTOF(szCurFile))) {
StringCchCopy(wchDirectory, COUNTOF(wchDirectory), szCurFile);
PathRemoveFileSpec(wchDirectory);
}
SHELLEXECUTEINFO sei;
ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.fMask = SEE_MASK_NOZONECHECKS;
sei.hwnd = NULL;
sei.lpVerb = NULL;
sei.lpFile = wchURL;
sei.lpParameters = NULL;
sei.lpDirectory = wchDirectory;
sei.nShow = SW_SHOWNORMAL;
ShellExecuteEx(&sei);
}
}
}
//=============================================================================
//
// MsgNotify() - Handles WM_NOTIFY
@ -5357,6 +5425,14 @@ LRESULT MsgNotify(HWND hwnd,WPARAM wParam,LPARAM lParam)
switch(pnmh->code)
{
case SCN_HOTSPOTCLICK:
{
if (scn->modifiers & SCMOD_CTRL) {
OpenHotSpotURL(scn->position);
}
}
break;
case SCN_UPDATEUI:
if (scn->updated & ~(SC_UPDATE_V_SCROLL | SC_UPDATE_H_SCROLL))
{
@ -5513,6 +5589,7 @@ LRESULT MsgNotify(HWND hwnd,WPARAM wParam,LPARAM lParam)
}
else if (bAutoCompleteWords && !SendMessage(hwndEdit, SCI_AUTOCACTIVE, 0, 0))
EditCompleteWord(hwndEdit, FALSE);
break;
case SCN_MODIFIED:
@ -5525,6 +5602,7 @@ LRESULT MsgNotify(HWND hwnd,WPARAM wParam,LPARAM lParam)
}
}
if (scn->linesAdded != 0) {
EditUpdateUrlHotspots(hwndEdit, -1, -1);
UpdateLineNumberWidth();
}
bModified = TRUE;
@ -7457,7 +7535,7 @@ BOOL FileLoad(BOOL bDontSave,BOOL bNew,BOOL bReload,BOOL bNoEncDetect,LPCWSTR lp
InstallFileWatching(szCurFile);
// the .LOG feature ...
if (SendMessage(hwndEdit,SCI_GETLENGTH,0,0) >= 4) {
if (SendMessage(hwndEdit,SCI_GETTEXTLENGTH,0,0) >= 4) {
char tchLog[5] = { '\0' };
SendMessage(hwndEdit,SCI_GETTEXT,5,(LPARAM)tchLog);
if (StringCchCompareXA(tchLog,".LOG") == 0) {
@ -7487,6 +7565,8 @@ BOOL FileLoad(BOOL bDontSave,BOOL bNew,BOOL bReload,BOOL bNoEncDetect,LPCWSTR lp
UpdateStatusbar();
UpdateLineNumberWidth();
EditUpdateUrlHotspots(hwndEdit, 0, (tPos)SendMessage(hwndEdit, SCI_GETTEXTLENGTH, 0, 0) - 1);
// consistent settings file handling (if loaded in editor)
bEnableSaveSettings = (StringCchCompareINW(szCurFile, COUNTOF(szCurFile), szIniFile, COUNTOF(szIniFile)) == 0) ? FALSE : TRUE;
UpdateSettingsCmds();

View File

@ -3559,6 +3559,17 @@ void Style_SetLexer(HWND hwnd, PEDITLEXER pLexNew) {
}
}
// Hot Spot settings
SendMessage(hwnd, SCI_STYLESETFORE, STYLE_NP3_ID_HOTSPOT, (LPARAM)RGB(0, 0, 200));
SendMessage(hwnd, SCI_STYLESETITALIC, STYLE_NP3_ID_HOTSPOT, (LPARAM)TRUE);
//SendMessage(hwnd, SCI_STYLESETUNDERLINE, iHotSpotStyle, (LPARAM)TRUE);
SendMessage(hwnd, SCI_STYLESETHOTSPOT, STYLE_NP3_ID_HOTSPOT, (LPARAM)TRUE);
SendMessage(hwnd, SCI_SETHOTSPOTACTIVEFORE, TRUE, (LPARAM)RGB(0, 0, 255));
SendMessage(hwnd, SCI_SETHOTSPOTACTIVEUNDERLINE, TRUE, 0);
SendMessage(hwnd, SCI_SETHOTSPOTSINGLELINE, TRUE, 0);
SendMessage(hwnd,SCI_COLOURISE,0,(LPARAM)-1);
// Save current lexer