OSDN Git Service

Selection~系列のプロパティをSelectionプロパティに統合した
[fooeditengine/FooEditEngine.git] / Common / UndoCommands.cs
1 /*
2  * Copyright (C) 2013 FooProject
3  * * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
5
6  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 
7  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8
9 You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
10  */
11 using System;
12 using System.Text;
13 using System.Text.RegularExpressions;
14 using Slusser.Collections.Generic;
15
16 namespace FooEditEngine
17 {
18     sealed class ReplaceCommand : ICommand
19     {
20         StringBuffer Buffer;
21         TextRange ReplacementRange, ReplacedRange;
22         GapBuffer<char> replacement, replaced;   //置き換え後の文字列、置き換え前の文字列
23
24         public ReplaceCommand(StringBuffer buf, int start, int length, string str)
25         {
26             this.Buffer = buf;
27             this.ReplacementRange = new TextRange(start,str.Length);
28             this.replacement = new GapBuffer<char>();
29             this.replacement.AddRange(Util.GetEnumrator(str),str.Length);
30             this.ReplacedRange = new TextRange(start,length);
31             this.replaced = new GapBuffer<char>();
32             this.replaced.AddRange(this.Buffer.GetEnumerator(start, length));
33         }
34
35         #region ICommand メンバー
36
37         public void undo()
38         {
39             this.Buffer.Replace(this.ReplacementRange.Index, this.replacement.Count,this.replaced,this.replaced.Count);
40         }
41
42         public void redo()
43         {
44             this.Buffer.Replace(this.ReplacedRange.Index, this.replaced.Count, this.replacement, this.replacement.Count);
45         }
46
47         public bool marge(ICommand a)
48         {
49             ReplaceCommand cmd = a as ReplaceCommand;
50             if (cmd == null)
51                 return false;
52             
53             if (this.ReplacedRange.Length == 0 &&
54                 cmd.ReplacementRange.Index >= this.ReplacementRange.Index &&
55                 cmd.ReplacementRange.Index + cmd.ReplacementRange.Length <= this.ReplacementRange.Index + this.ReplacementRange.Length)
56             {
57                 int bufferIndex = cmd.ReplacedRange.Index - this.ReplacementRange.Index;
58                 if(bufferIndex < this.replacement.Count)
59                     this.replacement.RemoveRange(bufferIndex, cmd.ReplacedRange.Length);
60                 this.replacement.InsertRange(bufferIndex, cmd.replacement, cmd.replacement.Count);
61                 return true;
62             }
63
64             if (this.ReplacedRange.Index + this.ReplacementRange.Length == cmd.ReplacedRange.Index && 
65                 this.ReplacedRange.Index == this.ReplacementRange.Index)
66             {
67                 this.replaced.AddRange(cmd.replaced,cmd.replaced.Count);
68                 this.replacement.AddRange(cmd.replacement,cmd.replacement.Count);
69                 this.ReplacedRange.Length += cmd.ReplacedRange.Length;
70                 this.ReplacementRange.Length += cmd.ReplacementRange.Length;
71                 return true;
72             }
73             return false;
74         }
75
76         public bool isempty()
77         {
78             return this.replaced.Count == 0 && this.replacement.Count == 0;
79         }
80         #endregion
81
82     }
83
84     sealed class ReplaceAllCommand : ICommand
85     {
86         StringBuffer buffer;
87         Regex regex;
88         StringBuffer oldBuffer;
89         string replacePattern;
90         bool groupReplace;
91         public ReplaceAllCommand(StringBuffer buffer, Regex regex, string replacePattern,bool groupReplace)
92         {
93             this.buffer = buffer;
94             this.regex = regex;
95             this.replacePattern = replacePattern;
96             this.groupReplace = groupReplace;
97         }
98
99         public void undo()
100         {
101             this.buffer.Replace(this.oldBuffer);
102         }
103
104         public void redo()
105         {
106             this.oldBuffer = new StringBuffer(this.buffer);
107
108             GapBuffer<char> result = new GapBuffer<char>();
109             foreach (string line in this.buffer.GetLines(0, this.buffer.Length - 1))
110             {
111                 string output = this.regex.Replace(line, (m) =>{
112                     if (this.groupReplace)
113                         return m.Result(this.replacePattern);
114                     else
115                         return this.replacePattern;
116                 });
117                 result.AddRange(Util.GetEnumrator(output),output.Length);
118             }
119
120             this.buffer.Replace(result);
121         }
122
123         public bool marge(ICommand a)
124         {
125             return false;
126         }
127
128         public bool isempty()
129         {
130             return false;
131         }
132     }
133     sealed class FastReplaceAllCommand : ICommand
134     {
135         StringBuffer buffer;
136         Regex regex;
137         StringBuffer oldBuffer;
138         string targetPattern;
139         string replacePattern;
140         bool caseInsensitve;
141         public FastReplaceAllCommand(StringBuffer buffer,string targetPattern, string replacePattern,bool ci)
142         {
143             this.buffer = buffer;
144             this.replacePattern = replacePattern;
145             this.targetPattern = targetPattern;
146             this.caseInsensitve = ci;
147         }
148
149         public void undo()
150         {
151             this.buffer.Replace(this.oldBuffer);
152         }
153
154         public void redo()
155         {
156             this.oldBuffer = new StringBuffer(this.buffer);
157             this.buffer.Replace(this.targetPattern, this.replacePattern,this.caseInsensitve);
158         }
159
160         public bool marge(ICommand a)
161         {
162             return false;
163         }
164
165         public bool isempty()
166         {
167             return false;
168         }
169     }
170 }