public SelectionKeyProcessor(TerminalPane owner, TerminalDocument doc, GLine line, int pos) { _owner = owner; _document = doc; Debug.Assert(line!=null); _currentLine = line; _caretPos = pos; }
public void WriteLine(GLine line) { }
public GLine Export() { GWord w = new GWord(_decorations[0]==null? TextDecoration.ClonedDefault() : _decorations[0], 0, GLine.CalcCharGroup(_text[0])); GLine line = new GLine(_text, w); line.EOLType = _eolType; int m = _text.Length; for(int offset=1; offset<m; offset++) { char ch = _text[offset]; if(ch=='\0') break; else if(ch==GLine.WIDECHAR_PAD) continue; TextDecoration dec = _decorations[offset]; if(_decorations[offset-1]!=dec || w.CharGroup!=GLine.CalcCharGroup(ch)) { if(dec==null) dec = TextDecoration.ClonedDefault(); //!!�{���͂�����null�ɂȂ��Ă���̂͂��肦�Ȃ��͂��B��Œ������邱�� GWord ww = new GWord(dec, offset, GLine.CalcCharGroup(ch)); w.Next = ww; w = ww; } } return line; }
//index�̈ʒu�̕\���]�����V����GLine��Ԃ� //inverse��false���ƁAGWord�̕����͂��邪Decoration�̔��]�͂��Ȃ��B�q�N�q�N���̑Ώ��Ƃ��Ď����B internal GLine InverseCaret(int index, bool inverse, bool underline) { ExpandBuffer(index+1); if(_text[index]==WIDECHAR_PAD) index--; GLine ret = new GLine(_text, null); ret.ID = _id; ret.EOLType = _eolType; GWord w = _firstWord; int nextoffset = 0; while(w!=null) { nextoffset = WordNextOffset(w); if(w.Offset<=index && index<nextoffset) { //!!tail���珇�ɘA���������������͂悢 if(w.Offset<index) { GWord head = new GWord(w.Decoration, w.Offset, w.CharGroup); ret.Append(head); } TextDecoration dec = (TextDecoration)w.Decoration.Clone(); if(inverse) { //�F���L�����b�g�̃T�|�[�g dec.ToCaretStyle(); } if(underline) dec.Underline = true; GWord mid = new GWord(dec, index, w.CharGroup); ret.Append(mid); if(index+CalcDisplayLength(_text[index]) < nextoffset) { GWord tail = new GWord(w.Decoration, index+CalcDisplayLength(_text[index]), w.CharGroup); ret.Append(tail); } } else ret.Append(w.StandAloneClone()); w = w.Next; } //!!���́A�L�����b�g�ʒu�ɃX�y�[�X������̂�Inverse�Ƃ͈Ⴄ�����ł��邩�番�����邱�� if(nextoffset<=index) { while(nextoffset<=index) { Debug.Assert(nextoffset < ret.Text.Length); ret.Text[nextoffset++] = ' '; } TextDecoration dec = TextDecoration.ClonedDefault(); if(inverse) { dec.ToCaretStyle(); } if(underline) dec.Underline = true; ret.Append(new GWord(dec, index, CharGroup.SingleByte)); } return ret; }
/// <summary> /// �����Ɠ�����e�ŏ���������Bline�̓�e�͔j��Ȃ��B /// ������null�̂Ƃ��͈����Ȃ��̃R���X�g���N�^�Ɠ������ʂɂȂ�B /// </summary> public void Load(GLine line, int cc) { if(line==null) { //���ꂪnull�ɂȂ��Ă���Ƃ����v���Ȃ��N���b�V�����|�[�g���������B�{���͂Ȃ��͂��Ȃ�... Clear(80); return; } Clear(line.Length); GWord w = line.FirstWord; Debug.Assert(line.Text.Length==_text.Length); Array.Copy(line.Text, 0, _text, 0, _text.Length); int n = 0; while(w != null) { int nextoffset = line.WordNextOffset(w); while(n < nextoffset) _decorations[n++] = w.Decoration; w = w.Next; } _eolType = line.EOLType; ExpandBuffer(cc+1); this.CaretColumn = cc; //' '�Ŗ��߂邱�Ƃ����̂Ńv���p�e�B�Z�b�g��g�� }
public bool ProcessKey(Keys key) { Keys body = key & Keys.KeyCode; bool shift = (key & Keys.Shift) != Keys.None; bool control = (key & Keys.Control) != Keys.None; bool processed = false; //�ړ���̍s�ƌ��̌v�Z GLine nextLine = _currentLine; _document.InvalidateLine(nextLine.ID); if(body==Keys.Up) { if(_currentLine.PrevLine!=null) nextLine = _currentLine.PrevLine; _document.InvalidateLine(nextLine.ID); processed = true; } else if(body==Keys.Down) { if(_currentLine.NextLine!=null) nextLine = _currentLine.NextLine; _document.InvalidateLine(nextLine.ID); processed = true; } else if(body==Keys.PageUp) { int n = _currentLine.ID - _owner.Connection.TerminalHeight; nextLine = n<=_document.FirstLineNumber? _document.FirstLine : _document.FindLine(n); _document.InvalidateAll(); processed = true; } else if(body==Keys.PageDown) { int n = _currentLine.ID + _owner.Connection.TerminalHeight; nextLine = n>=_document.LastLineNumber? _document.LastLine : _document.FindLine(n); _document.InvalidateAll(); processed = true; } int nextPos = _caretPos; if(body==Keys.Home) { nextPos = 0; processed = true; } else if(body==Keys.End) { nextPos = _currentLine.CharLength-1; processed = true; } else if(body==Keys.Left) { if(nextPos>0) { if(control) nextPos = _currentLine.FindPrevWordBreak(nextPos-1)+1; else nextPos--; } processed = true; } else if(body==Keys.Right) { if(nextPos<_currentLine.CharLength-1) { if(control) nextPos = _currentLine.FindNextWordBreak(nextPos+1); else nextPos++; } processed = true; } //�I��̈�̒��� TextSelection sel = GEnv.TextSelection; if(shift && processed) { if(sel.IsEmpty) sel.StartSelection(_owner, _currentLine, _caretPos, RangeType.Char, -1, -1); sel.ExpandTo(nextLine, nextPos, RangeType.Char); } else if(processed || body==Keys.Menu || body==Keys.ControlKey || body==Keys.ShiftKey) { if(processed) sel.Clear(); processed = true; } else { //��ʃL�[�̓��͂��������瑦���I���� sel.Clear(); } Debug.Assert(nextLine!=null); _currentLine = nextLine; _caretPos = nextPos; return processed; }
public abstract void AddLine(GLine line);
public void WriteLine(GLine line) { if (!_parent.LogSuspended) { _logger.WriteLine(line); string s = new string(line.Text).Trim('\0');//edited by xavier //Trace.Write(s); Trace.Write("\r");//edited by xavier log.Info(_controlName + ": " + s); //log.Info("\r");//edited by xavier } }
internal void Remove(GLine line) { if(_size<=1) { Clear(); return; } if(line.PrevLine!=null) { line.PrevLine.NextLine = line.NextLine; } if(line.NextLine!=null) { line.NextLine.PrevLine = line.PrevLine; } if(line==_firstLine) _firstLine = line.NextLine; if(line==_lastLine) _lastLine = line.PrevLine; if(line==_topLine) { _topLine = line.NextLine; } if(line==_currentLine) { _currentLine = line.NextLine; if(_currentLine==null) _currentLine = _lastLine; } _size--; _invalidatedAll = true; }
/// <summary> /// �Ō��remain�s�ȑO��폜���� /// </summary> internal int DiscardOldLines(int remain) { int delete_count = _size - remain; if(delete_count <= 0) return 0; GLine newfirst = _firstLine; for(int i=0; i<delete_count; i++) newfirst = newfirst.NextLine; //�V�����擪����߂� _firstLine = newfirst; newfirst.PrevLine.NextLine = null; newfirst.PrevLine = null; _size -= delete_count; Debug.Assert(_size==remain); AssertValid(); if(_topLine.ID<_firstLine.ID) _topLine=_firstLine; if(_currentLine.ID<_firstLine.ID) { _currentLine = _firstLine; _caretColumn = 0; } return delete_count; }
internal void Clear() { _caretColumn = 0; _firstLine = null; _lastLine = null; _size = 0; AddLine(new GLine(_connection.TerminalWidth)); }
//�����ɒlj����� internal void AddLine(GLine line) { if(_firstLine==null) { //���� _firstLine = line; _lastLine = line; _currentLine = line; _topLine = line; _size = 1; line.ID = 0; InvalidateLine(0); } else { //�ʏ�̒lj� Debug.Assert(_lastLine.NextLine==null); int lastID = _lastLine.ID; _lastLine.NextLine = line; line.PrevLine = _lastLine; _lastLine = line; line.ID = lastID+1; _size++; InvalidateLine(lastID+1); } }
//�Đڑ��p�Ɍ��݃h�L�������g�̑O�ɑ}�� public void InsertBefore(TerminalDocument olddoc, int paneheight) { lock(this) { GLine c = olddoc.LastLine; int offset = _currentLine.ID - _topLine.ID; bool flag = false; while(c!=null) { if(flag || c.Text[0]!='\0') { flag = true; GLine nl = c.Clone(); nl.ID = _firstLine.ID-1; InsertBefore(_firstLine, nl); //�ŏ��ɋ�łȂ��s������Έȍ~�͑S���}�� offset++; } c = c.PrevLine; } //ID�����ɂȂ�̂͂�����ƕ|���̂ŏC�� if(_firstLine.ID<0) { int t = -_firstLine.ID; c = _firstLine; while(c!=null) { c.ID += t; c = c.NextLine; } } _topLine = FindLineOrEdge(_currentLine.ID - Math.Min(offset, paneheight)); //Dump("insert doc"); } }
internal bool StartSelection(TerminalPane owner, GLine line, int position, RangeType type, int x, int y) { Debug.Assert(owner!=null); Debug.Assert(position>=0); line.ExpandBuffer(position+1); _disabledTemporary = false; _owner = owner; _pivotType = type; _forwardPivot._line = line.ID; _backwardPivot._line = line.ID; _forwardDestination._line = line.ID; _forwardDestination._position = position; _backwardDestination._line = line.ID; _backwardDestination._position = position; switch(type) { case RangeType.Char: _forwardPivot._position = position; _backwardPivot._position = position; break; case RangeType.Word: _forwardPivot._position = line.FindPrevWordBreak(position)+1; _backwardPivot._position = line.FindNextWordBreak(position); break; case RangeType.Line: _forwardPivot._position = 0; _backwardPivot._position = line.CharLength; break; } _state = SelectionState.Pivot; _startX = x; _startY = y; return true; }
internal bool ExpandTo(GLine line, int position, RangeType type) { line.ExpandBuffer(position+1); _disabledTemporary = false; _state = SelectionState.Expansion; _forwardDestination._line = line.ID; _backwardDestination._line = line.ID; //Debug.WriteLine(String.Format("ExpandTo Line{0} Position{1}", line.ID, position)); switch(type) { case RangeType.Char: _forwardDestination._position = position; _backwardDestination._position = position; break; case RangeType.Word: _forwardDestination._position = line.FindPrevWordBreak(position)+1; _backwardDestination._position = line.FindNextWordBreak(position); break; case RangeType.Line: _forwardDestination._position = 0; _backwardDestination._position = line.CharLength; break; } return true; }
private void InsertBefore(GLine pos, GLine line) { if(pos.PrevLine!=null) pos.PrevLine.NextLine = line; line.PrevLine = pos.PrevLine; line.NextLine = pos; pos.PrevLine = line; if(pos==_firstLine) _firstLine = line; _size++; _invalidatedAll = true; }
internal void RemoveAfter(int from) { if(from > _lastLine.ID) return; GLine delete = FindLineOrEdge(from); if(delete==null) return; GLine remain = delete.PrevLine; delete.PrevLine = null; if(remain==null) { Clear(); } else { remain.NextLine = null; _lastLine = remain; while(delete!=null) { _size--; if(delete==_topLine) _topLine = remain; if(delete==_currentLine) _currentLine = remain; delete = delete.NextLine; } } AssertValid(); _invalidatedAll = true; }
internal void Replace(GLine target, GLine newline) { newline.NextLine = target.NextLine; newline.PrevLine = target.PrevLine; if(target.NextLine!=null) target.NextLine.PrevLine = newline; if(target.PrevLine!=null) target.PrevLine.NextLine = newline; if(target==_firstLine) _firstLine = newline; if(target==_lastLine) _lastLine = newline; if(target==_topLine) _topLine = newline; if(target==_currentLine) _currentLine = newline; newline.ID = target.ID; InvalidateLine(newline.ID); AssertValid(); }
internal void ReplaceCurrentLine(GLine line) { #if DEBUG Replace(_currentLine, line); AssertValid(); #else if(_currentLine!=null) //�N���b�V�����|�[�g��݂�ƁA�����̔��q��null�ɂȂ��Ă����Ƃ����v���Ȃ� Replace(_currentLine, line); #endif }
internal void ScrollDown(int from, int to) { GLine top = FindLineOrEdge(from); GLine bottom = FindLineOrEdge(to); int top_id = top.ID; GLine newtop = top.NextLine; if(from==to) { _currentLine = top; _currentLine.Clear(); } else { Remove(top); //_topLine�̒����͕K�v�Ȃ炱���ōs���� _currentLine = new GLine(_connection.TerminalWidth); InsertAfter(bottom, _currentLine); //id maintainance GLine c = newtop; GLine end = _currentLine.NextLine; while(c != end) { c.ID = top_id++; c = c.NextLine; } } AssertValid(); _invalidatedAll = true; }
public void WriteLine(GLine line) { if(!_parent.LogSuspended) _logger.WriteLine(line); }
internal void ScrollUp(int from, int to) { GLine top = FindLineOrEdge(from); GLine bottom = FindLineOrEdge(to); if(top==null || bottom==null) return; //�G���[�n���h�����O��FindLine�̒��ŁB�����ł̓N���b�V����������s�� int bottom_id = bottom.ID; int topline_id = _topLine.ID; GLine nextbottom = bottom.NextLine; if(from==to) { _currentLine = top; _currentLine.Clear(); } else { Remove(bottom); _currentLine = new GLine(_connection.TerminalWidth); InsertBefore(top, _currentLine); GLine c = _currentLine; do { c.ID = from++; c = c.NextLine; } while(c!=nextbottom); Debug.Assert(nextbottom==null || nextbottom.ID==from); } /* //id maintainance GLine c = newbottom; GLine end = _currentLine.PrevLine; while(c != end) { c.ID = bottom_id--; c = c.PrevLine; } */ //!!���̂Q�s��xterm�����Ă���Ԃɔ������ďC���B VT100�ł͉����̕K�v�������Ă����Ȃ����͂��Ȃ̂Ō�Œ��ׂ邱�� //if(_scrollingTop<=_topLine.ID && _topLine.ID<=_scrollingBottom) // _topLine = _currentLine; while(topline_id<_topLine.ID) _topLine = _topLine.PrevLine; AssertValid(); _invalidatedAll = true; }
public GLine Clone() { GLine nl = new GLine(_text, _firstWord.DeepClone()); nl._eolType = _eolType; nl._id = _id; return nl; }
private GLine FindLineByHint(int index, GLine hintLine) { int h = hintLine.ID; GLine l = hintLine; if(index >= h) { for(int i=h; i<index; i++) { l = l.NextLine; if(l==null) FindLineByHintFailed(index, hintLine); } } else { for(int i=h; i>index; i--) { l = l.PrevLine; if(l==null) FindLineByHintFailed(index, hintLine); } } return l; }
internal GLine InverseRange(int from, int to) { ExpandBuffer(Math.Max(from+1,to)); //���������T�C�Y�����Ƃ��Ȃǂɂ��̏�����������Ȃ����Ƃ����� Debug.Assert(from>=0 && from<_text.Length); if(from<_text.Length && _text[from]==WIDECHAR_PAD) from--; if(to>0 && to-1<_text.Length && _text[to-1]==WIDECHAR_PAD) to--; GLine ret = new GLine(_text, null); ret.ID = _id; ret.EOLType = _eolType; //�����̔z���Z�b�g TextDecoration[] dec = new TextDecoration[_text.Length]; GWord w = _firstWord; while(w!=null) { Debug.Assert(w.Decoration!=null); dec[w.Offset] = w.Decoration; w = w.Next; } //���]�J�n�_ TextDecoration original = null; TextDecoration inverse = null; for(int i=from; i>=0; i--) { if(dec[i]!=null) { original = dec[i]; break; } } Debug.Assert(original!=null); inverse = (TextDecoration)original.Clone(); inverse.Inverse(); dec[from] = inverse; //�͈͂ɓn���Ĕ��]��� for(int i=from+1; i<to; i++) { if(i<dec.Length && dec[i]!=null) { original = dec[i]; inverse = (TextDecoration)original.Clone(); inverse.Inverse(); dec[i] = inverse; } } if(to<dec.Length && dec[to]==null) dec[to] = original; //����ɏ]����GWord���� w = null; for(int i=dec.Length-1; i>=0; i--) { char ch = _text[i]; if(dec[i]!=null && ch!='\0') { int j = i; if(ch==WIDECHAR_PAD) j++; GWord ww = new GWord(dec[i], j, CalcCharGroup(ch)); ww.Next = w; w = ww; } } ret.Append(w); return ret; }
//FindLineByHint�͂����Ύ��s����̂Ńf�o�b�O�p�Ɍ��ݏ�Ԃ�_���v private void FindLineByHintFailed(int index, GLine hintLine) { #if DEBUG Dump(String.Format("FindLine {0}, hint_id={1}", index, hintLine.ID)); Debugger.Break(); #endif GEnv.InterThreadUIService.InvalidDocumentOperation(this, GEnv.Strings.GetString("Message.TerminalDocument.UnexpectedCode")); }
public override void WriteLine(GLine line) { char[] t = line.Text; for(int i=0; i<line.CharLength; i++) { char ch = t[i]; if(ch!=GLine.WIDECHAR_PAD) _writer.Write(ch); } _writer.WriteLine(); //_writer.WriteLine(line.Text, 0, line.CharLength); }
private void InsertAfter(GLine pos, GLine line) { if(pos.NextLine!=null) pos.NextLine.PrevLine = line; line.NextLine = pos.NextLine; line.PrevLine = pos; pos.NextLine = line; if(pos==_lastLine) _lastLine = line; _size++; _invalidatedAll = true; }
//!!�s�P�ʂ̏������� ���͕W���Ƃ���ȊO�ł̓��O�̈������ɋ��ʓ_�����܂�Ȃ��̂ɋ����Ɉ�̃N���X�ɂ܂Ƃ߂悤�Ƃ��ă{�����ł� public virtual void WriteLine(GLine line) { }
public bool ProcessKey(Keys key) { Keys body = key & Keys.KeyCode; bool shift = (key & Keys.Shift) != Keys.None; bool control = (key & Keys.Control) != Keys.None; bool processed = false; //移動先の行と桁の計算 GLine nextLine = _currentLine; _document.InvalidateLine(nextLine.ID); if (body == Keys.Up) { if (_currentLine.PrevLine != null) { nextLine = _currentLine.PrevLine; } _document.InvalidateLine(nextLine.ID); processed = true; } else if (body == Keys.Down) { if (_currentLine.NextLine != null) { nextLine = _currentLine.NextLine; } _document.InvalidateLine(nextLine.ID); processed = true; } else if (body == Keys.PageUp) { int n = _currentLine.ID - _owner.Connection.TerminalHeight; nextLine = n <= _document.FirstLineNumber? _document.FirstLine : _document.FindLine(n); _document.InvalidateAll(); processed = true; } else if (body == Keys.PageDown) { int n = _currentLine.ID + _owner.Connection.TerminalHeight; nextLine = n >= _document.LastLineNumber? _document.LastLine : _document.FindLine(n); _document.InvalidateAll(); processed = true; } int nextPos = _caretPos; if (body == Keys.Home) { nextPos = 0; processed = true; } else if (body == Keys.End) { nextPos = _currentLine.CharLength - 1; processed = true; } else if (body == Keys.Left) { if (nextPos > 0) { if (control) { nextPos = _currentLine.FindPrevWordBreak(nextPos - 1) + 1; } else { nextPos--; } } processed = true; } else if (body == Keys.Right) { if (nextPos < _currentLine.CharLength - 1) { if (control) { nextPos = _currentLine.FindNextWordBreak(nextPos + 1); } else { nextPos++; } } processed = true; } //選択領域の調整 TextSelection sel = GEnv.TextSelection; if (shift && processed) { if (sel.IsEmpty) { sel.StartSelection(_owner, _currentLine, _caretPos, RangeType.Char, -1, -1); } sel.ExpandTo(nextLine, nextPos, RangeType.Char); } else if (processed || body == Keys.Menu || body == Keys.ControlKey || body == Keys.ShiftKey) { if (processed) { sel.Clear(); } processed = true; } else { //一般キーの入力があったら即時選択解除 sel.Clear(); } Debug.Assert(nextLine != null); _currentLine = nextLine; _caretPos = nextPos; return(processed); }