summaryrefslogtreecommitdiff
path: root/src/hed/edit.cc
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
committerHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
commit5df79c53745fde5d6c3340a2979b1429cd5892c1 (patch)
tree1a81af141708b826e9c61e8a04019994fcca8298 /src/hed/edit.cc
Initial import of htcd system 1.0
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/hed/edit.cc')
-rw-r--r--src/hed/edit.cc262
1 files changed, 262 insertions, 0 deletions
diff --git a/src/hed/edit.cc b/src/hed/edit.cc
new file mode 100644
index 0000000..b38b1e9
--- /dev/null
+++ b/src/hed/edit.cc
@@ -0,0 +1,262 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <hed/edit.h>
21#include <hed/input.h>
22#include <string.h>
23#include <malloc.h>
24
25const mstring end_tag="~";
26
27Editor::Line::Line()
28{
29 line=(char*)malloc(MAXCOLS);
30 line[0]=0;
31 dim=1;
32}
33Editor::Line::Line(char* p,int s)
34{
35 line=(char*)malloc(MAXCOLS);
36 memcpy(line,p,s);
37 dim=s;
38}
39Editor::Line::~Line()
40{
41 delete line;
42}
43int Editor::Line::Insert(int pos,char c)
44{
45 if(pos>=dim) pos=dim-1;
46 if(dim<MAXCOLS) {
47 memmove(line+pos+1,line+pos,dim-pos);
48 line[pos]=c;
49 dim++;
50 return 1;
51 }
52 else return 0;
53}
54int Editor::Line::Append(const Line* p)
55{
56 if(dim-1+p->dim<=MAXCOLS) {
57 memcpy(line+dim-1,p->line,p->dim);
58 dim+=p->dim-1;
59 return 1;
60 }
61 else return 0;
62}
63Editor::Line* Editor::Line::Break(int pos)
64{
65 if(pos>=dim) pos=dim-1;
66 Line* p=new Line(line+pos,dim-pos);
67 line[pos]=0;
68 dim=pos+1;
69 return p;
70}
71void Editor::Line::Delete(int pos)
72{
73 if(dim-1>pos) {
74 memmove(line+pos,line+pos+1,dim-pos-1);
75 dim--;
76 }
77}
78
79/////////////////////////////////////////////////////////////////////////
80
81Editor::Editor(const mstring& s,int ex) :
82 path(s),
83 from(0),lines(Lines()),atline(0),size(0),
84 tab(0),cols(Columns()),atcol(0),exclusive(ex)
85{
86 memset(map,0,sizeof(Line*)*MAXLINES);
87 map[0]=new Line();
88 size=1;
89 caption=path;
90 caption+=sref(" ok (ESC to go back)");
91 if(!exclusive) caption+=sref(" (readonly)");
92}
93Editor::~Editor()
94{
95 for(int i=0;i<size;i++) delete map[i];
96}
97
98void Editor::Show()
99{
100 ClearScreen();
101 for(int i=from;i<from+lines&&i<size;i++) {
102 if(tab<map[i]->dim) {
103 if(i==size-1) {
104 if(tab<map[i]->dim-1)
105 OutputField(i-from,0,cols,sref(map[i]->line+tab,map[i]->dim-tab-1));
106 OutputField(i-from,map[i]->dim-tab-1,1,end_tag);
107 }
108 else {
109 OutputField(i-from,0,cols,sref(map[i]->line+tab,map[i]->dim-tab));
110 }
111 }
112 }
113 Reverse(1);
114 OutputField(lines,0,cols,caption);
115 Reverse(0);
116 MoveCursor(atline-from,atcol-tab);
117 Refresh();
118}
119
120void Editor::Move(int i,int j)
121{
122 atline+=i;
123 atcol+=j;
124 if(atline<0) atline=0; else if(atline>=size) atline=size-1;
125 if(atline<from) from=atline; else if(atline>=from+lines) from=atline+1-lines;
126 if(atcol<0) atcol=0; else if(atcol>=map[atline]->dim) atcol=map[atline]->dim-1;
127 if(atcol<tab) tab=atcol; else if(atcol>=tab+cols) tab=atcol+1-cols;
128}
129
130void Editor::Home()
131{
132 atline=from=atcol=tab=0;
133}
134
135void Editor::Navigate()
136{
137 int c;
138 while(1) {
139 Show();
140 switch(c=Input()) {
141 case KK_UP:
142 case 16:
143 Move(-1,0);
144 break;
145 case KK_DOWN:
146 case 14:
147 Move(1,0);
148 break;
149 case KK_LEFT:
150 case 2:
151 Move(0,-1); break;
152 case KK_RIGHT:
153 case 6:
154 Move(0,1);
155 break;
156 case KK_NPAGE:
157 Move(lines/2,0);
158 break;
159 case KK_PPAGE:
160 Move(-lines/2,0);
161 break;
162 case KK_HOME:
163 case 1:
164 Move(0,-map[atline]->dim);
165 break;
166 case KK_END:
167 case 5:
168 Move(0,map[atline]->dim);
169 break;
170 case 127:
171 case 4:
172 if(exclusive) Delete();
173 break;
174 case 8:
175 if(exclusive) Backspace();
176 break;
177 case 13:
178 if(exclusive) BreakLine();
179 break;
180 case KK_F(1):
181 if(exclusive) Insert('å');
182 break;
183 case KK_F(2):
184 if(exclusive) Insert('ä');
185 break;
186 case KK_F(3):
187 if(exclusive) Insert('ö');
188 break;
189 case 9:
190 if(exclusive) Insert('\t');
191 break;
192 default:
193 if(exclusive) if(c>=32&&c<127) Insert(c);
194 break;
195 case 27:
196 return;
197 }
198 }
199}
200
201void Editor::Insert(int c)
202{
203 if(map[atline]->Insert(atcol,c)) Move(0,1);
204}
205
206void Editor::BreakLine()
207{
208 if(size<MAXLINES) {
209 Line* p=map[atline]->Break(atcol);
210 memmove(map+atline+2,map+atline+1,sizeof(Line*)*(size-atline-1));
211 map[atline+1]=p;
212 size++;
213 Move(1,-atcol);
214 }
215}
216
217void Editor::Delete()
218{
219 if(map[atline]->dim-1>atcol) {
220 map[atline]->Delete(atcol);
221 }
222 else if(size-1>atline) {
223 delete map[atline];
224 memmove(map+atline,map+atline+1,sizeof(Line*)*(size-atline-1));
225 size--;
226 }
227}
228
229void Editor::Backspace()
230{
231 if(atcol>0) {
232 Move(0,-1);
233 map[atline]->Delete(atcol);
234 }
235 else if(atline>0) {
236 int pos=map[atline-1]->dim-1;
237 if(map[atline-1]->Append(map[atline])) {
238 delete map[atline];
239 memmove(map+atline,map+atline+1,sizeof(Line*)*(size-atline-1));
240 size--;
241 Move(-1,pos-atcol);
242 }
243 }
244}
245
246void Editor::Paste(const mstring& s)
247{
248 for(int i=0;i<s.size();i++) {
249 if(s[i]=='\n') BreakLine();
250 else if(s[i]!='\r') Insert(s[i]);
251 }
252 Home();
253}
254
255void Editor::Copy(mstring& s)
256{
257 s.clear();
258 for(int i=0;i<size;i++) {
259 s+=sref(map[i]->line,map[i]->dim-1);
260 if(i<size-1) s+='\n';
261 }
262}