Пример #1
0
void Edit::ReplaceText(const wxString &find_string)
{
  int found_start, found_end;
  const int select_start = GetSelectionStart();
  const int select_end = GetSelectionEnd();

  // replace & search
  if (select_start > -1 && select_end > select_start) {
    const wxString select_string = GetSelectedText();
    if (select_string == find_string) {
      ReplaceSelection(m_FindData.GetReplaceString());
      // search
      if (FindText(found_start, found_end, false)) {
        SetSelection(found_start, found_end);
      }
      else {
        wxMessageDialog dialog(this, wxT("Cannot find the text \"" + find_string + "\" from current position"), wxT("Find"));
        dialog.ShowModal();
      }
    }
  }
  // search
  else if (FindText(found_start, found_end, false)) {
    SetSelection(found_start, found_end);
  }
}
Пример #2
0
/* TextEditor::showFindReplacePanel
 * Shows or hides the Find+Replace panel, depending on [show]. If
 * shown, fills the find text box with the current selection or the
 * current word at the caret
 *******************************************************************/
void TextEditor::showFindReplacePanel(bool show)
{
	// Do nothing if no F+R panel has been set
	if (!panel_fr)
		return;

	// Hide if needed
	if (!show)
	{
		panel_fr->Hide();
		panel_fr->GetParent()->Layout();
		SetFocus();
		return;
	}

	// Get currently selected text
	string find = GetSelectedText();

	// Get the word at the current cursor position if there is no current selection
	if (find.IsEmpty())
	{
		int ws = WordStartPosition(GetCurrentPos(), true);
		int we = WordEndPosition(GetCurrentPos(), true);
		find = GetTextRange(ws, we);
	}

	// Show the F+R panel
	panel_fr->Show();
	panel_fr->GetParent()->Layout();
	panel_fr->setFindText(find);
}
Пример #3
0
/* TextEditor::replaceCurrent
 * Replaces the currently selected occurrence of [find] with
 * [replace], then selects and scrolls to the next occurrence of
 * [find] in the text. Returns false if [find] is invalid or the
 * current selection does not match it, true otherwise
 *******************************************************************/
bool TextEditor::replaceCurrent(string find, string replace)
{
	// Check search string
	if (find.IsEmpty())
		return false;

	// Check that we've done a find previously
	// (by searching for the find string within the current selection)
	if (GetSelectedText().Length() != find.Length())
		return false;
	SetTargetStart(GetSelectionStart());
	SetTargetEnd(GetSelectionEnd());
	if (SearchInTarget(find) < 0)
		return false;

	// Do the replace
	ReplaceTarget(replace);

	// Update selection
	SetSelection(GetTargetStart(), GetTargetEnd());

	// Do find next
	findNext(find);

	return true;
}
Пример #4
0
bool SearchableEditor::find(bool newSearch)
{
    if (!fd)
        fd = new FindDialog(this, ::wxGetTopLevelParent(this));
    if (newSearch || findTextM.empty())
    {
        if (newSearch)
        {
            // find selected text
            wxString findText(GetSelectedText());
            // failing that initialize with the word at the caret
            if (findText.empty())
            {
                int pos = GetCurrentPos();
                int start = WordStartPosition(pos, true);
                int end = WordEndPosition(pos, true);
                if (end > start)
                    findText = GetTextRange(start, end);
            }
            fd->SetFindText(findText);
        }

        // do not re-center dialog if it is already visible
        if (!fd->IsShown())
            fd->Show();
        fd->SetFocus();
        return false;    // <- caller shouldn't care about this
    }

    int start = GetSelectionEnd();
    if (findFlagsM.has(se::FROM_TOP))
    {
        start = 0;
        findFlagsM.remove(se::ALERT);    // remove flag after first find
    }

    int end = GetTextLength();
    int p = FindText(start, end, findTextM, findFlagsM.asStc());
    if (p == -1)
    {
        if (findFlagsM.has(se::WRAP))
            p = FindText(0, end, findTextM, findFlagsM.asStc());
        if (p == -1)
        {
            if (findFlagsM.has(se::ALERT))
                wxMessageBox(_("No more matches"), _("Search complete"), wxICON_INFORMATION|wxOK);
            return false;
        }
    }
    centerCaret(true);
    GotoPos(p);
    GotoPos(p + findTextM.Length());
    SetSelectionStart(p);
    SetSelectionEnd(p + findTextM.Length());
    centerCaret(false);
    return true;
}
Пример #5
0
void EditTextTask::Copy()
{
    if (wxTheClipboard->Open())
    {
// This data objects are held by the clipboard,
// so do not delete them in the app.
        wxTheClipboard->SetData( new wxTextDataObject(GetSelectedText()) );
        wxTheClipboard->Close();
    }
}
Пример #6
0
/*****************************************************************************
 * Function:	_DtCanvasGetSelection()
 *
 * Purpose:	Indicate the end point for a selection.
 *
 *****************************************************************************/
_DtCvStatus
_DtCanvasGetSelection (
    _DtCvHandle		 canvas_handle,
    unsigned int	 mask,
    _DtCvPointer	*ret_select)
{
    _DtCanvasStruct     *canvas = (_DtCanvasStruct *) canvas_handle;

    *ret_select = NULL;
    return(GetSelectedText(canvas, canvas->select_start, canvas->select_end,
							mask, ret_select));
}
Пример #7
0
bool CodeEdit::UntabifySelection()
{

    wxString text = GetSelectedText();

    if (Untabify(text))
    {
        ReplaceSelection(text);
        return true;
    }

    return false;

}
Пример #8
0
BOOL CEditView::SameAsSelected(LPCTSTR lpszCompare, BOOL bCase)
{
	// check length first
	size_t nLen = lstrlen(lpszCompare);
	int nStartChar, nEndChar;
	GetEditCtrl().GetSel(nStartChar, nEndChar);
	if (nLen != (size_t)(nEndChar - nStartChar))
		return FALSE;

	// length is the same, check contents
	CString strSelect;
	GetSelectedText(strSelect);
	return (bCase && lstrcmp(lpszCompare, strSelect) == 0) ||
		(!bCase && lstrcmpi(lpszCompare, strSelect) == 0);
}
Пример #9
0
void Edit::OnFindReplace(wxCommandEvent &event) {
  const wxString find_string = m_FindData.GetFindString();
  int found_start, found_end;

  if (event.GetId() == myID_FINDNEXT) {
    // search
    if (FindText(found_start, found_end, true)) {
      SetSelection(found_start, found_end);
    }
    else {
      wxMessageDialog dialog(this, wxT("Cannot find the text \"" + find_string + "\" from current position"), wxT("Find"));
      dialog.ShowModal();
    }
  }
  if (event.GetId() == myID_REPLACENEXT) {
    ReplaceText(find_string);
  }
  else {
    if (m_findReplace) {
      delete m_findReplace;
      m_findReplace = NULL;
    }

    const int select_start = GetSelectionStart();
    const int select_end = GetSelectionEnd();
    wxString find_text;
    if (select_start > -1 && select_end > select_start) {
      find_text = GetSelectedText();
    }

    if (event.GetId() == myID_DLG_FIND_TEXT) {
      if (find_text.size() > 0) {
        m_FindData.SetFindString(find_text);
      }
      m_findReplace = new wxFindReplaceDialog(this, &m_FindData, wxT("Find"));
    }
    else {
      if (find_text.size() > 0) {
        m_FindData.SetFindString(find_text);
      }
      m_findReplace = new wxFindReplaceDialog(this, &m_FindData, wxT("Find & Replace"), wxFR_REPLACEDIALOG);
    }
    m_findReplace->Show();
  }
}
Пример #10
0
bool CodeEdit::GetHoverText(int position, wxString& result)
{

    int selectionStart = GetSelectionStart();
    int selectionEnd   = GetSelectionEnd();

    if (position >= selectionStart && position < selectionEnd)
    {
        // We're mousing over the selected text.
        result = GetSelectedText();
        return true;
    }

    // We don't use the : character as a joiner since we don't
    // want to evaulate with that.
    return GetTokenFromPosition(position, ".", result);
    
}
Пример #11
0
void CEditView::OnEditFindReplace(BOOL bFindOnly)
{
	ASSERT_VALID(this);
	_AFX_EDIT_STATE* pEditState = _afxEditState;
	if (pEditState->pFindReplaceDlg != NULL)
	{
		if (pEditState->bFindOnly == bFindOnly)
		{
			pEditState->pFindReplaceDlg->SetActiveWindow();
			pEditState->pFindReplaceDlg->ShowWindow(SW_SHOW);
			return;
		}
		ASSERT(pEditState->bFindOnly != bFindOnly);
		pEditState->pFindReplaceDlg->SendMessage(WM_CLOSE);
		ASSERT(pEditState->pFindReplaceDlg == NULL);
		ASSERT_VALID(this);
	}

	CString strFind;
	GetSelectedText(strFind);
	if (strFind.IsEmpty())
		strFind = pEditState->strFind;
	CString strReplace = pEditState->strReplace;
	pEditState->pFindReplaceDlg = new CFindReplaceDialog;
	ASSERT(pEditState->pFindReplaceDlg != NULL);
	DWORD dwFlags = FR_HIDEWHOLEWORD;
	if (pEditState->bNext)
		dwFlags |= FR_DOWN;
	if (pEditState->bCase)
		dwFlags |= FR_MATCHCASE;
	if (!pEditState->pFindReplaceDlg->Create(bFindOnly, strFind,
		strReplace, dwFlags, this))
	{
		pEditState->pFindReplaceDlg = NULL;
		ASSERT_VALID(this);
		return;
	}

	pEditState->pFindReplaceDlg->SetActiveWindow();
	pEditState->pFindReplaceDlg->ShowWindow(SW_SHOW);
	ASSERT(pEditState->pFindReplaceDlg != NULL);
	pEditState->bFindOnly = bFindOnly;
	ASSERT_VALID(this);
}
Пример #12
0
void ctlSQLBox::OnSearchReplace(wxCommandEvent &ev)
{
	if (!m_dlgFindReplace)
	{
		m_dlgFindReplace = new dlgFindReplace(this);
		m_dlgFindReplace->Show(true);
	}
	else
	{
		m_dlgFindReplace->Show(true);
		m_dlgFindReplace->SetFocus();
	}

	wxString selText = GetSelectedText();
	if (!selText.IsEmpty())
	{
		m_dlgFindReplace->SetFindString(selText);
	}

	m_dlgFindReplace->FocusSearch();
}
Пример #13
0
void t4p::FindInFilesViewClass::OnEditFindInFiles(wxCommandEvent& event) {
    // prime finder with selected text
    wxString selectedText = GetSelectedText();
    if (!selectedText.empty()) {
        Feature.PreviousFindInFiles.Expression = t4p::WxToIcu(selectedText);
    }
    FindInFilesDialogClass dialog(GetMainWindow(), Feature, *this);
    if (dialog.ShowModal() == wxID_OK) {
        t4p::FindInFilesResultsPanelClass* panel = new t4p::FindInFilesResultsPanelClass(GetToolsNotebook(),
                *this, GetStatusBarWithGauge(), Feature.App.RunningThreads);
        wxBitmap findBitmap = wxNullBitmap;
        if (Feature.PreviousFindInFiles.ReplaceExpression.isEmpty()) {
            findBitmap = t4p::BitmapImageAsset(wxT("find-in-files"));
        } else {
            findBitmap = t4p::BitmapImageAsset(wxT("replace-in-files"));
        }

        if (AddToolsWindow(panel, _("Find In Files Results"), wxEmptyString, findBitmap)) {
            panel->Find(Feature.PreviousFindInFiles, Feature.DoHiddenFiles);
            ResultsPanels.push_back(panel);
        }
    }
}
Пример #14
0
void DisassemblyTextCtrl::OnGPM(wxMouseEvent& event)
{
    if(platform::gtk == false) // only if GPM is not already implemented by the OS
    {
        int pos = PositionFromPoint(wxPoint(event.GetX(), event.GetY()));

        if(pos == wxSCI_INVALID_POSITION)
            return;

        int start = GetSelectionStart();
        int end = GetSelectionEnd();

        const wxString s = GetSelectedText();

        if(pos < GetCurrentPos())
        {
            start += s.length();
            end += s.length();
        }

        InsertText(pos, s);
        SetSelectionVoid(start, end);
    }
} // end of OnGPM
Пример #15
0
void CEditView::OnReplaceSel( LPCTSTR lpszFind, BOOL bNext, BOOL bCase,
                              LPCTSTR lpszReplace )
/*************************************************/
{
    _AFX_EDIT_STATE *pState = _afxEditState.GetData();
    ASSERT( pState != NULL );
    
    pState->strFind = lpszFind;
    pState->bNext = bNext;
    pState->bCase = bCase;
    pState->strReplace = lpszReplace;
    
    CString strSelection;
    GetSelectedText( strSelection );
    if( (bCase && strSelection.Compare( lpszFind ) != 0) ||
        (!bCase && strSelection.Compare( lpszFind ) != 0) ) {
        if( !FindText( lpszFind, bNext, bCase ) ) {
            OnTextNotFound( lpszFind );
            return;
        }
    }
    ::SendMessage( m_hWnd, EM_REPLACESEL, TRUE, (LPARAM)lpszReplace );
    FindText( lpszFind, bNext, bCase );
}
Пример #16
0
bool ctlSQLBox::BlockComment(bool uncomment)
{
	wxString lineEnd;
	switch (GetEOLMode())
	{
		case wxSTC_EOL_LF:
			lineEnd = wxT("\n");
			break;
		case wxSTC_EOL_CRLF:
			lineEnd = wxT("\r\n");
			break;
		case wxSTC_EOL_CR:
			lineEnd = wxT("\r");
			break;
	}

	// Save the start position
	const wxString comment = wxT("-- ");
	int start = GetSelectionStart();

	if (!GetSelectedText().IsEmpty())
	{
		wxString selection = GetSelectedText();
		if (!uncomment)
		{
			selection.Replace(lineEnd, lineEnd + comment);
			selection.Prepend(comment);
			if (selection.EndsWith(comment))
				selection = selection.Left(selection.Length() - comment.Length());
		}
		else
		{
			selection.Replace(lineEnd + comment, lineEnd);
			if (selection.StartsWith(comment))
				selection = selection.Right(selection.Length() - comment.Length());
		}
		ReplaceSelection(selection);
		SetSelection(start, start + selection.Length());
	}
	else
	{
		// No text selection - (un)comment the current line
		int column = GetColumn(start);
		int curLineNum = GetCurrentLine();
		int pos = PositionFromLine(curLineNum);

		if (!uncomment)
		{
			InsertText(pos, comment);
		}
		else
		{
			wxString t = GetTextRange(pos, pos + comment.Length());
			if (t == comment)
			{
				// The line starts with a comment, so we remove it
				SetTargetStart(pos);
				SetTargetEnd(pos + comment.Length());
				ReplaceTarget(wxT(""));
			}
			else
			{
				// The line doesn't start with a comment, do nothing
				return false;
			}
		}

		if (GetLineCount() > curLineNum)
		{
			wxString nextLine = GetLine(curLineNum + 1);
			if (nextLine.EndsWith(lineEnd))
				nextLine = nextLine.Left(nextLine.Length() - lineEnd.Length());

			int nextColumn = (nextLine.Length() < (unsigned int)column ? nextLine.Length() : column);
			GotoPos(PositionFromLine(curLineNum + 1) + nextColumn);
		}
	}

	return true;
}
Пример #17
0
void ctlSQLBox::OnKeyDown(wxKeyEvent &event)
{
#ifdef __WXGTK__
	event.m_metaDown = false;
#endif

	// Get the line ending type
	wxString lineEnd;
	switch (GetEOLMode())
	{
		case wxSTC_EOL_LF:
			lineEnd = wxT("\n");
			break;
		case wxSTC_EOL_CRLF:
			lineEnd = wxT("\r\n");
			break;
		case wxSTC_EOL_CR:
			lineEnd = wxT("\r");
			break;
	}

	// Block comment/uncomment
	if (event.GetKeyCode() == 'K')
	{
		// Comment (Ctrl+k)
		if (event.GetModifiers() == wxMOD_CONTROL)
		{
			if (BlockComment(false))
				return;
		}
		// Uncomment (Ctrl+Shift+K)
		else if (event.GetModifiers() == (wxMOD_CONTROL | wxMOD_SHIFT))
		{
			if (BlockComment(true))
				return;
		}
	}

	// Autoindent
	if (m_autoIndent && event.GetKeyCode() == WXK_RETURN)
	{
		wxString indent, line;
		line = GetLine(GetCurrentLine());

		// Get the offset for the current line - basically, whether
		// or not it ends with a \r\n, \n or \r, and if so, the length
		int offset =  0;
		if (line.EndsWith(wxT("\r\n")))
			offset = 2;
		else if (line.EndsWith(wxT("\n")))
			offset = 1;
		else if (line.EndsWith(wxT("\r")))
			offset = 1;

		// Get the indent. This is every leading space or tab on the
		// line, up until the current cursor position.
		int x = 0;
		int max = line.Length() - (GetLineEndPosition(GetCurrentLine()) - GetCurrentPos()) - offset;
		if(line != wxEmptyString)
		{
			while ((line[x] == '\t' || line[x] == ' ') && x < max)
				indent += line[x++];
		}

		// Select any indent in front of the cursor to be removed. If
		// the cursor is positioned after any non-indent characters,
		// we don't remove anything. If there is already some selected,
		// don't select anything new at all.
		if (indent.Length() != 0 &&
		        (unsigned int)GetCurrentPos() <= ((GetLineEndPosition(GetCurrentLine()) - line.Length()) + indent.Length() + offset) &&
		        GetSelectedText() == wxEmptyString)
			SetSelection(GetLineEndPosition(GetCurrentLine()) - line.Length() + offset, GetLineEndPosition(GetCurrentLine()) - line.Length() + indent.Length() + offset);

		// Lose any selected text.
		ReplaceSelection(wxEmptyString);

		// Insert a replacement \n (or whatever), and the indent at the insertion point.
		InsertText(GetCurrentPos(), lineEnd + indent);

		// Now, reset the position, and clear the selection
		SetCurrentPos(GetCurrentPos() + indent.Length() + lineEnd.Length());
		SetSelection(GetCurrentPos(), GetCurrentPos());
	}
	else if (m_dlgFindReplace && event.GetKeyCode() == WXK_F3)
	{
		m_dlgFindReplace->FindNext();
	}
	else
		event.Skip();
}
Пример #18
0
bool ctlSQLBox::DoFind(const wxString &find, const wxString &replace, bool doReplace, bool wholeWord, bool matchCase, bool useRegexps, bool startAtTop, bool reverse)
{
	int flags = 0;
	int startPos = GetSelectionStart();
	int endPos = GetTextLength();

	// Setup flags
	if (wholeWord)
		flags |= wxSTC_FIND_WHOLEWORD;

	if (matchCase)
		flags |= wxSTC_FIND_MATCHCASE;

	// Replace the current selection, if there is one and it matches the find param.
	wxString current = GetSelectedText();
	if (doReplace)
	{
		if (useRegexps)
		{
			CharacterRange cr = RegexFindText(GetSelectionStart(), GetSelectionEnd(), find);
			if (GetSelectionStart() == cr.cpMin && GetSelectionEnd() == cr.cpMax)
			{
				if (cr.cpMin == cr.cpMax) // Must be finding a special char, such as $ (line end)
				{
					InsertText(cr.cpMax, replace);
					SetSelection(cr.cpMax, cr.cpMax + replace.Length());
					SetCurrentPos(cr.cpMax + replace.Length());

					// Stop if we've got to the end. This is important for the $
					// case where it'll just keep finding the end of the line!!
					if ((int)(cr.cpMin + replace.Length()) == GetLength())
						return false;
				}
				else
				{
					ReplaceSelection(replace);
					SetSelection(startPos, startPos + replace.Length());
					SetCurrentPos(startPos + replace.Length());
				}
			}
		}
		else if ((matchCase && current == find) || (!matchCase && current.Upper() == find.Upper()))
		{
			ReplaceSelection(replace);
			if (!reverse)
			{
				SetSelection(startPos, startPos + replace.Length());
				SetCurrentPos(startPos + replace.Length());
			}
			else
			{
				SetSelection(startPos + replace.Length(), startPos);
				SetCurrentPos(startPos);
			}
		}
	}

	////////////////////////////////////////////////////////////////////////
	// Figure out the starting position for the next search
	////////////////////////////////////////////////////////////////////////

	if (startAtTop)
	{
		startPos = 0;
		endPos = GetTextLength();
	}
	else
	{
		if (reverse)
		{
			endPos = 0;
			startPos = GetCurrentPos();
		}
		else
		{
			endPos = GetTextLength();
			startPos = GetCurrentPos();
		}
	}

	size_t selStart = 0, selEnd = 0;

	if (useRegexps)
	{
		CharacterRange cr = RegexFindText(startPos, endPos, find);
		selStart = cr.cpMin;
		selEnd = cr.cpMax;
	}
	else
	{
		selStart = FindText(startPos, endPos, find, flags);
		selEnd = selStart + find.Length();
	}

	if (selStart >= 0 && selStart != (size_t)(-1))
	{
		if (reverse)
		{
			SetCurrentPos(selStart);
			SetSelection(selEnd, selStart);
		}
		else
		{
			SetCurrentPos(selEnd);
			SetSelection(selStart, selEnd);
		}
		EnsureCaretVisible();
		return true;
	}
	else
		return false;
}
Пример #19
0
    void StyledTextBox::OnKeyPressed(wxKeyEvent& keyEvent) {

        bool eventHandled = false;
        int keycode = keyEvent.GetKeyCode();
        int originalCursorPosition = GetCursorPosition();

        // Used to indicate there was a cursor navigation event
        bool navigationEvent = false;

        if (keyEvent.GetModifiers() & wxMOD_SHIFT) {
            EnsureSelectionStarted();
        }

        // Select All
        if (keyEvent.ControlDown() && keycode == 'A') {
            SetCursorPosition(GetText().Length());
            SetSelection(0, 0);
            SetSelectionEnd(GetCursorPosition());
            eventHandled = true;
        }

        // Copy
        if (keyEvent.ControlDown() && keycode == 'C') {
            if (wxTheClipboard->Open())
            {
                wxTheClipboard->SetData(new wxTextDataObject(GetSelectedText()));
                wxTheClipboard->Close();
            }
            eventHandled = true;
        }

        // Paste
        if (keyEvent.ControlDown() && keycode == 'V') {
            if (wxTheClipboard->Open())
            {
                if (wxTheClipboard->IsSupported(wxDF_TEXT))
                {
                    wxTextDataObject data;
                    wxTheClipboard->GetData(data);
                    if (HasSelectedText()) {
                        RemoveSelectedText();
                    }
                    auto text = GetText();
                    text.insert(GetCursorPosition(), data.GetText());
                    SetText(text);
                    SetCursorPosition(GetCursorPosition() + data.GetText().Length());
                }
                wxTheClipboard->Close();
            }
        }

        if (keycode == WXK_BACK) {
            if (HasSelectedText()) {
                RemoveSelectedText();
            } else if (GetCursorPosition() > 0) {
                auto text = GetStdText();

                auto eraseStart = begin(text) + GetCursorPosition() - 1;
                auto eraseEnd = eraseStart + 1;
                text.erase(eraseStart, eraseEnd);

                SetText(text);

                SetCursorPosition(GetCursorPosition() - 1);
            }
            eventHandled = true;
            navigationEvent = true;
        }

        if (keycode == WXK_DELETE) {
            if (HasSelectedText()) {
                RemoveSelectedText();
            } else if (GetCursorPosition() < GetText().Length()) {
                auto text = GetStdText();

                auto eraseStart = begin(text) + GetCursorPosition();
                auto eraseEnd = eraseStart + 1;
                text.erase(eraseStart, eraseEnd);

                SetText(text);
            }
            return;
        } 

        if (keycode == WXK_LEFT) {
            if (GetCursorPosition() > 0) {
                SetCursorPosition(GetCursorPosition() - 1);
            }
            eventHandled = true;
            navigationEvent = true;
        }

        if (keycode == WXK_RIGHT) {
            if (GetCursorPosition() < GetText().Length()) {
                SetCursorPosition(GetCursorPosition() + 1);
            }
            eventHandled = true;
            navigationEvent = true;
        }

        if (keycode == WXK_END) {
            SetCursorPosition(GetText().Length());
            eventHandled = true;
            navigationEvent = true;
        }

        if (keycode == WXK_HOME) {
            SetCursorPosition(0);
            eventHandled = true;
            navigationEvent = true;
        }

        if (keyEvent.GetModifiers() & wxMOD_SHIFT) {
            SetSelectionEnd(GetCursorPosition());
        } else {
            if (navigationEvent) {
                ClearSelection();
            }
        }

        if (!eventHandled) {
            keyEvent.Skip();
        }

        Refresh();
    }
void cbStyledTextCtrl::OnKeyDown(wxKeyEvent& event)
{
    m_lastSelectedText = GetSelectedText();
    bool emulateDwellStart = false;

    switch ( event.GetKeyCode() )
    {
        case _T('I'):
        {
            if (event.GetModifiers() == wxMOD_ALT)
                m_braceShortcutState = true;
            break;
        }

        case WXK_TAB:
        {
            if (m_tabSmartJump && event.GetModifiers() == wxMOD_NONE)
            {
                if (!AutoCompActive() && m_bracePosition != wxSCI_INVALID_POSITION)
                {
                    m_lastPosition = GetCurrentPos();
                    GotoPos(m_bracePosition);

                    // Need judge if it's the final brace
                    HighlightRightBrace();
                    if (!m_tabSmartJump && CallTipActive())
                        CallTipCancel();
                    return;
                }
            }
        }
        break;

        case WXK_BACK:
        {
            if (m_tabSmartJump)
            {
                if (!(event.ControlDown() || event.ShiftDown() || event.AltDown()))
                {
                    const int pos = GetCurrentPos();
                    const int index = s_leftBrace.Find((wxChar)GetCharAt(pos - 1));
                    if (index != wxNOT_FOUND && (wxChar)GetCharAt(pos) == s_rightBrace.GetChar(index))
                    {
                        CharRight();
                        DeleteBack();
                    }
                }
                else if (m_lastPosition != wxSCI_INVALID_POSITION && event.ControlDown())
                {
                    GotoPos(m_lastPosition);
                    m_lastPosition = wxSCI_INVALID_POSITION;
                    return;
                }
            }
        }
        break;

        case WXK_RETURN:
        case WXK_NUMPAD_ENTER:
        case WXK_ESCAPE:
        {
            if (m_tabSmartJump)
                m_tabSmartJump = false;
        }
        break;

        case WXK_CONTROL:
        {
            EmulateDwellStart();
            emulateDwellStart = true;
        }
        break;
        default: break;
    }

    if (event.ControlDown() && !emulateDwellStart)
        EmulateDwellStart();

    event.Skip();
}