/************************************************************************* * * HTCd - Copyright (C) 1998-2006 Henrik Rydberg * * 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include const mstring end_tag="~"; Editor::Line::Line() { line=(char*)malloc(MAXCOLS); line[0]=0; dim=1; } Editor::Line::Line(char* p,int s) { line=(char*)malloc(MAXCOLS); memcpy(line,p,s); dim=s; } Editor::Line::~Line() { delete line; } int Editor::Line::Insert(int pos,char c) { if(pos>=dim) pos=dim-1; if(dimdim<=MAXCOLS) { memcpy(line+dim-1,p->line,p->dim); dim+=p->dim-1; return 1; } else return 0; } Editor::Line* Editor::Line::Break(int pos) { if(pos>=dim) pos=dim-1; Line* p=new Line(line+pos,dim-pos); line[pos]=0; dim=pos+1; return p; } void Editor::Line::Delete(int pos) { if(dim-1>pos) { memmove(line+pos,line+pos+1,dim-pos-1); dim--; } } ///////////////////////////////////////////////////////////////////////// Editor::Editor(const mstring& s,int ex) : path(s), from(0),lines(Lines()),atline(0),size(0), tab(0),cols(Columns()),atcol(0),exclusive(ex) { memset(map,0,sizeof(Line*)*MAXLINES); map[0]=new Line(); size=1; caption=path; caption+=sref(" ok (ESC to go back)"); if(!exclusive) caption+=sref(" (readonly)"); } Editor::~Editor() { for(int i=0;idim) { if(i==size-1) { if(tabdim-1) OutputField(i-from,0,cols,sref(map[i]->line+tab,map[i]->dim-tab-1)); OutputField(i-from,map[i]->dim-tab-1,1,end_tag); } else { OutputField(i-from,0,cols,sref(map[i]->line+tab,map[i]->dim-tab)); } } } Reverse(1); OutputField(lines,0,cols,caption); Reverse(0); MoveCursor(atline-from,atcol-tab); Refresh(); } void Editor::Move(int i,int j) { atline+=i; atcol+=j; if(atline<0) atline=0; else if(atline>=size) atline=size-1; if(atline=from+lines) from=atline+1-lines; if(atcol<0) atcol=0; else if(atcol>=map[atline]->dim) atcol=map[atline]->dim-1; if(atcol=tab+cols) tab=atcol+1-cols; } void Editor::Home() { atline=from=atcol=tab=0; } void Editor::Navigate() { int c; while(1) { Show(); switch(c=Input()) { case KK_UP: case 16: Move(-1,0); break; case KK_DOWN: case 14: Move(1,0); break; case KK_LEFT: case 2: Move(0,-1); break; case KK_RIGHT: case 6: Move(0,1); break; case KK_NPAGE: Move(lines/2,0); break; case KK_PPAGE: Move(-lines/2,0); break; case KK_HOME: case 1: Move(0,-map[atline]->dim); break; case KK_END: case 5: Move(0,map[atline]->dim); break; case 127: case 4: if(exclusive) Delete(); break; case 8: if(exclusive) Backspace(); break; case 13: if(exclusive) BreakLine(); break; case KK_F(1): if(exclusive) Insert('å'); break; case KK_F(2): if(exclusive) Insert('ä'); break; case KK_F(3): if(exclusive) Insert('ö'); break; case 9: if(exclusive) Insert('\t'); break; default: if(exclusive) if(c>=32&&c<127) Insert(c); break; case 27: return; } } } void Editor::Insert(int c) { if(map[atline]->Insert(atcol,c)) Move(0,1); } void Editor::BreakLine() { if(sizeBreak(atcol); memmove(map+atline+2,map+atline+1,sizeof(Line*)*(size-atline-1)); map[atline+1]=p; size++; Move(1,-atcol); } } void Editor::Delete() { if(map[atline]->dim-1>atcol) { map[atline]->Delete(atcol); } else if(size-1>atline) { delete map[atline]; memmove(map+atline,map+atline+1,sizeof(Line*)*(size-atline-1)); size--; } } void Editor::Backspace() { if(atcol>0) { Move(0,-1); map[atline]->Delete(atcol); } else if(atline>0) { int pos=map[atline-1]->dim-1; if(map[atline-1]->Append(map[atline])) { delete map[atline]; memmove(map+atline,map+atline+1,sizeof(Line*)*(size-atline-1)); size--; Move(-1,pos-atcol); } } } void Editor::Paste(const mstring& s) { for(int i=0;iline,map[i]->dim-1); if(i