summaryrefslogtreecommitdiff
path: root/src/hed
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
Initial import of htcd system 1.0
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/hed')
-rw-r--r--src/hed/edit.cc262
-rw-r--r--src/hed/edit.h61
-rw-r--r--src/hed/hed.cc56
-rw-r--r--src/hed/input.cc107
-rw-r--r--src/hed/input.h52
-rw-r--r--src/hed/tables.cc442
-rw-r--r--src/hed/tables.h61
-rw-r--r--src/hed/test.cc33
8 files changed, 1074 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}
diff --git a/src/hed/edit.h b/src/hed/edit.h
new file mode 100644
index 0000000..e6ae437
--- /dev/null
+++ b/src/hed/edit.h
@@ -0,0 +1,61 @@
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#ifndef EDITH
21#define EDITH
22
23#include <mt/mstring.h>
24
25struct Editor {
26 static const int MAXLINES=1024;
27 static const int MAXCOLS=256;
28 struct Line {
29 Line();
30 Line(char* p,int s);
31 ~Line();
32 int Insert(int pos,char c);
33 int Append(const Line* p);
34 Line* Break(int pos);
35 void Delete(int pos);
36 char* line;
37 int dim;
38 };
39
40 Editor(const mstring& path,int ex);
41 ~Editor();
42
43 void Copy(mstring& s);
44 void Paste(const mstring& s);
45
46 void Show();
47 void Home();
48 void Move(int i,int j);
49 void Navigate();
50 void Insert(int c);
51 void BreakLine();
52 void Delete();
53 void Backspace();
54
55 mstring path,caption;
56 Line* map[MAXLINES];
57 int from,lines,atline,size;
58 int tab,cols,atcol,exclusive;
59};
60
61#endif
diff --git a/src/hed/hed.cc b/src/hed/hed.cc
new file mode 100644
index 0000000..dc469cc
--- /dev/null
+++ b/src/hed/hed.cc
@@ -0,0 +1,56 @@
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 "tables.h"
21#include "input.h"
22#include <unistd.h>
23
24static fp_stream merr(stderr);
25
26main(int argc,char* argv[])
27{
28 if(argc<2) {
29 merr<<"Usage: "<<argv[0]<<" <hdb> [exclusive]\n";
30 return -1;
31 }
32 char* path=argv[1];
33 int excl=argc>2?atoi(argv[2]):0;
34 mstring err;
35 sleep(1);
36 InitCurses();
37 Tables tab;
38 try {
39 tab.Open(path,excl);
40 tab.Setup(20);
41 tab.Navigate();
42 }
43 catch(const merror_t& e) {
44 err=e.desc;
45 }
46 catch(...) {
47 err="hdb: Unexpected error";
48 }
49 tab.Close();
50 EndCurses();
51 if(err.nempty()) {
52 merr<<err<<"\n";
53 sleep(2);
54 }
55 return 0;
56}
diff --git a/src/hed/input.cc b/src/hed/input.cc
new file mode 100644
index 0000000..4f2b008
--- /dev/null
+++ b/src/hed/input.cc
@@ -0,0 +1,107 @@
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/input.h>
21#include <mt/mstring.h>
22#include <unistd.h>
23#include <poll.h>
24#include <curses.h>
25
26int Lines() { return LINES-1; }
27int Columns() { return COLS-1; }
28
29void ClearScreen() { erase(); }
30void MoveCursor(int i,int j) { move(i,j); }
31
32void InitCurses()
33{
34 initscr();
35 nodelay(stdscr,1);
36 raw();
37 noecho();
38 nonl();
39 keypad(stdscr,1);
40 intrflush(stdscr,FALSE);
41}
42
43void EndCurses()
44{
45 endwin();
46}
47
48void OutputField(int row,int col,int field,const sref& in)
49{
50 mstring tmp=in.left_first_of(cset_newl);
51 int cut=tmp.size()!=in.size();
52 if(tmp.size()<field) tmp.append(field-tmp.size(),' ');
53 if(cut||in.size()>field) { tmp.resize(field-1); tmp.append(1,'\\'); }
54 mvaddstr(row,col,(char*)tmp.c_str());
55}
56
57void Reverse(int n)
58{
59 if(n) attron(A_REVERSE); else attroff(A_REVERSE);
60}
61void Bold(int n)
62{
63 if(n) attron(A_BOLD); else attroff(A_BOLD);
64}
65
66void Refresh()
67{
68 refresh();
69}
70
71int RawInput() {
72 int c=getch();
73 if(c>0) return c;
74 struct pollfd ps={fileno(stdin),POLLIN,0};
75 poll(&ps,1,1000);
76 return getch();
77}
78
79int Input() {
80 int c=RawInput();
81#if 0
82 if(c==27) {
83 napms(1);
84 int c2=getch();
85 if(c2!=-1) {
86 switch(c2) {
87 default: return 0;
88 case 91:
89 switch(RawInput()) {
90 default: return 0;
91 case '2':
92 RawInput();
93 switch(RawInput()) {
94 default: return 0;
95 case 52: return RawInput()==122?KEY_HOME:0;
96 case 54: return RawInput()==122?KEY_PPAGE:0;
97 case 48: return RawInput()==122?KEY_END:0;
98 case 50: return RawInput()==122?KEY_NPAGE:0;
99 }
100 }
101 }
102 }
103 }
104#endif
105 return c;
106}
107
diff --git a/src/hed/input.h b/src/hed/input.h
new file mode 100644
index 0000000..76071ce
--- /dev/null
+++ b/src/hed/input.h
@@ -0,0 +1,52 @@
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 <mt/stringref.h>
21
22#ifndef INPUTH
23#define INPUTH
24
25#define KK_DOWN 0402
26#define KK_UP 0403
27#define KK_LEFT 0404
28#define KK_RIGHT 0405
29#define KK_HOME 0406
30#define KK_F0 0410
31#define KK_F(n) (KK_F0+(n))
32#define KK_NPAGE 0522
33#define KK_PPAGE 0523
34#define KK_END 0550
35
36int Input();
37int RawInput();
38
39int Lines();
40int Columns();
41
42void ClearScreen();
43void MoveCursor(int i,int j);
44void OutputField(int row,int col,int field,const sref& p);
45void Reverse(int n);
46void Bold(int n);
47void Refresh();
48
49void InitCurses();
50void EndCurses();
51
52#endif
diff --git a/src/hed/tables.cc b/src/hed/tables.cc
new file mode 100644
index 0000000..c489e6f
--- /dev/null
+++ b/src/hed/tables.cc
@@ -0,0 +1,442 @@
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 "tables.h"
21#include "input.h"
22#include <string.h>
23#include <malloc.h>
24#include <stdio.h>
25
26const mstring star_tag="*";
27
28const int PAD=2;
29const mstring HELP=
30"Commands from record page:\n"
31"\n"
32"DEL - Delete record\n"
33"RET - Edit record\n"
34"n - New record\n"
35"s - Sort by table\n"
36"o - Order by table\n"
37"c - Check for duplicates\n"
38"f - Filename for map\n"
39"r - Remove table\n"
40"a - Add table\n";
41
42Tables::Tables() :
43 from(0),lines(Lines()-1),atline(0),writable(0),
44 tab(0),space(10),cols(Columns()),atcol(0),
45 lastfrom(-1),lasttab(-1),lastline(0),lastcol(0)
46{
47 dispcols=cols/space;
48}
49
50Tables::~Tables()
51{
52}
53
54void Tables::Setup(int sp)
55{
56 space=sp;
57 dispcols=cols/space;
58 Home();
59}
60
61void Tables::Show()
62{
63 if(db.remap()) {
64 lastfrom=-1;
65 caption.convert("%d, %d, %d, %d",
66 db.head()->filesize.get(),
67 db.head()->fatal.get(),
68 db.head()->major.get(),
69 db.head()->minor.get());
70 }
71 if(from!=lastfrom||tab!=lasttab) {
72 ClearScreen();
73 Bold(1);
74 for(int j=tab;j<tab+dispcols&&j<db.Tables();j++) {
75 if(j==db.Index()) {
76 OutputField(0,space*(j-tab),space-PAD-1,db.Table(j));
77 OutputField(0,space*(j-tab)+space-PAD-1,1,star_tag);
78 }
79 else {
80 OutputField(0,space*(j-tab),space-PAD,db.Table(j));
81 }
82 }
83 Bold(0);
84 for(int i=from;i<from+lines&&i<=db.size();i++) {
85 for(int j=tab;j<tab+dispcols&&j<=db.Tables();j++) {
86 sref tmp; if(i<db.size()&&j<db.Tables()) tmp=db(i,j);
87 if(i==atline&&j==atcol) Reverse(1); else Reverse(0);
88 OutputField(i+1-from,space*(j-tab),space-PAD,tmp);
89 if(i==atline&&j==atcol) Reverse(0);
90 }
91 }
92 Reverse(1);
93 OutputField(lines+1,1,cols-1,caption);
94 Reverse(0);
95 }
96 else {
97 int i=lastline,j=lastcol;
98 if(i>=0&&i<=db.size()&&j>=0&&j<=db.Tables()) {
99 sref tmp; if(i<db.size()&&j<db.Tables()) tmp=db(i,j);
100 OutputField(i+1-from,space*(j-tab),space-PAD,tmp);
101 }
102 i=atline; j=atcol;
103 if(i>=0&&i<=db.size()&&j>=0&&j<=db.Tables()) {
104 sref tmp; if(i<db.size()&&j<db.Tables()) tmp=db(i,j);
105 Reverse(1);
106 OutputField(i+1-from,space*(j-tab),space-PAD,tmp);
107 Reverse(0);
108 }
109 }
110 MoveCursor(lines+1,0);
111 Refresh();
112 lastline=atline;
113 lastcol=atcol;
114 lastfrom=from;
115 lasttab=tab;
116}
117
118void Tables::Home()
119{
120 atline=atcol=from=tab=0;
121}
122
123void Tables::Move(int i,int j)
124{
125 atline+=i;
126 if(atline>=db.size()) atline=db.size();
127 if(atline<0) atline=0;
128 if(atline>=from+lines) from=atline+1-lines;
129 if(atline<from) from=atline;
130 atcol+=j;
131 if(atcol>=db.Tables()) atcol=db.Tables();
132 if(atcol<0) atcol=0;
133 if(atcol>=tab+dispcols) tab=atcol+1-dispcols;
134 if(atcol<tab) tab=atcol;
135}
136
137void Tables::Insert()
138{
139 if(db.remap()) lastfrom=-1;
140 if(db.Tables()==0) return;
141 mstring tx,key,ttab=db.Table(db.Index());
142 tx.convert("%s - insert %s",path.c_str(),ttab.c_str());
143 Editor edit(tx,1);
144 edit.Paste("");
145 edit.Navigate();
146 edit.Copy(key);
147 int row=-1;
148 try {
149 spile list(db.Tables());
150 list[db.Index()]=key;
151 row=db.Insert(list,1);
152 if(row>=0) {
153 caption.convert("%s - added record",path.c_str());
154 Move(row-atline,0);
155 }
156 else {
157 caption.convert("%s - record nonunique - not added",path.c_str());
158 Move(0,0);
159 }
160 }
161 catch(const merror_t& e) {
162 caption=e.desc;
163 Move(0,0);
164 }
165 lastfrom=-1;
166}
167
168void Tables::Delete()
169{
170 if(db.remap()) lastfrom=-1;
171 if(atline<db.size()) {
172 db.Rem(atline);
173 Move(0,0);
174 lastfrom=-1;
175 }
176}
177
178void Tables::Navigate()
179{
180 int c;
181 while(1) {
182 Show();
183 switch(c=Input()) {
184 case KK_UP:
185 case 16:
186 Move(-1,0);
187 break;
188 case KK_DOWN:
189 case 14:
190 Move(1,0);
191 break;
192 case KK_LEFT:
193 case 2:
194 Move(0,-1); break;
195 case KK_RIGHT:
196 case 6:
197 case 9:
198 Move(0,1);
199 break;
200 case KK_NPAGE:
201 Move(lines/2,0);
202 break;
203 case KK_PPAGE:
204 Move(-lines/2,0);
205 break;
206 case KK_HOME:
207 case 1:
208 Move(0,-db.Tables());
209 break;
210 case KK_END:
211 case 5:
212 Move(0,db.Tables());
213 break;
214 case 127:
215 case 4:
216 if(writable) Delete();
217 break;
218 case 13:
219 Edit();
220 break;
221 case 's':
222 Sort();
223 break;
224 case 'o':
225 if(writable) Order();
226 break;
227 case 'c':
228 Check();
229 break;
230 case 'f':
231 FileName();
232 break;
233 case 'r':
234 if(writable) RemTable();
235 break;
236 case 'a':
237 if(writable) AddTable();
238 break;
239 case 'n':
240 if(writable) Insert();
241 break;
242 case 27:
243 if(Command()) break;
244 else return;
245 }
246
247 }
248}
249
250int Tables::Command()
251{
252 mstring tmp=caption;
253 caption="q (quit), s (save), h (help)";
254 lastfrom=-1;
255 Show();
256 switch(Input()) {
257 case 'q':
258 return 0;
259 case 's':
260 Save();
261 break;
262 case 'h':
263 Help();
264 break;
265 default:
266 caption=tmp;
267 break;
268 }
269 lastfrom=-1;
270 return 1;
271}
272
273void Tables::Help()
274{
275 Editor edit("help",0);
276 edit.Paste(HELP);
277 edit.Navigate();
278 lastfrom=-1;
279}
280
281void Tables::Edit()
282{
283 if(db.remap()) lastfrom=-1;
284 if(atline<db.size()&&atcol<db.Tables()) {
285 mstring tx;
286 tx.convert("%s - (%d,%d)",path.c_str(),atline+1,atcol+1);
287 Editor edit(tx,writable&&atcol!=db.Index());
288 edit.Paste(db(atline,atcol));
289 edit.Navigate();
290 edit.Copy(tx);
291 try {
292 if(writable) db.Set(atline,atcol,tx);
293 caption=path;
294 caption+=sref(" edited.");
295 }
296 catch(const merror_t& e) {
297 caption=e.desc;
298 }
299 catch(...) {
300 }
301 Move(0,0);
302 lastfrom=-1;
303 }
304}
305
306void Tables::Sort()
307{
308 if(db.remap()) lastfrom=-1;
309 if(atline<=db.size()&&atcol<db.Tables()) {
310 mstring tx=db.Compname();
311 Editor edit("compname",1);
312 edit.Paste(tx);
313 edit.Navigate();
314 edit.Copy(tx);
315 db.Sort(db.Table(atcol),tx);
316 mstring ttab=db.Table(db.Index());
317 caption.convert("%s sorted: %s %s",path.c_str(),ttab.c_str(),tx.c_str());
318 Move(0,0);
319 lastfrom=-1;
320 }
321}
322
323void Tables::Order()
324{
325 if(db.remap()) lastfrom=-1;
326 if(atline<=db.size()&&atcol<db.Tables()) {
327 mstring tx=db.Compname();
328 Editor edit("compname",1);
329 edit.Paste(tx);
330 edit.Navigate();
331 edit.Copy(tx);
332 db.Order(db.Table(atcol),tx);
333 mstring ttab=db.Table(db.Index());
334 caption.convert("%s ordered: %s %s",path.c_str(),ttab.c_str(),tx.c_str());
335 Move(0,0);
336 lastfrom=-1;
337 }
338}
339
340void Tables::Check()
341{
342 if(db.remap()) lastfrom=-1;
343 int idx=db.Index();
344 mswrite mm;
345 for(int i=0;i<db.size()-1;i++) {
346 if(db(i,idx)==db(i+1,idx)) mm<<db(i,idx)<<" duplicated\n";
347 }
348 if(mm.str().empty()) mm<<"Nothing duplicated\n";
349 Editor edit("check",0);
350 edit.Paste(mm.str());
351 edit.Navigate();
352 lastfrom=-1;
353}
354
355void Tables::FileName()
356{
357 if(db.remap()) lastfrom=-1;
358 mstring tx; tx.convert("%s - filename",path.c_str());
359 Editor edit(tx,1);
360 tx.convert("%s",path.c_str());
361 edit.Paste(tx);
362 edit.Navigate();
363 edit.Copy(tx);
364 path=tx;
365 lastfrom=-1;
366}
367
368void Tables::AddTable()
369{
370 if(db.remap()) lastfrom=-1;
371 mstring tx;
372 tx.convert("%s - add table (def: 2nd line)",path.c_str());
373 Editor edit(tx,1);
374 edit.Paste("");
375 edit.Navigate();
376 mstring tb;
377 edit.Copy(tb);
378 sref first,rest=tb;
379 Splitln(first,rest);
380 mstring name=first;
381 Splitln(first,rest);
382 int ok=-db.Tables();
383 db.InsertTable(atcol,name);
384 ok+=db.Tables();
385 if(ok) {
386 Move(0,0);
387 caption.convert("%s - added table",path.c_str());
388 }
389 else caption.convert("%s - not unique - table not added",path.c_str());
390 lastfrom=-1;
391}
392
393void Tables::RemTable()
394{
395 if(db.remap()) lastfrom=-1;
396 if(atcol<db.Tables()&&atcol!=db.Index()) {
397 db.RemTable(atcol);
398 Move(0,0);
399 caption.convert("%s - removed table",path.c_str());
400 }
401 else caption.convert("%s - key table - not removed",path.c_str());
402 lastfrom=-1;
403}
404
405void Tables::Open(const mstring& s,int ex)
406{
407 path=s;
408 writable=ex;
409 db.Open(s,ex);
410 if(ex) db.Saveas(path+sref(".bak"));
411 caption=s;
412 caption+=sref(" loaded");
413 if(ex) caption+=sref(" (exclusive)");
414 lastfrom=-1;
415}
416
417void Tables::Save()
418{
419 try {
420 db.Saveas(path);
421 caption=path;
422 caption+=sref(" saved");
423 }
424 catch(const merror_t& e) {
425 caption=e.desc;
426 }
427 lastfrom=-1;
428}
429
430void Tables::Close()
431{
432 if(writable) {
433 db.Close();
434 caption=path;
435 caption+=sref(" closed");
436 }
437 else {
438 caption=path;
439 caption+=sref(" readonly - not closed");
440 }
441 lastfrom=-1;
442}
diff --git a/src/hed/tables.h b/src/hed/tables.h
new file mode 100644
index 0000000..205ca63
--- /dev/null
+++ b/src/hed/tables.h
@@ -0,0 +1,61 @@
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#ifndef TABLESH
21#define TABLESH
22
23#include <hed/edit.h>
24#include <hdb/db.h>
25
26struct Tables {
27 Tables();
28 ~Tables();
29
30 void Open(const mstring& path,int ex=0);
31 void Save();
32 void Close();
33
34 void Setup(int sp);
35
36 void Show();
37 void Home();
38 void Move(int i,int j);
39 void Navigate();
40 int Command();
41
42 void Sort();
43 void Order();
44 void Check();
45
46 void Edit();
47 void Insert();
48 void Delete();
49 void FileName();
50 void AddTable();
51 void RemTable();
52 void Help();
53
54 dbmap db;
55 mstring path,caption;
56 int from,lines,atline,writable;
57 int tab,space,cols,dispcols,dim,atcol;
58 int lastfrom,lasttab,lastline,lastcol;
59};
60
61#endif
diff --git a/src/hed/test.cc b/src/hed/test.cc
new file mode 100644
index 0000000..318334f
--- /dev/null
+++ b/src/hed/test.cc
@@ -0,0 +1,33 @@
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 "input.h"
21#include <stdio.h>
22
23main(int argc,char* argv[])
24{
25 InitCurses();
26 while(1) {
27 int c=RawInput();
28 fprintf(stderr,"%d\r\n",c);
29 if(c==27) break;
30 }
31 EndCurses();
32 return 0;
33}