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); } }
void CodeEdit::OnCharAdded(wxStyledTextEvent& event) { // Indent the line to the same indentation as the previous line. // Adapted from http://STCntilla.sourceforge.net/STCntillaUsage.html char ch = event.GetKey(); if (ch == '\r' || ch == '\n') { int line = GetCurrentLine(); int lineLength = LineLength(line); if (line > 0 && lineLength <= 2) { wxString buffer = GetLine(line - 1); for (unsigned int i = 0; i < buffer.Length(); ++i) { if (buffer[i] != ' ' && buffer[i] != '\t') { buffer.Truncate(i); break; } } ReplaceSelection(buffer); // Remember that we just auto-indented so that the backspace // key will un-autoindent us. m_autoIndented = true; } } else if (m_enableAutoComplete && m_autoCompleteManager != NULL) { // Handle auto completion. wxString token; if (GetTokenFromPosition(GetCurrentPos() - 1, ".:", token)) { StartAutoCompletion(token); } } event.Skip(); }
void ListControlExtendedMultipleSelectStrategy::SelectItemsBetweenFocusedAndSpecified(std::size_t index) { std::size_t select_index = 0; std::size_t select_count = 0; MakeSelectionRange(index, focused_index_, select_index, select_count); auto list_control = GetListControl(); if (list_control != nullptr) { list_control->ReplaceSelection(select_index, select_count); list_control->ScrollToItemAtIndex(index); } }
bool CodeEdit::UntabifySelection() { wxString text = GetSelectedText(); if (Untabify(text)) { ReplaceSelection(text); return true; } return false; }
bool ListControlExtendedMultipleSelectStrategy::ChangeSelectionByKeyDown(const KeyMessage& message) { bool is_pressing_shift_key = (GetKeyState(VK_SHIFT) < 0); std::size_t previous_index = InvalidIndex; if (is_pressing_shift_key) { previous_index = last_focused_index_with_shift_key_; } if (previous_index == InvalidIndex) { previous_index = focused_index_; } std::size_t new_index = 0; bool is_changed = ChangeIndexByKeyDown(message, previous_index, new_index); if (! is_changed) { return false; } std::size_t select_range_index = 0; std::size_t select_range_count = 0; if (is_pressing_shift_key) { MakeSelectionRange(focused_index_, new_index, select_range_index, select_range_count); } else { select_range_index = new_index; select_range_count = 1; focused_index_ = new_index; } last_focused_index_with_shift_key_ = new_index; auto list_control = GetListControl(); if (list_control != nullptr) { list_control->ReplaceSelection(select_range_index, select_range_count); list_control->ScrollToItemAtIndex(new_index); list_control->NotifySelectionChange(); } return true; }
bool SearchableEditor::replace(bool force) { int start = GetSelectionStart(); int end = GetSelectionEnd(); if (start == end || FindText(start, end, findTextM, findFlagsM.asStc()) == -1) { if (!find(false)) return false; if (!force) return false; } // we have selection here start = GetSelectionStart(); ReplaceSelection(replaceTextM); SetSelectionEnd(start + replaceTextM.Length()); // position at end of replaced text find(false); return true; }
int SearchableEditor::replaceInSelection() { findFlagsM.remove(se::FROM_TOP); // turn flag off bool alert = findFlagsM.has(se::ALERT); if (alert) findFlagsM.remove(se::ALERT); // turn flag off temporary bool wrap = findFlagsM.has(se::WRAP); if (wrap) findFlagsM.remove(se::WRAP); // turn it off to prevent endless loop (if replace text contains search text) int cnt = 0; int selstart = GetSelectionStart(); int selend = GetSelectionEnd(); SetSelectionEnd(selstart); // start replace from here while (find(false)) { int start = GetSelectionStart(); int end = GetSelectionEnd(); if (end <= selend) // in range { selend += replaceTextM.Length() - (end-start); // expand/contract range ReplaceSelection(replaceTextM); SetSelectionEnd(start + replaceTextM.Length()); // move to appropriate position for next find() cnt++; } else break; } if (alert) { wxMessageBox(wxString::Format(_("%d replacements were made."), cnt), _("Replace"), wxICON_INFORMATION|wxOK); findFlagsM.add(se::ALERT); // turn it back on } if (wrap) // turn it back on findFlagsM.add(se::WRAP); SetSelectionStart(selstart); SetSelectionEnd(selend); return cnt; }
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; }
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(); }
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; }
win::LRESULT CtrlWindowProc(win::HWND hwnd, win::UINT msg, win::WPARAM wParam, win::LPARAM lParam){ switch(msg){ case WM_KEYDOWN: case WM_KEYUP: switch(wParam){ case VK_RETURN: if(!(te_flags&TXTED_ALLOW_EOL) || IsReadOnly()) return CallWindowProc(save_ig_proc, hwnd_ig, msg, wParam, lParam); return 0; case VK_SHIFT: case VK_LSHIFT: case VK_RSHIFT: shift_down = (msg==WM_KEYDOWN); return CallWindowProc(save_ig_proc, hwnd_ig, msg, wParam, lParam); case VK_UP: case VK_DOWN: if(!(te_flags&TXTED_ALLOW_EOL)){ if(shift_down){ SetCursorPos(wParam==VK_UP ? 0 : text.size()-1, cursor_sel); ResetCursor(); TextEditNotify(false, true, false); break; } } if(te_flags&TXTED_REAL_VISIBLE){ dword sel0, sel1; win::SendMessage(hwnd, EM_GETSEL, (win::WPARAM)&sel0, (win::LPARAM)&sel1); if(sel0!=sel1) break; int num_lines = win::SendMessage(hwnd, EM_GETLINECOUNT, 0, 0); if(wParam==VK_UP){ //check if we're on 1st line if(num_lines>1 && int(sel0)>=win::SendMessage(hwnd, EM_LINELENGTH, 0, 0)) break; }else{ if(num_lines>1 && int(sel0)<win::SendMessage(hwnd, EM_LINELENGTH, num_lines-1, 0)) break; } } case VK_F1: case VK_F2: case VK_F3: case VK_F4: case VK_F5: case VK_F6: case VK_F7: case VK_F8: case VK_F9: case VK_F10: case VK_F11: case VK_F12: #ifdef _WINDOWS case VK_ESCAPE: case VK_PRIOR: case VK_NEXT: case VK_TAB: #endif return CallWindowProc(save_ig_proc, hwnd_ig, msg, wParam, lParam); case VK_DELETE: if(mask_password){ mask_password = false; SetInitText(NULL); } /* else if(!GetTextLength()) return CallWindowProc(save_ig_proc, hwnd_ig, msg, wParam, lParam); */ break; /* case VK_LEFT: case VK_RIGHT: if(!GetTextLength()) return CallWindowProc(save_ig_proc, hwnd_ig, msg, wParam, lParam); break; */ } break; #ifdef _DEBUG case WM_SYSKEYDOWN: case WM_SYSKEYUP: if(wParam==VK_F10){ return CallWindowProc(save_ig_proc, hwnd_ig, msg, wParam, lParam); } break; #endif //* case WM_CHAR: //process end-of-line here, because Windows enters \r\n as eol if(wParam=='\r'){ if((te_flags&TXTED_ALLOW_EOL) && !IsReadOnly()){ if(!(te_flags&TXTED_REAL_VISIBLE)){ ReplaceSelection(L"\n"); TextEditNotify(false, false, true); return 0; }else return CallWindowProc(save_ctrl_proc, hwnd, msg, wParam, lParam); } return CallWindowProc(save_ig_proc, hwnd_ig, msg, wParam, lParam); }else if(wParam=='\t'){ return 0; } break; /**/ case WM_TIMER: { /* #ifdef _WIN32_WCE if(!IsWMSmartphone() && want_keyboard!=-1){ //win::SetWindowPos(hwnd_ig, b ? HWND_NOTOPMOST : HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); //UpdateWindow(hwnd_ig); if(want_keyboard){ win::SHSipPreference(hwnd_ig, C_text_editor_win32::last_sip_on ? win::SIP_UP : win::SIP_DOWN); }else{ win::SHSipPreference(hwnd_ig, win::SIP_DOWN); } want_keyboard = -1; } #endif /**/ if(win::GetFocus()!=hwnd_ctrl) win::SetFocus(hwnd_ctrl); bool cm = SetSelFromWin(); //if(cm) CorrectText(true); bool cf = TickCursor(); if(cm || cf || text_dirty){ TextEditNotify(cf, cm, text_dirty); text_dirty = false; } } break; } return CallWindowProc(save_ctrl_proc, hwnd, msg, wParam, lParam); }
BOOL CEdit::OnDrop( LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect ) { CEditView *pView; int nBuffCol, nRow; *pdwEffect = GetDropEffect( pIDataSource, grfKeyState, pt, pView, nBuffCol, nRow ); m_bDroppedHere = TRUE; BOOL bDropped = FALSE; if ( *pdwEffect != DROPEFFECT_NONE ) { FORMATETC fe = { CLIP_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; STGMEDIUM stgm; if ( !SUCCEEDED( pIDataSource->GetData( &fe, &stgm ) ) ) { // data could not be retrieved m_Selection.SetEmptySelection( nBuffCol, nRow ); m_Selection.ShowCaret(); return FALSE; } HGLOBAL hMem = stgm.hGlobal; ASSERT( hMem ); LPCTSTR pszText = ( LPCTSTR ) GlobalLock( hMem ); m_Buffer.BeginEdit( m_Selection.GetEndRow(), m_Selection.GetEndCol() ); if ( pszText && IsDragAndDropping() ) { // we are dragging and dropping from within this control -- be careful how // the *current* selection is handled POINT ptClient = { pt.x, pt.y }; ScreenToClient( m_hWnd, &ptClient ); if ( PtInSelection( ptClient.x, ptClient.y, FALSE ) ) { m_Selection.SetEmptySelection( nBuffCol, nRow ); } else { BOOL bMove = HAS_FLAG( *pdwEffect, DROPEFFECT_MOVE ); int nStartRow, nStartCol, nEndRow, nEndCol; m_Selection.GetNormalizedBufferSelection( nStartCol, nStartRow, nEndCol, nEndRow ); if (nRow == nStartRow && nBuffCol == nStartCol) { // nothing really to do -- the source and destination are identical. // We do however need to erase the drag insertion caret. DamageSelection(FALSE); } else if ( ( nRow < nStartRow ) || ( nRow == nStartRow && nBuffCol < nStartCol ) ) { // dragging before the selection -- delete the selection first (if move) if ( bMove ) DeleteSelection( FALSE, FALSE ); m_Selection.SetEmptySelection( nBuffCol, nRow ); ReplaceSelection( pszText, FALSE, TRUE, TRUE ); } else { // dragging after the selection -- insert the new text first m_Selection.SetEmptySelection( nBuffCol, nRow ); ReplaceSelection( pszText, FALSE, TRUE, TRUE ); int nStartRowNew, nStartColNew, nEndRowNew, nEndColNew; m_Selection.GetNormalizedBufferSelection( nStartColNew, nStartRowNew, nEndColNew, nEndRowNew ); if ( bMove ) { m_Selection.SetExtendedSelection( nStartCol, nStartRow, nEndCol, nEndRow ); DeleteSelection( FALSE, FALSE ); } // we want to select the dropped text, but we must first factor in the // shift caused by the text that was just deleted. if ( nStartRowNew == nEndRow ) { ASSERT( nStartColNew >= nEndCol ); if ( nStartRow == nEndRow ) nStartColNew -= nEndCol - nStartCol; else if ( nStartRowNew == nEndRow ) nStartColNew = nStartCol + nStartColNew - nEndCol; else nStartColNew -= nEndCol; } nStartRowNew -= nEndRow - nStartRow; if ( nEndRowNew == nEndRow ) { ASSERT( nEndColNew > nEndCol ); if ( nStartRow == nEndRow ) nEndColNew -= nEndCol - nStartCol; else nEndColNew -= nEndCol; } nEndRowNew -= nEndRow - nStartRow; // select the dropped text m_Selection.SetExtendedSelection( nStartColNew, nStartRowNew, nEndColNew, nEndRowNew ); } } } else { // data came from another window -- just insert it as usual -- the other window // will remove the text if a move m_Selection.SetEmptySelection( nBuffCol, nRow ); ReplaceSelection( pszText, FALSE, TRUE, TRUE ); } if ( m_pActiveView != pView ) { SetActiveView( pView ); } m_Buffer.EndEdit( m_Selection.GetEndRow(), m_Selection.GetEndCol() ); GlobalUnlock( hMem ); if ( !stgm.pUnkForRelease ) { // provider of data decided that we should release the data ReleaseStgMedium( &stgm ); } bDropped = TRUE; } m_Selection.ShowCaret(); return bDropped; }
// TOOD: map flags; detect wrap around void Edit::OnFindDialog(wxFindDialogEvent& event) { wxEventType type = event.GetEventType(); if(type == wxEVT_FIND || type == wxEVT_FIND_NEXT) { const wxString find = event.GetFindString(); const int curPos = FindLine(event); if(curPos > -1) { GotoPos(curPos); SetSelectionStart(curPos); SetSelectionEnd(curPos + find.size()); } else { wxLogMessage(wxT("Unable to find \"%s\""), find); } } else if(type == wxEVT_FIND_REPLACE) { const wxString find = event.GetFindString(); const int curPos = FindLine(event); if(curPos > -1) { SetSelectionStart(curPos); SetSelectionEnd(curPos + find.size()); ReplaceSelection(event.GetReplaceString()); } else { wxLogMessage(wxT("Unable to find \"%s\""), find); } } else if(type == wxEVT_FIND_REPLACE_ALL) { const wxString find = event.GetFindString(); const wxString replace = event.GetReplaceString(); const long minPos = GetCurrentPos(); const long maxPos = GetLastPosition(); int count = 0; int curPos = FindText(minPos, maxPos, find); while(curPos > minPos) { ++count; SetSelectionStart(curPos); SetSelectionEnd(curPos + find.size()); ReplaceSelection(replace); curPos = FindText(curPos + replace.size(), maxPos, find); } wxLogMessage(wxT("Replaced %d instance(s) of \"%s\" were replaced with \"%s\""), count, find, replace); } // FIX ME... else if(type == wxEVT_FIND_CLOSE) { /* if(event.GetDialog() == m_dlgFind) { wxDELETE(m_dlgFind); m_dlgFind = NULL; } else if(event.GetDialog() == m_dlgReplace) { wxDELETE(m_dlgReplace); m_dlgReplace = NULL; } */ } }
void CEdit::FindReplaceSelection() { if ( g_FindReplaceData.m_bPreserveCase ) { /////////////////////////////////////// // // Format the replace text such that it follows the same // case pattern of the find text: // // a) All lower // b) All upper // c) First n chars all upper // // HGLOBAL hMem = NULL; // Selection should be normalized by caller! ASSERT( m_Selection.GetStartRow() <= m_Selection.GetEndRow() ); ASSERT( m_Selection.GetStartRow() < m_Selection.GetEndRow() || m_Selection.GetStartCol() < m_Selection.GetEndCol() ); VERIFY( m_Buffer.GetText( m_Selection.GetStartRow(), m_Selection.GetStartCol(), m_Selection.GetEndRow(), m_Selection.GetEndCol(), hMem, FALSE, FALSE ) ); ASSERT( hMem ); LPCTSTR pszFind = ( LPCTSTR ) GlobalLock( hMem ); BOOL bUpper = TRUE; BOOL bLower = TRUE; int nFirstUpper = 0; LPCTSTR psz = pszFind; while ( *psz ) { TCHAR chUpper = g_UpperConv[ ( BYTE ) *psz ]; bUpper &= ( chUpper == *psz ); bLower &= ( chUpper != *psz ); if ( bUpper ) { nFirstUpper++; } psz++; } LPTSTR pszOut = new TCHAR[ _tcslen( g_FindReplaceData.m_pszReplaceText ) + 1 ]; _tcscpy( pszOut, g_FindReplaceData.m_pszReplaceText ); if ( bUpper ) { CharUpper( pszOut ); } else if ( bLower ) { CharLower( pszOut ); } else if ( nFirstUpper ) { CharLower( pszOut ); LPTSTR psz = pszOut; while ( nFirstUpper-- && *psz ) { *psz = g_UpperConv[ ( BYTE ) *psz ]; psz++; } } ReplaceSelection( pszOut, FALSE ); delete [] pszOut; GlobalUnlock( hMem ); GlobalFree( hMem ); } else { ReplaceSelection( g_FindReplaceData.m_pszReplaceText, FALSE ); } }