[BUG_FIXED] (Author: Ivan Radić, aka Loreia) Fix link hotspot colourising issue.

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@970 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
Don Ho 2012-10-19 00:20:40 +00:00
parent a97b25ed92
commit 25ae135f82
11 changed files with 128 additions and 116 deletions

View File

@ -36,6 +36,8 @@ const bool dirDown = false;
#define NPP_CP_DOS_437 437 #define NPP_CP_DOS_437 437
#define NPP_CP_BIG5 950 #define NPP_CP_BIG5 950
#define LINKTRIGGERED WM_USER+555
#ifdef UNICODE #ifdef UNICODE
#define NppMainEntry wWinMain #define NppMainEntry wWinMain
#define generic_strtol wcstol #define generic_strtol wcstol

View File

@ -122,7 +122,7 @@ Notepad_plus::Notepad_plus(): _mainWindowStatus(0), _pDocTab(NULL), _pEditView(N
_pMainSplitter(NULL), _pMainSplitter(NULL),
_recordingMacro(false), _pTrayIco(NULL), _isUDDocked(false), _pFileSwitcherPanel(NULL), _recordingMacro(false), _pTrayIco(NULL), _isUDDocked(false), _pFileSwitcherPanel(NULL),
_pProjectPanel_1(NULL), _pProjectPanel_2(NULL), _pProjectPanel_3(NULL), _pDocMap(NULL), _pProjectPanel_1(NULL), _pProjectPanel_2(NULL), _pProjectPanel_3(NULL), _pDocMap(NULL),
_linkTriggered(true), _isDocModifing(false), _isHotspotDblClicked(false), _isFolding(false), _linkTriggered(true), _isHotspotDblClicked(false), _isFolding(false),
_sysMenuEntering(false), _sysMenuEntering(false),
_autoCompleteMain(&_mainEditView), _autoCompleteSub(&_subEditView), _smartHighlighter(&_findReplaceDlg), _autoCompleteMain(&_mainEditView), _autoCompleteSub(&_subEditView), _smartHighlighter(&_findReplaceDlg),
_isFileOpening(false), _rememberThisSession(true), _pAnsiCharPanel(NULL), _pClipboardHistoryPanel(NULL) _isFileOpening(false), _rememberThisSession(true), _pAnsiCharPanel(NULL), _pClipboardHistoryPanel(NULL)
@ -2025,40 +2025,12 @@ void Notepad_plus::setUniModeText()
} }
void Notepad_plus::addHotSpot(bool docIsModifing) void Notepad_plus::addHotSpot()
{ {
//bool docIsModifing = true; int startPos = 0;
int posBegin2style = 0; int endPos = -1;
if (docIsModifing)
posBegin2style = _pEditView->execute(SCI_GETCURRENTPOS);
int endStyle = _pEditView->execute(SCI_GETENDSTYLED); int endStyle = _pEditView->execute(SCI_GETENDSTYLED);
if (docIsModifing)
{
posBegin2style = _pEditView->execute(SCI_GETCURRENTPOS);
if (posBegin2style > 0) posBegin2style--;
UCHAR ch = (UCHAR)_pEditView->execute(SCI_GETCHARAT, posBegin2style);
// determinating the type of EOF to make sure how many steps should we be back
if ((ch == 0x0A) || (ch == 0x0D))
{
int eolMode = _pEditView->execute(SCI_GETEOLMODE);
if ((eolMode == SC_EOL_CRLF) && (posBegin2style > 1))
posBegin2style -= 2;
else if (posBegin2style > 0)
posBegin2style -= 1;
}
ch = (UCHAR)_pEditView->execute(SCI_GETCHARAT, posBegin2style);
while ((posBegin2style > 0) && ((ch != 0x0A) && (ch != 0x0D)))
{
ch = (UCHAR)_pEditView->execute(SCI_GETCHARAT, posBegin2style--);
}
}
int startPos = 0, endPos = -1;
_pEditView->getVisibleStartAndEndPosition(&startPos, &endPos); _pEditView->getVisibleStartAndEndPosition(&startPos, &endPos);
_pEditView->execute(SCI_SETSEARCHFLAGS, SCFIND_REGEXP|SCFIND_POSIX); _pEditView->execute(SCI_SETSEARCHFLAGS, SCFIND_REGEXP|SCFIND_POSIX);
@ -2066,9 +2038,30 @@ void Notepad_plus::addHotSpot(bool docIsModifing)
_pEditView->execute(SCI_SETTARGETSTART, startPos); _pEditView->execute(SCI_SETTARGETSTART, startPos);
_pEditView->execute(SCI_SETTARGETEND, endPos); _pEditView->execute(SCI_SETTARGETEND, endPos);
vector<pair<int, int> > hotspotStylers; std::vector<unsigned char> hotspotPairs; //= _pEditView->GetHotspotPairs();
unsigned char style_hotspot = 0;
unsigned char mask = INDIC1_MASK;
// INDIC2_MASK == 255 and it represents MSB bit
// only LEX_HTML and LEX_POSTSCRIPT use use INDIC2_MASK bit internally
// LEX_HTML is using INDIC2_MASK bit even though it has only 127 states, so it is safe to overwrite 8th bit
// INDIC2_MASK will be used for LEX_HTML
// LEX_POSTSCRIPT is using INDIC2_MASK bit for "tokenization", and is using mask=31 in lexer,
// therefore hotspot in LEX_POSTSCRIPT will be saved to 5th bit
// there are only 15 states in LEX_POSTSCRIPT, so it is safe to overwrite 5th bit
// rule of the thumb is, any lexet that calls: styler.StartAt(startPos, 255);
// must have special processing here, all other lexers are fine with INDIC1_MASK (7th bit)
LangType type = _pEditView->getCurrentBuffer()->getLangType();
if (type == L_HTML)
mask = INDIC2_MASK;
else if (type == L_PS)
mask = 16;
int style_hotspot = 30;
int posFound = _pEditView->execute(SCI_SEARCHINTARGET, strlen(URL_REG_EXPR), (LPARAM)URL_REG_EXPR); int posFound = _pEditView->execute(SCI_SEARCHINTARGET, strlen(URL_REG_EXPR), (LPARAM)URL_REG_EXPR);
while (posFound != -1) while (posFound != -1)
@ -2076,42 +2069,40 @@ void Notepad_plus::addHotSpot(bool docIsModifing)
int start = int(_pEditView->execute(SCI_GETTARGETSTART)); int start = int(_pEditView->execute(SCI_GETTARGETSTART));
int end = int(_pEditView->execute(SCI_GETTARGETEND)); int end = int(_pEditView->execute(SCI_GETTARGETEND));
int foundTextLen = end - start; int foundTextLen = end - start;
int idStyle = _pEditView->execute(SCI_GETSTYLEAT, posFound); unsigned char idStyle = static_cast<unsigned char>(_pEditView->execute(SCI_GETSTYLEAT, posFound));
if (end < posBegin2style - 1) // Search the style
{
if (style_hotspot > 24)
style_hotspot--;
}
else
{
int fs = -1; int fs = -1;
for (size_t i = 0 ; i < hotspotStylers.size() ; i++) for (size_t i = 0 ; i < hotspotPairs.size() ; i++)
{ {
if (hotspotStylers[i].second == idStyle) // make sure to ignore "hotspot bit" when comparing document style with archived hotspot style
if ((hotspotPairs[i] & ~mask) == (idStyle & ~mask))
{ {
fs = hotspotStylers[i].first; fs = hotspotPairs[i];
_pEditView->execute(SCI_STYLEGETFORE, fs);
break; break;
} }
} }
// if we found it then use it to colourize
if (fs != -1) if (fs != -1)
{ {
_pEditView->execute(SCI_STARTSTYLING, start, 0xFF); _pEditView->execute(SCI_STARTSTYLING, start, 0xFF);
_pEditView->execute(SCI_SETSTYLING, foundTextLen, fs); _pEditView->execute(SCI_SETSTYLING, foundTextLen, fs);
} }
else else // generize a new style and add it into a array
{ {
pair<int, int> p(style_hotspot, idStyle); style_hotspot = idStyle | mask; // set "hotspot bit"
hotspotStylers.push_back(p); hotspotPairs.push_back(style_hotspot);
int activeFG = 0xFF0000; int activeFG = 0xFF0000;
unsigned char idStyleMSBunset = idStyle & ~mask;
char fontNameA[128]; char fontNameA[128];
Style hotspotStyle; Style hotspotStyle;
hotspotStyle._styleID = style_hotspot; hotspotStyle._styleID = static_cast<int>(style_hotspot);
_pEditView->execute(SCI_STYLEGETFONT, idStyle, (LPARAM)fontNameA); _pEditView->execute(SCI_STYLEGETFONT, idStyleMSBunset, (LPARAM)fontNameA);
TCHAR *generic_fontname = new TCHAR[128]; TCHAR *generic_fontname = new TCHAR[128];
#ifdef UNICODE #ifdef UNICODE
WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance();
@ -2122,13 +2113,13 @@ void Notepad_plus::addHotSpot(bool docIsModifing)
#endif #endif
hotspotStyle._fontName = generic_fontname; hotspotStyle._fontName = generic_fontname;
hotspotStyle._fgColor = _pEditView->execute(SCI_STYLEGETFORE, idStyle); hotspotStyle._fgColor = _pEditView->execute(SCI_STYLEGETFORE, idStyleMSBunset);
hotspotStyle._bgColor = _pEditView->execute(SCI_STYLEGETBACK, idStyle); hotspotStyle._bgColor = _pEditView->execute(SCI_STYLEGETBACK, idStyleMSBunset);
hotspotStyle._fontSize = _pEditView->execute(SCI_STYLEGETSIZE, idStyle); hotspotStyle._fontSize = _pEditView->execute(SCI_STYLEGETSIZE, idStyleMSBunset);
int isBold = _pEditView->execute(SCI_STYLEGETBOLD, idStyle); int isBold = _pEditView->execute(SCI_STYLEGETBOLD, idStyleMSBunset);
int isItalic = _pEditView->execute(SCI_STYLEGETITALIC, idStyle); int isItalic = _pEditView->execute(SCI_STYLEGETITALIC, idStyleMSBunset);
int isUnderline = _pEditView->execute(SCI_STYLEGETUNDERLINE, idStyle); int isUnderline = _pEditView->execute(SCI_STYLEGETUNDERLINE, idStyleMSBunset);
hotspotStyle._fontStyle = (isBold?FONTSTYLE_BOLD:0) | (isItalic?FONTSTYLE_ITALIC:0) | (isUnderline?FONTSTYLE_UNDERLINE:0); hotspotStyle._fontStyle = (isBold?FONTSTYLE_BOLD:0) | (isItalic?FONTSTYLE_ITALIC:0) | (isUnderline?FONTSTYLE_UNDERLINE:0);
int urlAction = (NppParameters::getInstance())->getNppGUI()._styleURL; int urlAction = (NppParameters::getInstance())->getNppGUI()._styleURL;
@ -2140,11 +2131,10 @@ void Notepad_plus::addHotSpot(bool docIsModifing)
_pEditView->execute(SCI_STYLESETHOTSPOT, style_hotspot, TRUE); _pEditView->execute(SCI_STYLESETHOTSPOT, style_hotspot, TRUE);
_pEditView->execute(SCI_SETHOTSPOTACTIVEFORE, TRUE, activeFG); _pEditView->execute(SCI_SETHOTSPOTACTIVEFORE, TRUE, activeFG);
_pEditView->execute(SCI_SETHOTSPOTSINGLELINE, style_hotspot, 0); _pEditView->execute(SCI_SETHOTSPOTSINGLELINE, style_hotspot, 0);
_pEditView->execute(SCI_STARTSTYLING, start, 0x1F);
// colourize it!
_pEditView->execute(SCI_STARTSTYLING, start, 0xFF);
_pEditView->execute(SCI_SETSTYLING, foundTextLen, style_hotspot); _pEditView->execute(SCI_SETSTYLING, foundTextLen, style_hotspot);
if (style_hotspot > 24)
style_hotspot--;
}
} }
_pEditView->execute(SCI_SETTARGETSTART, posFound + foundTextLen); _pEditView->execute(SCI_SETTARGETSTART, posFound + foundTextLen);

View File

@ -375,7 +375,6 @@ private:
// For hotspot // For hotspot
bool _linkTriggered; bool _linkTriggered;
bool _isDocModifing;
bool _isHotspotDblClicked; bool _isHotspotDblClicked;
bool _isFolding; bool _isFolding;
@ -518,7 +517,7 @@ private:
}; };
void MaintainIndentation(TCHAR ch); void MaintainIndentation(TCHAR ch);
void addHotSpot(bool docIsModifing = false); void addHotSpot();
void bookmarkAdd(int lineno) const { void bookmarkAdd(int lineno) const {
if (lineno == -1) if (lineno == -1)

View File

@ -1279,6 +1279,9 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa
checkUndoState(); //4 checkUndoState(); //4
} }
if (wParam == LINKTRIGGERED)
notification->wParam = LINKTRIGGERED;
_pluginsManager.notify(notification); _pluginsManager.notify(notification);
return notify(notification); return notify(notification);

View File

@ -168,8 +168,6 @@ BufferID Notepad_plus::doOpen(const TCHAR *fileName, bool isReadOnly, int encodi
} }
PathRemoveFileSpec(longFileName); PathRemoveFileSpec(longFileName);
_linkTriggered = true; _linkTriggered = true;
_isDocModifing = false;
_isFileOpening = false; _isFileOpening = false;
// Notify plugins that current file is just opened // Notify plugins that current file is just opened

View File

@ -50,7 +50,6 @@ BOOL Notepad_plus::notify(SCNotification *notification)
{ {
prevWasEdit = true; prevWasEdit = true;
_linkTriggered = true; _linkTriggered = true;
_isDocModifing = true;
::InvalidateRect(notifyView->getHSelf(), NULL, TRUE); ::InvalidateRect(notifyView->getHSelf(), NULL, TRUE);
} }
@ -398,7 +397,7 @@ BOOL Notepad_plus::notify(SCNotification *notification)
{ {
int urlAction = (NppParameters::getInstance())->getNppGUI()._styleURL; int urlAction = (NppParameters::getInstance())->getNppGUI()._styleURL;
if ((urlAction == 1) || (urlAction == 2)) if ((urlAction == 1) || (urlAction == 2))
addHotSpot(_isDocModifing); addHotSpot();
} }
if (_pDocMap) if (_pDocMap)
@ -473,7 +472,8 @@ BOOL Notepad_plus::notify(SCNotification *notification)
int urlAction = (NppParameters::getInstance())->getNppGUI()._styleURL; int urlAction = (NppParameters::getInstance())->getNppGUI()._styleURL;
if ((urlAction == 1) || (urlAction == 2)) if ((urlAction == 1) || (urlAction == 2))
addHotSpot(_isDocModifing); addHotSpot();
break; break;
} }
@ -568,13 +568,12 @@ BOOL Notepad_plus::notify(SCNotification *notification)
NppParameters *nppParam = NppParameters::getInstance(); NppParameters *nppParam = NppParameters::getInstance();
// if it's searching/replacing, then do nothing // if it's searching/replacing, then do nothing
if (_linkTriggered && !nppParam->_isFindReplacing) if ((_linkTriggered && !nppParam->_isFindReplacing) || notification->wParam == LINKTRIGGERED)
{ {
int urlAction = (NppParameters::getInstance())->getNppGUI()._styleURL; int urlAction = (NppParameters::getInstance())->getNppGUI()._styleURL;
if ((urlAction == 1) || (urlAction == 2)) if ((urlAction == 1) || (urlAction == 2))
addHotSpot(_isDocModifing); addHotSpot();
_linkTriggered = false; _linkTriggered = false;
_isDocModifing = false;
} }
if (_pDocMap) if (_pDocMap)

View File

@ -79,7 +79,7 @@ void Buffer::setLangType(LangType lang, const TCHAR * userLangName)
{ {
_userLangExt = userLangName; _userLangExt = userLangName;
} }
_needLexer = true; //change of lang means lexern eeds updating _needLexer = true; //change of lang means lexern needs updating
doNotify(BufferChangeLanguage|BufferChangeLexing); doNotify(BufferChangeLanguage|BufferChangeLexing);
} }

View File

@ -65,6 +65,14 @@ BOOL CALLBACK GoToLineDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM)
(*_ppEditView)->execute(SCI_GOTOPOS, line); (*_ppEditView)->execute(SCI_GOTOPOS, line);
} }
} }
// find hotspots
NMHDR nmhdr;
nmhdr.code = SCN_PAINTED;
nmhdr.hwndFrom = _hSelf;
nmhdr.idFrom = ::GetDlgCtrlID(nmhdr.hwndFrom);
::SendMessage(_hParent, WM_NOTIFY, (WPARAM)LINKTRIGGERED, (LPARAM)&nmhdr);
(*_ppEditView)->getFocus(); (*_ppEditView)->getFocus();
return TRUE; return TRUE;
} }

View File

@ -381,6 +381,20 @@ LRESULT ScintillaEditView::scintillaNew_Proc(HWND hwnd, UINT Message, WPARAM wPa
break; break;
} }
case WM_KEYUP :
{
if (wParam == VK_PRIOR || wParam == VK_NEXT)
{
// find hotspots
NMHDR nmhdr;
nmhdr.code = SCN_PAINTED;
nmhdr.hwndFrom = _hSelf;
nmhdr.idFrom = ::GetDlgCtrlID(nmhdr.hwndFrom);
::SendMessage(_hParent, WM_NOTIFY, (WPARAM)LINKTRIGGERED, (LPARAM)&nmhdr);
}
break;
}
case WM_VSCROLL : case WM_VSCROLL :
{ {
break; break;
@ -1483,18 +1497,9 @@ void ScintillaEditView::defineDocType(LangType typeDoc)
setSpecialStyle(styleLN); setSpecialStyle(styleLN);
} }
setTabSettings(_pParameter->getLangFromID(typeDoc)); setTabSettings(_pParameter->getLangFromID(typeDoc));
int bitsNeeded = execute(SCI_GETSTYLEBITSNEEDED); execute(SCI_SETSTYLEBITS, 8); // Always use 8 bit mask in Document class (Document::stylingBitsMask),
execute(SCI_SETSTYLEBITS, bitsNeeded); // in that way Editor::PositionIsHotspot will return correct hotspot styleID.
// This value has no effect on LexAccessor::mask.
// Reapply the hotspot styles.
if (_hotspotStyles.find(_currentBuffer) != _hotspotStyles.end())
{
StyleMap* currentStyleMap = _hotspotStyles[_currentBuffer];
for (StyleMap::iterator it(currentStyleMap->begin()); it != currentStyleMap->end(); ++it)
{
setStyle(it->second);
}
}
} }
BufferID ScintillaEditView::attachDefaultDoc() BufferID ScintillaEditView::attachDefaultDoc()
@ -1580,7 +1585,8 @@ void ScintillaEditView::activateBuffer(BufferID buffer)
saveCurrentPos(); saveCurrentPos();
// get foldStateInfo of current doc // get foldStateInfo of current doc
std::vector<HeaderLineState> lineStateVector = getCurrentFoldStates(); std::vector<HeaderLineState> lineStateVector;
getCurrentFoldStates(lineStateVector);
// put the state into the future ex buffer // put the state into the future ex buffer
_currentBuffer->setHeaderLineState(lineStateVector, this); _currentBuffer->setHeaderLineState(lineStateVector, this);
@ -1601,6 +1607,13 @@ void ScintillaEditView::activateBuffer(BufferID buffer)
restyleBuffer(); restyleBuffer();
} }
// find hotspots
NMHDR nmhdr;
nmhdr.code = SCN_PAINTED;
nmhdr.hwndFrom = _hSelf;
nmhdr.idFrom = ::GetDlgCtrlID(nmhdr.hwndFrom);
::SendMessage(_hParent, WM_NOTIFY, (WPARAM)LINKTRIGGERED, (LPARAM)&nmhdr);
// restore the collapsed info // restore the collapsed info
const std::vector<HeaderLineState> & lineStateVectorNew = newBuf->getHeaderLineState(this); const std::vector<HeaderLineState> & lineStateVectorNew = newBuf->getHeaderLineState(this);
syncFoldStateWith(lineStateVectorNew); syncFoldStateWith(lineStateVectorNew);
@ -1619,9 +1632,8 @@ void ScintillaEditView::activateBuffer(BufferID buffer)
return; //all done return; //all done
} }
std::vector<HeaderLineState> ScintillaEditView::getCurrentFoldStates() void ScintillaEditView::getCurrentFoldStates(std::vector<HeaderLineState> & lineStateVector)
{ {
std::vector<HeaderLineState> lineStateVector;
int maxLine = execute(SCI_GETLINECOUNT); int maxLine = execute(SCI_GETLINECOUNT);
for (int line = 0; line < maxLine; line++) for (int line = 0; line < maxLine; line++)
@ -1633,7 +1645,6 @@ std::vector<HeaderLineState> ScintillaEditView::getCurrentFoldStates()
lineStateVector.push_back(HeaderLineState(line, expanded)); lineStateVector.push_back(HeaderLineState(line, expanded));
} }
} }
return lineStateVector;
} }
void ScintillaEditView::syncFoldStateWith(const std::vector<HeaderLineState> & lineStateVectorNew) void ScintillaEditView::syncFoldStateWith(const std::vector<HeaderLineState> & lineStateVectorNew)
@ -1778,7 +1789,7 @@ void ScintillaEditView::fold(int line, bool mode)
void ScintillaEditView::foldAll(bool mode) void ScintillaEditView::foldAll(bool mode)
{ {
// The following code is needed : // The following code is needed :
execute(SCI_COLOURISE, 0, -1); //execute(SCI_COLOURISE, 0, -1);
// according to the Scitilla document : // according to the Scitilla document :
// This requests the current lexer or the container (if the lexer is set to SCLEX_CONTAINER) // This requests the current lexer or the container (if the lexer is set to SCLEX_CONTAINER)
// to style the document between startPos and endPos. If endPos is -1, the document is styled from startPos to the end. // to style the document between startPos and endPos. If endPos is -1, the document is styled from startPos to the end.

View File

@ -242,7 +242,7 @@ public:
void activateBuffer(BufferID buffer); void activateBuffer(BufferID buffer);
std::vector<HeaderLineState> getCurrentFoldStates(); void getCurrentFoldStates(std::vector<HeaderLineState> & lineStateVector);
void syncFoldStateWith(const std::vector<HeaderLineState> & lineStateVectorNew); void syncFoldStateWith(const std::vector<HeaderLineState> & lineStateVectorNew);
void getText(char *dest, int start, int end) const; void getText(char *dest, int start, int end) const;

View File

@ -47,7 +47,9 @@ void DocumentMap::reloadMap()
_pScintillaEditView->setCurrentBuffer(editBuf); _pScintillaEditView->setCurrentBuffer(editBuf);
// folding // folding
_pScintillaEditView->syncFoldStateWith((*_ppEditView)->getCurrentFoldStates()); std::vector<HeaderLineState> lineStateVector;
(*_ppEditView)->getCurrentFoldStates(lineStateVector);
_pScintillaEditView->syncFoldStateWith(lineStateVector);
// Wrapping // Wrapping
if ((*_ppEditView)->isWrap() && needToRecomputeWith()) if ((*_ppEditView)->isWrap() && needToRecomputeWith())