// cbEVT_EDITOR_TOOLTIP void CCManager::OnEditorTooltip(CodeBlocksEvent& event) { event.Skip(); if (wxGetKeyState(WXK_CONTROL)) return; EditorBase* base = event.GetEditor(); cbEditor* ed = base && base->IsBuiltinEditor() ? static_cast<cbEditor*>(base) : nullptr; if (!ed || ed->IsContextMenuOpened()) return; cbStyledTextCtrl* stc = ed->GetControl(); cbCodeCompletionPlugin* ccPlugin = GetProviderFor(ed); int pos = stc->PositionFromPointClose(event.GetX(), event.GetY()); if (!ccPlugin || pos < 0 || pos >= stc->GetLength()) { if (stc->CallTipActive() && event.GetExtraLong() == 0 && m_CallTipActive == wxSCI_INVALID_POSITION) static_cast<wxScintilla*>(stc)->CallTipCancel(); return; } int hlStart, hlEnd, argsPos; hlStart = hlEnd = argsPos = wxSCI_INVALID_POSITION; bool allowCallTip = true; const std::vector<cbCodeCompletionPlugin::CCToken>& tokens = ccPlugin->GetTokenAt(pos, ed, allowCallTip); std::set<wxString> uniqueTips; for (size_t i = 0; i < tokens.size(); ++i) uniqueTips.insert(tokens[i].displayName); wxStringVec tips(uniqueTips.begin(), uniqueTips.end()); const int style = event.GetInt(); if (!tips.empty()) { const int tknStart = stc->WordStartPosition(pos, true); const int tknEnd = stc->WordEndPosition(pos, true); if (tknEnd - tknStart > 2) { for (size_t i = 0; i < tips[0].Length(); ++i) { size_t hlLoc = tips[0].find(stc->GetTextRange(tknStart, tknEnd), i); if (hlLoc == wxString::npos) break; hlStart = hlLoc; hlEnd = hlStart + tknEnd - tknStart; if ( (hlStart > 0 && (tips[0][hlStart - 1] == wxT('_') || wxIsalpha(tips[0][hlStart - 1]))) || (hlEnd < static_cast<int>(tips[0].Length()) - 1 && (tips[0][hlEnd] == wxT('_') || wxIsalpha(tips[0][hlEnd]))) ) { i = hlEnd; hlStart = hlEnd = wxSCI_INVALID_POSITION; } else break; } } } else if ( allowCallTip && !( stc->IsString(style) || stc->IsComment(style) || stc->IsCharacter(style) || stc->IsPreprocessor(style) ) ) { const int line = stc->LineFromPosition(pos); if (pos + 4 > stc->PositionFromLine(line) + (int)ed->GetLineIndentString(line).Length()) { const CallTipVec& cTips = ccPlugin->GetCallTips(pos, style, ed, argsPos); for (size_t i = 0; i < cTips.size(); ++i) tips.push_back(cTips[i].tip); if (!tips.empty()) { hlStart = cTips[0].hlStart; hlEnd = cTips[0].hlEnd; } } } if (tips.empty()) { if (stc->CallTipActive() && event.GetExtraLong() == 0 && m_CallTipActive == wxSCI_INVALID_POSITION) static_cast<wxScintilla*>(stc)->CallTipCancel(); } else { DoShowTips(tips, stc, pos, argsPos, hlStart, hlEnd); event.SetExtraLong(1); } m_CallTipActive = wxSCI_INVALID_POSITION; }