editors: fix remove prev/next word

This commit is contained in:
Vadim Lopatin 2014-04-24 19:45:31 +04:00
parent fb55d64849
commit 5afa935930
2 changed files with 28 additions and 19 deletions

View File

@ -231,6 +231,14 @@ class Window {
/// dispatch keyboard event /// dispatch keyboard event
bool dispatchKeyEvent(KeyEvent event) { bool dispatchKeyEvent(KeyEvent event) {
if (event.action == KeyAction.Text) {
// filter text
if (event.text.length < 1)
return false;
dchar ch = event.text[0];
if (ch < ' ' || ch == 0x7F) // filter out control symbols
return false;
}
Widget focus = focusedWidget; Widget focus = focusedWidget;
if (focus !is null) { if (focus !is null) {
if (focus.onKeyEvent(event)) if (focus.onKeyEvent(event))

View File

@ -598,7 +598,8 @@ class EditableContent {
throw new Exception("content is readonly"); throw new Exception("content is readonly");
if (op.action == EditAction.Replace) { if (op.action == EditAction.Replace) {
TextRange rangeBefore = op.range; TextRange rangeBefore = op.range;
correctRange(rangeBefore); assert(rangeBefore.start <= rangeBefore.end);
//correctRange(rangeBefore);
dstring[] oldcontent = rangeText(rangeBefore); dstring[] oldcontent = rangeText(rangeBefore);
dstring[] newcontent = op.content; dstring[] newcontent = op.content;
if (newcontent.length == 0) if (newcontent.length == 0)
@ -613,6 +614,7 @@ class EditableContent {
// same line // same line
rangeAfter.end.pos = rangeAfter.start.pos + cast(int)newcontent[0].length; rangeAfter.end.pos = rangeAfter.start.pos + cast(int)newcontent[0].length;
} }
assert(rangeAfter.start <= rangeAfter.end);
op.newRange = rangeAfter; op.newRange = rangeAfter;
op.oldContent = oldcontent; op.oldContent = oldcontent;
replaceRange(rangeBefore, rangeAfter, newcontent); replaceRange(rangeBefore, rangeAfter, newcontent);
@ -980,6 +982,7 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
} }
override void onContentChange(EditableContent content, EditOperation operation, ref TextRange rangeBefore, ref TextRange rangeAfter, Object source) { override void onContentChange(EditableContent content, EditOperation operation, ref TextRange rangeBefore, ref TextRange rangeAfter, Object source) {
Log.d("onContentChange rangeBefore=", rangeBefore, " rangeAfter=", rangeAfter, " text=", operation.content);
updateMaxLineWidth(); updateMaxLineWidth();
measureVisibleText(); measureVisibleText();
if (source is this) { if (source is this) {
@ -1169,10 +1172,12 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
protected bool removeRangeText(TextRange range) { protected bool removeRangeText(TextRange range) {
if (range.empty) if (range.empty)
return false; return false;
_selectionRange = range; //_selectionRange = range;
_caretPos = _selectionRange.end; //_caretPos = _selectionRange.end;
EditOperation op = new EditOperation(EditAction.Replace, range, [""d]); EditOperation op = new EditOperation(EditAction.Replace, range, [""d]);
_content.performOperation(op, this); _content.performOperation(op, this);
//_selectionRange.start = _caretPos;
//_selectionRange.end = _caretPos;
ensureCaretVisible(); ensureCaretVisible();
return true; return true;
} }
@ -1271,9 +1276,8 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
if (removeSelectionTextIfSelected()) // clear selection if (removeSelectionTextIfSelected()) // clear selection
return true; return true;
TextPosition newpos = _content.moveByWord(_caretPos, -1, _camelCasePartsAsWords); TextPosition newpos = _content.moveByWord(_caretPos, -1, _camelCasePartsAsWords);
if (newpos != _caretPos) { if (newpos < _caretPos)
removeRangeText(TextRange(newpos, _caretPos)); removeRangeText(TextRange(newpos, _caretPos));
}
return true; return true;
case EditorActions.DelNextWord: case EditorActions.DelNextWord:
if (readOnly) if (readOnly)
@ -1282,9 +1286,8 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
if (removeSelectionTextIfSelected()) // clear selection if (removeSelectionTextIfSelected()) // clear selection
return true; return true;
TextPosition newpos = _content.moveByWord(_caretPos, 1, _camelCasePartsAsWords); TextPosition newpos = _content.moveByWord(_caretPos, 1, _camelCasePartsAsWords);
if (newpos != _caretPos) { if (newpos > _caretPos)
removeRangeText(TextRange(_caretPos, newpos)); removeRangeText(TextRange(_caretPos, newpos));
}
return true; return true;
case EditorActions.DelPrevChar: case EditorActions.DelPrevChar:
if (readOnly) if (readOnly)
@ -1557,18 +1560,16 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
if (readOnly) if (readOnly)
return true; return true;
dchar ch = event.text[0]; dchar ch = event.text[0];
if (ch >= 32) { // ignore Backspace, Tab, Return, etc. chars if (replaceMode && _selectionRange.empty && _content[_caretPos.line].length >= _caretPos.pos + event.text.length) {
if (replaceMode && _selectionRange.empty && _content[_caretPos.line].length >= _caretPos.pos + event.text.length) { // replace next char(s)
// replace next char(s) TextRange range = _selectionRange;
TextRange range = _selectionRange; range.end.pos += cast(int)event.text.length;
range.end.pos += cast(int)event.text.length; EditOperation op = new EditOperation(EditAction.Replace, range, [event.text]);
EditOperation op = new EditOperation(EditAction.Replace, range, [event.text]); _content.performOperation(op, this);
_content.performOperation(op, this); } else {
} else { EditOperation op = new EditOperation(EditAction.Replace, _selectionRange, [event.text]);
EditOperation op = new EditOperation(EditAction.Replace, _selectionRange, [event.text]); _content.performOperation(op, this);
_content.performOperation(op, this); }
}
}
return true; return true;
} }
return super.onKeyEvent(event); return super.onKeyEvent(event);