/// </summary>\r
public int insertLength;\r
/// <summary>\r
+ /// 更新イベントが発生した行。行が不明な場合や行をまたぐ場合はnullを指定すること。\r
+ /// </summary>\r
+ public int? row;\r
+ /// <summary>\r
/// コンストラクター\r
/// </summary>\r
/// <param name="type">更新タイプ</param>\r
/// <param name="startIndex">開始インデックス</param>\r
/// <param name="removeLength">削除された長さ</param>\r
/// <param name="insertLength">追加された長さ</param>\r
- public DocumentUpdateEventArgs(UpdateType type, int startIndex, int removeLength, int insertLength)\r
+ /// <param name="row">開始行。nullを指定することができる</param>\r
+ public DocumentUpdateEventArgs(UpdateType type, int startIndex, int removeLength, int insertLength, int? row = null)\r
{\r
this.type = type;\r
this.startIndex = startIndex;\r
this.removeLength = removeLength;\r
this.insertLength = insertLength;\r
+ this.row = row;\r
}\r
}\r
\r
this.buffer = new StringBuffer();\r
else\r
this.buffer = new StringBuffer(doc.buffer);\r
- this.buffer.Update += new DocumentUpdateEventHandler(buffer_Update);\r
+ this.buffer.Update = new DocumentUpdateEventHandler(buffer_Update);\r
this.UpdateCalledAlways += (s, e) => { };\r
this.Update += new DocumentUpdateEventHandler((s, e) => { });\r
this.ChangeFireUpdateEvent += new EventHandler((s, e) => { });\r
/// </remarks>\r
public void ReplaceAll2(string target, string pattern,bool ci = false)\r
{\r
- FastReplaceAllCommand cmd = new FastReplaceAllCommand(this.buffer, target, pattern,ci);\r
+ FastReplaceAllCommand cmd = new FastReplaceAllCommand(this.buffer, this.LayoutLines, target, pattern,ci);\r
this.UndoManager.push(cmd);\r
cmd.redo();\r
}\r
switch (e.type)\r
{\r
case UpdateType.Replace:\r
- this._LayoutLines.UpdateAsReplace(e.startIndex, e.removeLength, e.insertLength);\r
+ if (e.row == null)\r
+ this._LayoutLines.UpdateAsReplace(e.startIndex, e.removeLength, e.insertLength);\r
+ else\r
+ this._LayoutLines.UpdateLineAsReplace(e.row.Value, e.removeLength, e.insertLength);\r
break;\r
case UpdateType.Clear:\r
this._LayoutLines.Clear();\r
this._gapEnd -= count;
// Clear the contents of the gap
- Array.Clear(this._buffer, index, deltaCount);
+ //Array.Clear(this._buffer, index, deltaCount);
}
else
{
this._gapEnd += count;
// Clear the contents of the gap
- Array.Clear(this._buffer, deltaIndex, this._gapEnd - deltaIndex);
+ //Array.Clear(this._buffer, deltaIndex, this._gapEnd - deltaIndex);
}
}
return result;\r
}\r
\r
+ internal void UpdateLineAsReplace(int row,int removedLength, int insertedLength)\r
+ {\r
+ int deltaLength = insertedLength - removedLength;\r
+\r
+ this.Lines[row] = new LineToIndexTableData(this.GetLineHeadIndex(row), this.GetLengthFromLineNumber(row) + deltaLength, true, true, null);\r
+\r
+ //行テーブルを更新する\r
+ this.UpdateLineHeadIndex(deltaLength, row, 1);\r
+\r
+ this.FoldingCollection.UpdateData(this.Document, this.GetLineHeadIndex(row), insertedLength, removedLength);\r
+\r
+ this._IsSync = false;\r
+\r
+ this.lastUpdateTicks = DateTime.Now.Ticks;\r
+ }\r
+\r
internal void UpdateAsReplace(int index, int removedLength, int insertedLength)\r
{\r
#if DEBUG\r
int startRow, endRow;\r
GetRemoveRange(index, removedLength, out startRow, out endRow);\r
\r
+ int deltaLength = insertedLength - removedLength;\r
+\r
var result = GetAnalyzeLength(startRow, endRow, index, removedLength, insertedLength);\r
int HeadIndex = result.Item1;\r
int analyzeLength = result.Item2;\r
\r
//消すべき行が複数ある場合は消すが、そうでない場合は最適化のため長さを変えるだけにとどめておく\r
int removeCount = endRow - startRow + 1;\r
- int deltaLength = insertedLength - removedLength;\r
- if(removeCount == 1 && newLines.Count == 1)\r
+ if (removeCount == 1 && newLines.Count == 1)\r
{\r
this.Lines[startRow] = newLines.First();\r
}\r
\r
public StringBuffer()\r
{\r
- this.Update += (s, e) => { };\r
+ this.Update = (s, e) => { };\r
}\r
\r
public StringBuffer(StringBuffer buffer)\r
get { return this.buf.Count; }\r
}\r
\r
- internal event DocumentUpdateEventHandler Update;\r
+ internal DocumentUpdateEventHandler Update;\r
\r
internal void Replace(StringBuffer buf)\r
{\r
TextSearch ts = new TextSearch(target,ci);\r
int left = 0, right = 0;\r
char[] pattern_chars = pattern.ToCharArray();\r
- while((right = ts.IndexOf(this.buf,left)) != -1)\r
+ while((right = ts.IndexOf(this.buf,left,this.buf.Count)) != -1)\r
{\r
this.buf.RemoveRange(right, target.Length);\r
this.buf.InsertRange(right, pattern_chars, pattern.Length);\r
this.Update(this, new DocumentUpdateEventArgs(UpdateType.Replace, 0, 0, buf.Count));\r
}\r
\r
+ internal void ReplaceAll(LineToIndexTable layoutlines,string target, string pattern, bool ci = false)\r
+ {\r
+ TextSearch ts = new TextSearch(target, ci);\r
+ char[] pattern_chars = pattern.ToCharArray();\r
+ for(int i = 0; i < layoutlines.Count; i++)\r
+ {\r
+ int lineHeadIndex = layoutlines.GetIndexFromLineNumber(i), lineLength = layoutlines.GetLengthFromLineNumber(i);\r
+ int left = lineHeadIndex, right = lineHeadIndex;\r
+ int newLineLength = lineLength;\r
+ while ((right = ts.IndexOf(this.buf, left, lineHeadIndex + newLineLength)) != -1)\r
+ {\r
+ this.buf.RemoveRange(right, target.Length);\r
+ this.buf.InsertRange(right, pattern_chars, pattern.Length);\r
+ left = right + pattern.Length;\r
+ newLineLength += pattern.Length - target.Length;\r
+ }\r
+ this.Update(this, new DocumentUpdateEventArgs(UpdateType.Replace, lineHeadIndex, lineLength, newLineLength, i));\r
+ }\r
+ }\r
+\r
internal int IndexOf(string target, int start,bool ci = false)\r
{\r
TextSearch ts = new TextSearch(target,ci);\r
- return ts.IndexOf(this.buf, start);\r
+ return ts.IndexOf(this.buf, start,this.buf.Count);\r
}\r
\r
/// <summary>\r
this.qsTable[pattern[i]] = len - i;\r
}\r
}\r
- public int IndexOf(GapBuffer<char> buf, int start)\r
+ public int IndexOf(GapBuffer<char> buf, int start,int end)\r
{\r
//QuickSearch法\r
int buflen = buf.Count - 1;\r
int plen = this.patternLength;\r
int i = start;\r
- int end = buf.Count - plen;\r
+ int search_end = end - plen;\r
//最適化のためわざとコピペした\r
if (this.caseInsenstive)\r
{\r
- while (i <= end)\r
+ while (i <= search_end)\r
{\r
int j = 0;\r
while (j < plen)\r
}\r
else\r
{\r
- while (i <= end)\r
+ while (i <= search_end)\r
{\r
int j = 0;\r
while (j < plen)\r
string targetPattern;
string replacePattern;
bool caseInsensitve;
- public FastReplaceAllCommand(StringBuffer buffer,string targetPattern, string replacePattern,bool ci)
+ LineToIndexTable layoutLines;
+ public FastReplaceAllCommand(StringBuffer buffer,LineToIndexTable layoutlines,string targetPattern, string replacePattern,bool ci)
{
this.buffer = buffer;
this.replacePattern = replacePattern;
this.targetPattern = targetPattern;
this.caseInsensitve = ci;
+ this.layoutLines = layoutlines;
}
public void undo()
public void redo()
{
this.oldBuffer = new StringBuffer(this.buffer);
- this.buffer.Replace(this.targetPattern, this.replacePattern,this.caseInsensitve);
+ this.buffer.ReplaceAll(this.layoutLines, this.targetPattern, this.replacePattern,this.caseInsensitve);
}
public bool marge(ICommand a)