public void OnPromptLine(GLine line, string prompt, string command) { _isPrompt = true; _lastLine = line; _promptText = prompt; _commandText = command; }
/// <summary> /// Clone this instance that text attributes in the specified range are inverted. /// </summary> /// <param name="from">start column index of the range. (inclusive)</param> /// <param name="to">end column index of the range. (exclusive)</param> /// <returns>new instance</returns> internal GLine CreateInvertedClone(int from, int to) { ExpandBuffer(Math.Max(from + 1, to)); //激しくリサイズしたときなどにこの条件が満たせないことがある Debug.Assert(from >= 0 && from < _text.Length); if (from < _text.Length && _text[from] == WIDECHAR_PAD) from--; if (to < _text.Length && _text[to] == WIDECHAR_PAD) to++; const int PHASE_LEFT = 0; const int PHASE_MIDDLE = 1; const int PHASE_RIGHT = 2; int phase = PHASE_LEFT; int inverseIndex = from; GWord first = null; GWord last = null; for (GWord word = _firstWord; word != null; word = word.Next) { TextDecoration originalDecoration = word.Decoration; if (originalDecoration == null) originalDecoration = TextDecoration.Default; int wordStart = word.Offset; int wordEnd = GetNextOffset(word); do { GWord newWord; if (phase == PHASE_RIGHT || inverseIndex < wordStart || wordEnd <= inverseIndex) { TextDecoration newDec = (phase == PHASE_MIDDLE) ? originalDecoration.GetInvertedCopy() : originalDecoration; newWord = new GWord(newDec, wordStart, word.CharGroup); wordStart = wordEnd; } else { TextDecoration leftDec = (phase == PHASE_LEFT) ? originalDecoration : originalDecoration.GetInvertedCopy(); if (wordStart < inverseIndex) newWord = new GWord(leftDec, wordStart, word.CharGroup); else newWord = null; wordStart = inverseIndex; // update phase if (phase == PHASE_LEFT) { phase = PHASE_MIDDLE; inverseIndex = to; } else if (phase == PHASE_MIDDLE) { phase = PHASE_RIGHT; } } // append new GWord to the list. if (newWord != null) { if (last == null) first = newWord; else last.Next = newWord; last = newWord; } } while (wordStart < wordEnd); } GLine ret = new GLine((char[])_text.Clone(), _displayLength, first); ret.ID = _id; ret.EOLType = _eolType; return ret; }
/// <summary> /// <ja> /// データをエクスポートします。 /// </ja> /// <en> /// Export the data. /// </en> /// </summary> /// <returns><ja>エクスポートされたGLineオブジェクト</ja><en>Exported GLine object</en></returns> public GLine Export() { GWord firstWord; GWord lastWord; CharAttr firstAttr = _attrs[0]; if (firstAttr.Decoration == null) firstAttr.Decoration = TextDecoration.Default; firstWord = lastWord = new GWord(firstAttr.Decoration, 0, firstAttr.CharGroup); int limit = _text.Length; int offset; if (_text[0] == '\0') { offset = 0; } else { CharAttr prevAttr = firstAttr; for (offset = 1; offset < limit; offset++) { char ch = _text[offset]; if (ch == '\0') break; else if (ch == GLine.WIDECHAR_PAD) continue; CharAttr attr = _attrs[offset]; if (attr.Decoration != prevAttr.Decoration || attr.CharGroup != prevAttr.CharGroup) { if (attr.Decoration == null) attr.Decoration = TextDecoration.Default; GWord w = new GWord(attr.Decoration, offset, attr.CharGroup); lastWord.Next = w; lastWord = w; prevAttr = attr; } } } GLine line = new GLine((char[])_text.Clone(), offset, firstWord); line.EOLType = _eolType; return line; }
//TODO �ȉ��Q���\�b�h��ID�����e�i���X��ʓr�s�����Ƃ�O��ɂ��Ă���B protected 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++; _invalidatedRegion.InvalidatedAll = true; }
//TODO �h�L�������g���ł����Ȃ�Ƃ���ł͒x���Ȃ肻�� protected 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); l = hintLine; break; } } } else { for (int i = h; i > index; i--) { l = l.PrevLine; if (l == null) { FindLineByHintFailed(index, hintLine); l = hintLine; break; } } } return l; }
//�����ɒlj� public virtual void AddLine(GLine line) { if (_firstLine == null) { //���� _firstLine = line; _lastLine = line; _size = 1; line.ID = 0; _invalidatedRegion.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++; _invalidatedRegion.InvalidateLine(lastID + 1); } }
public void ReplaceCurrentLine(GLine line) { #if DEBUG Replace(_currentLine, line); #else if (_currentLine != null) //クラッシュレポートをみると、何かの拍子にnullになっていたとしか思えない Replace(_currentLine, line); #endif }
public void RemoveAfter(int from) { GLine delete = FindLineOrNullClipTop(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; } } _invalidatedRegion.InvalidatedAll = true; }
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(_width); 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; _invalidatedRegion.InvalidatedAll = true; }
public void ReplaceCurrentLine(GLine line) { #if DEBUG Replace(_currentLine, line); #else if (_currentLine != null) //�N���b�V�����|�[�g��݂�ƁA�����̔��q��null�ɂȂ��Ă����Ƃ����v���Ȃ� Replace(_currentLine, line); #endif }
//�Đڑ��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.DisplayLength == 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"); } }
public void SetFirstLine(int id) { _firstLine = FindLineOrEdge(id); }
private void AppendTrim(StringBuilder bld, GLine line, int pos, int length) { Debug.Assert(pos >= 0); if (line.IsRightSideOfZenkaku(pos)) { //���{�ꕶ���̉E�[����̂Ƃ��͊g�傷�� pos--; length++; } line.WriteTo( delegate(char[] buff, int len) { bld.Append(buff, 0, len); }, pos, length); }
public bool StartSelection(GLine line, int position, RangeType type, int x, int y) { Debug.Assert(position >= 0); //���{�ꕶ���̉E������̑I��͍����ɏC�� line.ExpandBuffer(position + 1); if (line.IsRightSideOfZenkaku(position)) position--; //_disabledTemporary = false; _pivotType = type; _forwardPivot.Line = line.ID; _backwardPivot.Line = line.ID; _forwardDestination.Line = line.ID; _forwardDestination.Column = position; _backwardDestination.Line = line.ID; _backwardDestination.Column = position; switch (type) { case RangeType.Char: _forwardPivot.Column = position; _backwardPivot.Column = position; break; case RangeType.Word: _forwardPivot.Column = line.FindPrevWordBreak(position) + 1; _backwardPivot.Column = line.FindNextWordBreak(position); break; case RangeType.Line: _forwardPivot.Column = 0; _backwardPivot.Column = line.DisplayLength; break; } _state = SelectionState.Pivot; _startX = x; _startY = y; FireSelectionStarted(); return true; }
public 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.Column = position; _backwardDestination.Column = position; break; case RangeType.Word: _forwardDestination.Column = line.FindPrevWordBreak(position) + 1; _backwardDestination.Column = line.FindNextWordBreak(position); break; case RangeType.Line: _forwardDestination.Column = 0; _backwardDestination.Column = line.DisplayLength; break; } return true; }
public void StartCommand(AbstractTerminal terminal, string command_text, GLine prompt_line) { }
/// 最後のremain行以前を削除する public 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; //新しい先頭を決める _firstLine = newfirst; newfirst.PrevLine.NextLine = null; newfirst.PrevLine = null; _size -= delete_count; Debug.Assert(_size == remain); if (_topLine.ID < _firstLine.ID) _topLine = _firstLine; if (_currentLine.ID < _firstLine.ID) { _currentLine = _firstLine; _caretColumn = 0; } return delete_count; }
public void StartCommand(AbstractTerminal terminal, string command_text, GLine prompt_line) { _executingCommand = command_text; _terminal = terminal; }
//再接続用に現在ドキュメントの前に挿入 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.DisplayLength == 0) { flag = true; GLine nl = c.Clone(); nl.ID = _firstLine.ID - 1; InsertBefore(_firstLine, nl); //最初に空でない行があれば以降は全部挿入 offset++; } c = c.PrevLine; } //IDが負になるのはちょっと怖いので修正 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"); } }
public void OnPromptLine(GLine line, string prompt, string command) { _lastPromptLine = line; _lastCommand = command; Debug.WriteLineIf(DebugOpt.CommandPopup, "OnPromptLine " + _state.ToString() + ";" + command); if (_currentProcessor != null && _state == State.Fetch && command.Trim().Length == 0) { ProcessCommandResult(line.ID - 1); _state = State.Prompt; } else if (_state != State.Fetch) _state = State.Prompt; }
/// �����Ɠ�����e�ŏ���������Bline�̓�e�͔j��Ȃ��B /// ������null�̂Ƃ��͈����Ȃ��̃R���X�g���N�^�Ɠ������ʂɂȂ�B /// <summary> /// <ja> /// �����Ɠ�����e�ŏ��������܂��B /// </ja> /// <en> /// Initialize same as argument. /// </en> /// </summary> /// <param name="cc"> /// <ja> /// �ݒ肷��L�����b�g�ʒu /// </ja> /// <en> /// The caret position to set. /// </en> /// </param> /// <param name="line"> /// <ja>�R�s�[���ƂȂ�GLine�I�u�W�F�N�g</ja> /// <en>GLine object that becomes copy origin</en> /// </param> /// <remarks> /// <ja> /// <paramref name="line"/>��null�̂Ƃ��ɂ́A�����Ȃ��̃R���X�g���N�^�Ɠ������ʂɂȂ�܂��B /// </ja> /// <en> /// The same results with the constructor who doesn't have the argument when <paramref name="line"/> is null. /// </en> /// </remarks> 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; _text = line.DuplicateBuffer(_text); int n = 0; while (w != null) { int nextoffset = line.GetNextOffset(w); while (n < nextoffset) { _attrs[n++] = new CharAttr(w.Decoration, w.CharGroup); } w = w.Next; } _eolType = line.EOLType; ExpandBuffer(cc + 1); this.CaretColumn = cc; //' '�Ŗ��߂邱�Ƃ����̂Ńv���p�e�B�Z�b�g��g�� }
internal void ScrollUp(int from, int to) { GLine top = FindLineOrEdge(from); GLine bottom = FindLineOrEdge(to); if (top == null || bottom == null) return; //エラーハンドリングはFindLineの中で。ここではクラッシュ回避だけを行う 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(_width); 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; } */ //!!次の2行はxtermをやっている間に発見して修正。 VT100では何かの必要があってこうなったはずなので後で調べること //if(_scrollingTop<=_topLine.ID && _topLine.ID<=_scrollingBottom) // _topLine = _currentLine; while (topline_id < _topLine.ID) _topLine = _topLine.PrevLine; _invalidatedRegion.InvalidatedAll = true; }
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の調整は必要ならここで行われる _currentLine = new GLine(_width); InsertAfter(bottom, _currentLine); //id maintainance GLine c = newtop; GLine end = _currentLine.NextLine; while (c != end) { c.ID = top_id++; c = c.NextLine; } } _invalidatedRegion.InvalidatedAll = true; }
//FindLineByHint�͂����Ύ��s����̂Ńf�o�b�O�p�Ɍ��ݏ�Ԃ�_���v protected void FindLineByHintFailed(int index, GLine hintLine) { #if DEBUG Debug.WriteLine(String.Format("FindLine {0}, hint_id={1}", index, hintLine.ID)); Debugger.Break(); #endif }
public 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; _invalidatedRegion.InvalidateLine(newline.ID); }
public virtual void AssertValid(GLine line, int count) { GLine next = line.NextLine; while (next != null) { Debug.Assert(line.ID + 1 == next.ID); Debug.Assert(line == next.PrevLine); line = next; next = next.NextLine; } }
//末尾に追加する public override void AddLine(GLine line) { base.AddLine(line); if (_size == 1) { _currentLine = line; _topLine = line; } }
public GLine Clone() { GLine nl = new GLine((char[])_text.Clone(), _displayLength, _firstWord.DeepClone()); nl._eolType = _eolType; nl._id = _id; return nl; }
public 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--; _invalidatedRegion.InvalidatedAll = true; }
/// 引数と同じ内容で初期化する。lineの内容は破壊されない。 /// 引数がnullのときは引数なしのコンストラクタと同じ結果になる。 /// <summary> /// <ja> /// 引数と同じ内容で初期化します。 /// </ja> /// <en> /// Initialize same as argument. /// </en> /// </summary> /// <param name="cc"> /// <ja> /// 設定するキャレット位置 /// </ja> /// <en> /// The caret position to set. /// </en> /// </param> /// <param name="line"> /// <ja>コピー元となるGLineオブジェクト</ja> /// <en>GLine object that becomes copy origin</en> /// </param> /// <remarks> /// <ja> /// <paramref name="line"/>がnullのときには、引数なしのコンストラクタと同じ結果になります。 /// </ja> /// <en> /// The same results with the constructor who doesn't have the argument when <paramref name="line"/> is null. /// </en> /// </remarks> public void Load(GLine line, int cc) { if (line == null) { //これがnullになっているとしか思えないクラッシュレポートがあった。本来はないはずなんだが... Clear(80); return; } Clear(line.Length); GWord w = line.FirstWord; _text = line.DuplicateBuffer(_text); int n = 0; while (w != null) { int nextoffset = line.GetNextOffset(w); while (n < nextoffset) { _attrs[n++] = new CharAttr(w.Decoration, w.CharGroup); } w = w.Next; } _eolType = line.EOLType; ExpandBuffer(cc + 1); this.CaretColumn = cc; //' 'で埋めることもあるのでプロパティセットを使う }
/// <summary> /// Clone this instance that text attributes in the specified range are inverted. /// </summary> /// <param name="from">start column index of the range. (inclusive)</param> /// <param name="to">end column index of the range. (exclusive)</param> /// <returns>new instance</returns> internal GLine CreateInvertedClone(int from, int to) { ExpandBuffer(Math.Max(from + 1, to)); //激しくリサイズしたときなどにこの条件が満たせないことがある Debug.Assert(from >= 0 && from < _text.Length); if (from < _text.Length && _text[from] == WIDECHAR_PAD) { from--; } if (to < _text.Length && _text[to] == WIDECHAR_PAD) { to++; } const int PHASE_LEFT = 0; const int PHASE_MIDDLE = 1; const int PHASE_RIGHT = 2; int phase = PHASE_LEFT; int inverseIndex = from; GWord first = null; GWord last = null; for (GWord word = _firstWord; word != null; word = word.Next) { TextDecoration originalDecoration = word.Decoration; if (originalDecoration == null) { originalDecoration = TextDecoration.Default; } int wordStart = word.Offset; int wordEnd = GetNextOffset(word); do { GWord newWord; if (phase == PHASE_RIGHT || inverseIndex < wordStart || wordEnd <= inverseIndex) { TextDecoration newDec = (phase == PHASE_MIDDLE) ? originalDecoration.GetInvertedCopy() : originalDecoration; newWord = new GWord(newDec, wordStart, word.CharGroup); wordStart = wordEnd; } else { TextDecoration leftDec = (phase == PHASE_LEFT) ? originalDecoration : originalDecoration.GetInvertedCopy(); if (wordStart < inverseIndex) { newWord = new GWord(leftDec, wordStart, word.CharGroup); } else { newWord = null; } wordStart = inverseIndex; // update phase if (phase == PHASE_LEFT) { phase = PHASE_MIDDLE; inverseIndex = to; } else if (phase == PHASE_MIDDLE) { phase = PHASE_RIGHT; } } // append new GWord to the list. if (newWord != null) { if (last == null) { first = newWord; } else { last.Next = newWord; } last = newWord; } } while (wordStart < wordEnd); } GLine ret = new GLine((char[])_text.Clone(), _displayLength, first); ret.ID = _id; ret.EOLType = _eolType; return(ret); }