void wxTextValidator::OnChar(wxKeyEvent& event) { /* if ( !M_VTEXTDATA ) return; */ if ( m_validatorWindow ) { int keyCode = event.GetKeyCode(); // we don't filter special keys and Delete if ( !(keyCode < WXK_SPACE || keyCode == WXK_DELETE || keyCode > WXK_START) && ( ((m_validatorStyle & wxFILTER_INCLUDE_CHAR_LIST) && !IsInCharIncludes(wxString((wxChar) keyCode, 1))) || ((m_validatorStyle & wxFILTER_EXCLUDE_CHAR_LIST) && !IsNotInCharExcludes(wxString((wxChar) keyCode, 1))) || ((m_validatorStyle & wxFILTER_ASCII) && !isascii(keyCode)) || ((m_validatorStyle & wxFILTER_ALPHA) && !wxIsalpha(keyCode)) || ((m_validatorStyle & wxFILTER_ALPHANUMERIC) && !wxIsalnum(keyCode)) || ((m_validatorStyle & wxFILTER_NUMERIC) && !wxIsdigit(keyCode) && keyCode != '.' && keyCode != ',' && keyCode != '-') ) ) { if ( !wxValidator::IsSilent() ) wxBell(); // eat message return; } } event.Skip(); }
bool wxTerminal::CheckForCD( const wxString &command, wxString &path ) { if ( command.IsEmpty() ) return false; // Returning true tells caller there's nothing else to do if ( command.Left(2) != wxT("cd") ) return false; // Not a cd attempt so return false so that RunCommand takes over if ( wxIsalpha( command.GetChar(2) ) ) return false; // This must be a real command beginning with cd??? if ( command == wxT("cd.") || command == wxT("cd .") ) { path = wxGetCwd(); return true; } if ( command == wxT("cd") || command == wxT("cd~") || command == wxT("cd ~") ) { path = wxGetHomeDir(); return true; } else if ( command.Find(wxT("&&")) != wxNOT_FOUND ) { // a complex command: cd <somewhere> && ... return false; } else { // Otherwise it should be a real dir. Remove the initial cd, plus any white-space path = command.Mid( 2 ); path << wxFileName::GetPathSeparator(); path.Trim(false); wxFileName fn(path); fn.MakeAbsolute(m_workingDir); fn.Normalize(); if( fn.DirExists() ) { path = fn.GetFullPath(); return true; } return false; } }
bool wxFieldMaskData::IsValidInput(wxChar chNewChar) { bool bIsValidInput=FALSE; switch(m_eType) { // These are the input types. case MaskDataTypeDIGIT: bIsValidInput=wxIsdigit(chNewChar) != 0; break; case MaskDataTypeALPHANUMERIC: bIsValidInput=wxIsalnum(chNewChar) != 0; break; case MaskDataTypeALPHABETIC: case MaskDataTypeALPHAETICUPPER: case MaskDataTypeALPHAETICLOWER: bIsValidInput=wxIsalpha(chNewChar) != 0; break; case MaskDataTypeCHARACTER: if((chNewChar >= 32) && (chNewChar <= 126)) bIsValidInput=TRUE; if((chNewChar >= 128) && (chNewChar <= 255)) bIsValidInput = TRUE; break; } return bIsValidInput; }
static bool wxIsAlpha(const wxString& val) { int i; for ( i = 0; i < (int)val.Length(); i++) { if (!wxIsalpha(val[i])) return false; } return true; }
// Return just the directory, or NULL if no directory wxString wxPathOnly (const wxString& path) { if (!path.empty()) { wxChar buf[_MAXPATHLEN]; int l = path.length(); int i = l - 1; if ( i >= _MAXPATHLEN ) return wxString(); // Local copy wxStrcpy(buf, path); // Search backward for a backward or forward slash while (i > -1) { // Unix like or Windows if (path[i] == wxT('/') || path[i] == wxT('\\')) { // Don't return an empty string if (i == 0) i ++; buf[i] = 0; return wxString(buf); } #ifdef __VMS__ if (path[i] == wxT(']')) { buf[i+1] = 0; return wxString(buf); } #endif i --; } #if defined(__WINDOWS__) // Try Drive specifier if (wxIsalpha (buf[0]) && buf[1] == wxT(':')) { // A:junk --> A:. (since A:.\junk Not A:\junk) buf[2] = wxT('.'); buf[3] = wxT('\0'); return wxString(buf); } #endif } return wxEmptyString; }
/* static */ wxString wxFileSystemHandler::GetRightLocation(const wxString& location) { int i, len = location.length(); for (i = len-1; i >= 0; i--) { if (location[i] == wxT('#')) len = i; if (location[i] != wxT(':')) continue; // C: on Windows if (i == 1) continue; if (i >= 2 && wxIsalpha(location[i-1]) && location[i-2] == wxT('/')) continue; // Could be the protocol break; } if (i == 0) return wxEmptyString; const static wxString protocol(wxT("file:")); if (i < (int)protocol.length() - 1 || location.compare(0, i + 1, protocol)) return location.Mid(i + 1, len - i - 1); int s = ++i; // Start position // Check if there are three '/'s after "file:" int end = wxMin(len, s + 3); while (i < end && location[i] == wxT('/')) i++; if (i == s + 2) // Host is specified, e.g. "file://host/path" return location.Mid(s, len - s); if (i > s) { // Remove the last '/' if it is preceding "C:/...". // Otherwise, keep it. if (i + 1 >= len || location[i + 1] != wxT(':')) i--; else if (i + 4 < len) { // Check if ':' was encoded const static wxString colonLower(wxT("%3a")); const static wxString colonUpper(wxT("%3A")); wxString sub =location.Mid(i + 1, 3); if (sub == colonLower || sub == colonUpper) i--; } } return location.Mid(i, len - i); }
// Return just the directory, or NULL if no directory wxChar * wxPathOnly (wxChar *path) { if (path && *path) { static wxChar buf[_MAXPATHLEN]; int l = wxStrlen(path); int i = l - 1; if ( i >= _MAXPATHLEN ) return NULL; // Local copy wxStrcpy (buf, path); // Search backward for a backward or forward slash while (i > -1) { // Unix like or Windows if (path[i] == wxT('/') || path[i] == wxT('\\')) { buf[i] = 0; return buf; } #ifdef __VMS__ if (path[i] == wxT(']')) { buf[i+1] = 0; return buf; } #endif i --; } #if defined(__WINDOWS__) // Try Drive specifier if (wxIsalpha (buf[0]) && buf[1] == wxT(':')) { // A:junk --> A:. (since A:.\junk Not A:\junk) buf[2] = wxT('.'); buf[3] = wxT('\0'); return buf; } #endif } return NULL; }
bool wxIsAbsolutePath (const wxString& filename) { if (!filename.empty()) { // Unix like or Windows if (filename[0] == wxT('/')) return true; #ifdef __VMS__ if ((filename[0] == wxT('[') && filename[1] != wxT('.'))) return true; #endif #if defined(__WINDOWS__) // MSDOS like if (filename[0] == wxT('\\') || (wxIsalpha (filename[0]) && filename[1] == wxT(':'))) return true; #endif } return false ; }
wxString EvaluationQueue::GetCommand() { wxString retval; m_userLabel = wxEmptyString; if(!m_tokens.IsEmpty()) { retval = m_tokens[0]; wxString userLabel; int colonPos; if((colonPos = retval.find(wxT(":")))!=wxNOT_FOUND) { userLabel = retval.Left(colonPos); userLabel.Trim(true); userLabel.Trim(false); if((wxIsalpha(userLabel[0]))||(userLabel[0]==wxT('\\'))||(userLabel[0]==wxT('_'))) { for(size_t i=0;i<userLabel.Length();i++) { if(userLabel[i]==wxT('\\')) i++; else { if((!wxIsalnum(userLabel[i]))&&(userLabel[i]!='_')) { userLabel = wxEmptyString; break; } } } m_userLabel = userLabel; } }; } return retval; }
wxString Tokenizer::DoGetToken() { int start = m_TokenIndex; bool needReplace = false; wxString str; wxChar c = CurrentChar(); if (c == '_' || wxIsalpha(c)) { // keywords, identifiers, etc. // operator== is cheaper than wxIsalnum, also MoveToNextChar already includes IsEOF while ( ( (c == '_') || (wxIsalnum(c)) ) && MoveToNextChar() ) c = CurrentChar(); // repeat if (IsEOF()) return wxEmptyString; needReplace = true; str = m_Buffer.Mid(start, m_TokenIndex - start); } #ifdef __WXMSW__ // This is a Windows only bug! // fetch non-English characters, see more details in: http://forums.codeblocks.org/index.php/topic,11387.0.html else if (c == 178 || c == 179 || c == 185) { str = c; MoveToNextChar(); } #endif else if (wxIsdigit(c)) { // numbers while (NotEOF() && CharInString(CurrentChar(), _T("0123456789.abcdefABCDEFXxLl"))) MoveToNextChar(); if (IsEOF()) return wxEmptyString; str = m_Buffer.Mid(start, m_TokenIndex - start); } else if ( (c == '"') || (c == '\'') ) { SkipString(); //Now, we are after the end of the C-string, so return the whole string as a token. str = m_Buffer.Mid(start, m_TokenIndex - start); } else if (c == ':') { if (NextChar() == ':') { MoveToNextChar(); MoveToNextChar(); // this only copies a pointer, but operator= allocates memory and does a memcpy! str.assign(TokenizerConsts::colon_colon); } else { MoveToNextChar(); str.assign(TokenizerConsts::colon); } } else if (c == '<') { if (m_State&tsSingleAngleBrace) { if ( !SkipToOneOfChars( _T(">"), true, true) ) return wxEmptyString; MoveToNextChar(); str= m_Buffer.Mid(start, m_TokenIndex - start); } else { str = c; MoveToNextChar(); } } else if (c == '(') { if (m_State & tsReadRawExpression) { str = c; MoveToNextChar(); } else { ReadParentheses(str); } } else { if (c == '{') ++m_NestLevel; else if (c == '}') --m_NestLevel; str = c; MoveToNextChar(); } if (m_FirstRemainingLength != 0 && m_BufferLen - m_FirstRemainingLength < m_TokenIndex) { m_FirstRemainingLength = 0; m_IsReplaceParsing = false; m_RepeatReplaceCount = 0; } if (needReplace && m_State ^ tsReadRawExpression) MacroReplace(str); return str; }
//vfc add bGetValue wxString Tokenizer::DoGetToken(bool bGetValue, bool bTemplate) { if (IsEOF()) return wxEmptyString; if (!SkipWhiteSpace()) return wxEmptyString; if (m_SkipUnwantedTokens && !SkipUnwanted(bGetValue)) return wxEmptyString; // if m_SkipUnwantedTokens is false, we need to handle comments here too if (!m_SkipUnwantedTokens) SkipComment(); int start = m_TokenIndex; wxString m_Str; wxChar c = CurrentChar(); if (c == '_' || wxIsalpha(c)) { // keywords, identifiers, etc. // operator== is cheaper than wxIsalnum, also MoveToNextChar already includes IsEOF while ( ( CurrentChar() == '_' || wxIsalnum(CurrentChar()) ) && MoveToNextChar() ) ; if (IsEOF()) return wxEmptyString; m_Str = m_Buffer.Mid(start, m_TokenIndex - start); m_IsOperator = m_Str.IsSameAs(TokenizerConsts::operator_str); } #ifdef __WXMSW__ // This is a Windows only bug! else if (c == 178 || c == 179 || c == 185) // fetch ?and ? { m_Str = c; MoveToNextChar(); } #endif else if (wxIsdigit(CurrentChar())) { // numbers while (NotEOF() && CharInString(CurrentChar(), _T("0123456789.abcdefABCDEFXxLl"))) MoveToNextChar(); if (IsEOF()) return wxEmptyString; m_Str = m_Buffer.Mid(start, m_TokenIndex - start); m_IsOperator = false; } else if (CurrentChar() == '"' || CurrentChar() == '\'') { // string, char, etc. wxChar match = CurrentChar(); MoveToNextChar(); // skip starting ' or " if (!SkipToChar(match)) return wxEmptyString; MoveToNextChar(); // skip ending ' or " m_Str = m_Buffer.Mid(start, m_TokenIndex - start); } else if (CurrentChar() == ':') { if (NextChar() == ':') { MoveToNextChar(); MoveToNextChar(); m_Str.assign(TokenizerConsts::colon_colon); // this only copies a pointer, but operator= allocates memory and does a memcpy! } else { MoveToNextChar(); m_Str.assign(TokenizerConsts::colon); } } else if (CurrentChar() == '<' && bTemplate) { wxChar match = _T('>'); MoveToNextChar(); if (!SkipToOneOfChars(_T(">\r\n")),false) return wxEmptyString; MoveToNextChar(); wxString tmp = m_Buffer.Mid(start+1,m_TokenIndex-start-2); tmp.Trim(); m_Str = _T("<"); m_Str += tmp; m_Str += _T(">");//m_Buffer.Mid(start, m_TokenIndex - start); } else if (CurrentChar() == '(') { m_IsOperator = false; // skip blocks () [] if (!SkipBlock(CurrentChar())) return wxEmptyString; wxString tmp = m_Buffer.Mid(start, m_TokenIndex - start); // tmp.Replace(_T("\t"), _T(" ")); // replace tabs with spaces // tmp.Replace(_T("\n"), _T(" ")); // replace LF with spaces // tmp.Replace(_T("\r"), _T(" ")); // replace CR with spaces { // this is much faster: size_t i; while((i = tmp.find_first_of(TokenizerConsts::tabcrlf)) != wxString::npos) //tmp[i] = _T(' '); tmp.SetAt(i,_T(' ')); } // fix-up arguments (remove excessive spaces/tabs/newlines) for (unsigned int i = 0; i < tmp.Length() - 1; ++i) { //skip spaces before '=' and ',' if (tmp.GetChar(i) == ' ' && (tmp.GetChar(i + 1) == ',' || tmp.GetChar(i + 1) == '=')) continue; if (tmp.GetChar(i) == '/' && tmp.GetChar(i + 1) == '*') { // skip C comments i += 2; while (i < tmp.Length() - 1) { if (tmp.GetChar(i) == '*' && tmp.GetChar(i + 1) == '/') break; ++i; } if (i >= tmp.Length() - 1 || tmp.GetChar(i + 1) != '/') continue; // we failed... i += 2; } else if (tmp.GetChar(i) == '=') { // skip default assignments ++i; int level = 0; // nesting parenthesis while (i < tmp.Length()) { if (tmp.GetChar(i) == '(') ++level; else if (tmp.GetChar(i) == ')') --level; if ((tmp.GetChar(i) == ',' && level == 0) || (tmp.GetChar(i) == ')' && level < 0)) break; ++i; } if (i < tmp.Length() && tmp.GetChar(i) == ',') --i; continue; // we are done here } if (i < tmp.Length() - 1) { if ((tmp.GetChar(i) == ' ') && (tmp.GetChar(i + 1) == ' ')) continue; // skip excessive spaces // in case of c-style comments "i" might already be tmp.Length() // thus do only add the current char otherwise. // otherwise the following statement: // m_Str << _T(')'); // below would add another closing bracket. m_Str << tmp.GetChar(i); } } m_Str << _T(')'); // add closing parenthesis (see "i < tmp.Length() - 1" in previous "for") // m_Str.Replace(_T(" "), _T(" ")); // replace two-spaces with single-space (introduced if it skipped comments or assignments) // m_Str.Replace(_T("( "), _T("(")); // m_Str.Replace(_T(" )"), _T(")")); //Str.Replace is massive overkill here since it has to allocate one new block per replacement CompactSpaces(m_Str); } else { if (CurrentChar() == '{') ++m_NestLevel; else if (CurrentChar() == '}') --m_NestLevel; m_Str = CurrentChar(); MoveToNextChar(); } if (m_LastWasPreprocessor && !m_Str.IsSameAs(_T("#")) && !m_LastPreprocessor.IsSameAs(_T("#"))) { if (!m_LastPreprocessor.IsSameAs(TokenizerConsts::include_str)) { // except for #include and #if[[n]def], all other preprocessor directives need only // one word exactly after the directive, e.g. #define THIS_WORD SkipToEOL(); } m_LastPreprocessor.Clear(); } if (m_LastWasPreprocessor) m_LastPreprocessor << m_Str; m_LastWasPreprocessor = false; return m_Str; }
bool wxSimpleHtmlParser::IsWordChar(int ch) { return (wxIsalpha((wxChar) ch) != 0 || ch == wxT('-') || ch == wxT('_') || IsNumeric(ch)); }
bool wxSimpleHtmlParser::IsAlpha(int ch) { return (wxIsalpha((wxChar) ch) != 0); }
int URLDetector::FindURL(const wxChar *text, int& len) { // offset of the current value of text from the initial one int offset = 0; match: int pos = scan(text, len); if ( !len ) return -1; // the provisional start and end of the URL, will be changed below const wxChar *start = text + pos; const wxChar *p = start + len; // there are 2 different cases: a mailto: URL or a mail address and // anything else which we need to treat differently bool isMail = *start == '@'; if ( isMail ) { // look for the start of the address start--; while ( start > text && IsLocalPartChar(*start) ) start--; // have we stopped at '<'? bool hasAngleBracket = *start == '<'; if ( !hasAngleBracket ) { if ( !IsLocalPartChar(*start) ) { // we went too far backwards start++; } //else: we stopped at the start of the text } //else: keep '<' as part of the URL // now look for the end of it while ( *p && IsDomainChar(*p) ) { p++; } // finally we should either have the brackets from both sides or none // at all if ( hasAngleBracket ) { if ( *p == '>' ) { // take the right bracket as well p++; } else { // forget about the left one start++; } } } else // !bare mail address { for ( ;; ) { size_t lenURL = 0; while ( IsURLChar(*p) ) { lenURL++; p++; } // URLs are frequently so long that they're spread across multiple // lines, so try to see if this might be the case here // // first of all we need to check whether it is at the end of line but // we should allow some trailing spaces const wxChar* q = p; while ( *q == ' ' ) q++; if ( q[0] != '\r' || q[1] != '\n' ) break; // not at the line end // also check if it's really long enough to be wrapped: // the short URLs normally shouldn't be wrapped static const size_t URL_WRAP_LEN = 30; // min len of wrapped URL if ( lenURL < URL_WRAP_LEN ) break; // too short if ( !IsURLChar(q[2]) ) break; // doesn't seem to be continued on the next line // heuristic text for end of URL detection if ( p - start > 5 && !CanBeWrapped(p) ) { // it seems that the URL ends here break; } p = q + 2; // go to the start of next line // Check that the beginning of next line is not the start of // another URL. // // Note that although '@' alone is recognized as the beginning // of an URL: here it should not be the case. int nextlen = 0; int nextpos = scan(p, nextlen); if ( nextlen && nextpos == 0 && *p != '@') { p -= 2; // The start of the next line being the start of an URL on its own, // do not join the two. break; } // check whether the next line starts with a word -- this is a good // indication that the URL hasn't wrapped q = p; while ( wxIsalpha(*q) ) q++; if ( *q == _T(' ') || (wxStrchr(_T(".,:;"), *q) && q[1] == _T(' ')) ) { // looks like we've a word (i.e. sequence of letters terminated by // space or punctuation) at the start of the next line p -= 2; break; } // another special case: subsequent dashes are very unusual in URLs // but often used as separator lines, so we assume that they indicate // the end of the URL if we find them on the next line. if ( p[0] == '-' && p[1] == '-' ) break; // it might be a wrapped URL but it might be not: it seems like we // get way too many false positives if we suppose that it's always // the case... so restrict the wrapped URLs detection to the case // when they occur at the beginning of the line, possibly after some // white space as this is how people usually format them q = start; while ( q >= text && *q != '\n' ) { q--; if ( !wxIsspace(*q) ) break; } // Does the URL start at the beginning of the line, or does it have // a '<' just in front? if ( q >= text && *q != '\n' && *q != '<') break; // it did occur at the start (or after '<'), suppose the URL is // wrapped and so we continue on the next line (and no need to test // the first character, it had been already done above) p++; } } // truncate any punctuation at the end while ( strchr(".:,)]!?", *(p - 1)) ) p--; // additional checks for the matches which didn't have an explicit scheme if ( isMail || text[pos + len - 3 /* len of "://" */ ] != _T(':') ) { // '@' matches may result in false positives, as not every '@' character // is inside a mailto URL so try to weed them out by requiring that the // mail address has a reasonable minimal length ("*****@*****.**" and // "www.xy.fr" are probably the shortest ones we can have, hence 8) // which at least avoids matching the bare '@'s bool good = (p - start) >= 8; if ( good ) { // also check that we have at least one dot in the domain part for the // mail addresses const wxChar * pDot = wxTmemchr(text + pos + 1, '.', p - text - pos - 1); if ( !pDot ) { good = false; } else if ( !isMail ) { // and has either two dots or at least a slash the other URLs, // otherwise it probably isn't an address/URL neither (stuff like // "... using ftp.If you ... " shouldn't be recognized as an URL) good = wxTmemchr(pDot + 1, '.', p - pDot - 1) != NULL || wxTmemchr(pDot + 1, '/', p - pDot - 1) != NULL; } } if ( !good ) { const int offDiff = pos + len; offset += offDiff; text += offDiff; // slightly more efficient than recursion... goto match; } } // return the length of the match len = p - start; return start - text + offset; }
void ContentAssistantPopup::OnKeyPress(wxKeyEvent& event) { #if wxUSE_UNICODE wxChar key = event.GetUnicodeKey(); #else wxChar key = wxString::Format(wxT("%c"), ChangeNumpadToChar(event.GetKeyCode())); #endif switch (event.GetKeyCode()) { case WXK_TAB: if(m_completions.GetCount()>0) { wxChar ch; bool addChar = true; wxString word=m_editor->GetSelectionString(); int index=word.Length(); do { if(m_completions[0].Length()<=index) addChar = false; else { ch = m_completions[0][index]; for(size_t i=0;i<m_completions.GetCount();i++) if((m_completions[i].Length()<index + 1)||(m_completions[i][index]!=ch)) addChar = false; } if(addChar) { index++; word += ch; } } while(addChar); m_editor->ReplaceSelection(m_editor->GetSelectionString(),word,true); } break; case WXK_RETURN: case WXK_RIGHT: case WXK_NUMPAD_ENTER: { int selection = m_autocompletions->GetSelection(); if(selection<0) selection = 0; if(m_completions.GetCount()>0) m_editor->ReplaceSelection( m_editor->GetSelectionString(), m_completions[selection] ); this->GetParent()->GetParent()->Refresh(); if(!m_editor->IsActive()) m_editor->ActivateCell(); Dismiss(); } break; case WXK_LEFT: case WXK_ESCAPE: this->GetParent()->GetParent()->Refresh(); if(!m_editor->IsActive()) m_editor->ActivateCell(); Dismiss(); break; case WXK_UP: { int selection = m_autocompletions->GetSelection(); if(selection > 0) m_autocompletions->SetSelection(selection-1); else { if(m_completions.GetCount()>0) m_autocompletions->SetSelection(0); } break; } case WXK_DOWN: { int selection = m_autocompletions->GetSelection(); if(selection<0) selection = 0; selection++; if(selection >= m_completions.GetCount()) selection--; if(m_completions.GetCount()>0) m_autocompletions->SetSelection(selection); break; } case WXK_BACK: { wxString oldString=m_editor->GetSelectionString(); if(oldString!=wxEmptyString) { m_editor->ReplaceSelection( oldString, oldString.Left(oldString.Length()-1), true ); UpdateResults(); } else this->GetParent()->GetParent()->Refresh(); if(!m_editor->IsActive()) m_editor->ActivateCell(); Dismiss(); break; } default: { if((wxIsalpha(key))||(key==wxT('_'))) { wxString oldString=m_editor->GetSelectionString(); m_editor->ReplaceSelection( oldString, oldString+wxString(key), true ); UpdateResults(); } else if(wxIsprint(key)) { int selection = m_autocompletions->GetSelection(); if(selection<0) selection = 0; m_editor->ReplaceSelection( m_editor->GetSelectionString(), m_completions[selection]+key ); this->GetParent()->GetParent()->Refresh(); if(!m_editor->IsActive()) m_editor->ActivateCell(); Dismiss(); } else event.Skip(); } } this->GetParent()->GetParent()->Refresh(); }
// 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; }
void IncrementalSelectListBase::FilterItems() { m_Result.Empty(); m_Indexes.Empty(); // We put a star before and after pattern to find search expression everywhere in path // that is: if user enter "a", it will match "123a", "12a" or "a12". wxString search(wxT("*") + m_Text->GetValue().Lower() + wxT("*")); for (int i = 0; i < m_Iterator.GetCount(); ++i) { wxString const &item = m_Iterator.GetItem(i); // 2 for before and after stars =~ empty string if ((search.Length()==2) || item.Lower().Matches(search.c_str())) { m_Result.Add(m_Iterator.GetDisplayItem(i)); m_Indexes.Add(i); } } // if only alphabetical, pull word boundaries to the top if (search.Length() > 2) { wxString prefix; for (size_t i = 0; i < search.Length(); ++i) { if (wxIsalpha(search[i])) prefix += search[i]; } if (prefix.Length() == search.Length() - 2) { std::vector<size_t> promoteIdxs; wxArrayString newRes; wxArrayLong newIndx; for (size_t i = 0; i < m_Result.Count(); ++i) { wxString cur = m_Result[i].Lower(); bool promote = false; if (cur.StartsWith(prefix)) promote = true; else { int maxLn = cur.Length() - prefix.Length(); for (int j = 0; j < maxLn; ++j) { if (!wxIsalpha(cur[j]) && cur.Mid(j + 1).StartsWith(prefix)) { promote = true; break; } } } if (promote) { promoteIdxs.push_back(i); newRes.Add(m_Result[i]); newIndx.Add(m_Indexes[i]); } } if (!promoteIdxs.empty()) { for (size_t i = 0; i < m_Result.Count(); ++i) { if (!std::binary_search(promoteIdxs.begin(), promoteIdxs.end(), i)) { newRes.Add(m_Result[i]); newIndx.Add(m_Indexes[i]); } } m_Result = newRes; m_Indexes = newIndx; } } } m_Promoted = search.Length()>2; }
void IncrementalSelectListDlg::FillList() { Freeze(); // We put a star before and after pattern to find search expression everywhere in path wxString search(wxT("*") + m_Text->GetValue().Lower() + wxT("*")); wxArrayString result; wxArrayLong indexes; m_List->Clear(); for (int i = 0; i < m_Iterator.GetCount(); ++i) { wxString const &item = m_Iterator.GetItem(i); // 2 for before and after stars =~ empty string if ((search.Length()==2) || item.Lower().Matches(search.c_str())) { result.Add(m_Iterator.GetDisplayItem(i)); indexes.Add(i); } } // if only alphabetical, pull word boundaries to the top if (search.Length() > 2) { wxString prefix; for (size_t i = 0; i < search.Length(); ++i) { if (wxIsalpha(search[i])) prefix += search[i]; } if (prefix.Length() == search.Length() - 2) { std::vector<size_t> promoteIdxs; wxArrayString newRes; wxArrayLong newIndx; for (size_t i = 0; i < result.Count(); ++i) { wxString cur = result[i].Lower(); bool promote = false; if (cur.StartsWith(prefix)) promote = true; else { int maxLn = cur.Length() - prefix.Length(); for (int j = 0; j < maxLn; ++j) { if (!wxIsalpha(cur[j]) && cur.Mid(j + 1).StartsWith(prefix)) { promote = true; break; } } } if (promote) { promoteIdxs.push_back(i); newRes.Add(result[i]); newIndx.Add(indexes[i]); } } if (!promoteIdxs.empty()) { for (size_t i = 0; i < result.Count(); ++i) { if (!std::binary_search(promoteIdxs.begin(), promoteIdxs.end(), i)) { newRes.Add(result[i]); newIndx.Add(indexes[i]); } } result = newRes; indexes = newIndx; } } } if (!result.empty()) { m_List->Set(result, reinterpret_cast<void**>(&indexes[0])); m_List->SetSelection(0); } Thaw(); }