Fixed help file parsing
[Nebula.git] / TextDocument.cs
index e05e992..21f813a 100644 (file)
@@ -49,6 +49,7 @@ public class TextArray {
                while ((line = file.ReadLine()) != null) {
                        lines.Add(line);
                }
+               file.Close();
        }
 
        public ArrayList Lines {
@@ -74,12 +75,16 @@ public class TextArray {
                if (y >= lines.Count) return;
 
                string s = (string)lines[y];
-               if (x >= s.Length) return;
-
-               if (s.Length == 0 && x == 0) {
+               if (x >= s.Length) {
+                       if (y == lines.Count - 1) return;
+                       if (x > s.Length)
+                               s = s.PadRight(x);
+                       lines[y] = s + (string)lines[y+1];
+                       lines.RemoveAt(y+1);
+               } else if (s.Length == 0 && x == 0) {
                        lines.RemoveAt(y);
                } else {
-                       s.Remove(x, 1);
+                       lines[y] = s.Remove(x, 1);
                }
        }
 
@@ -116,17 +121,23 @@ public class TextArray {
                if (y >= lines.Count) return 0;
                return ((string)lines[y]).Length;
        }
+
+       public void Save(string filename) {
+               StreamWriter file = new StreamWriter(filename);
+               for (int i = 0; i < lines.Count; i++) {
+                       file.Write((string)lines[i]);
+                       file.Write('\n');
+               }
+               file.Close();
+       }
 }
 
-public class TextDocument {
+public class TextDocument : IKeyPress {
        private TextArray text;
+       public string filename = null;
        public Cursor cursor;
-
-       public ArrayList Lines {
-               get {
-                       return text.Lines;
-               }
-       }
+       public Cursor textorigin;
+       private int pagewidth, pageheight;
 
        public TextDocument() {
                text = new TextArray();
@@ -134,6 +145,34 @@ public class TextDocument {
 
        public TextDocument(string filename) {
                text = new TextArray(filename);
+               this.filename = filename;
+       }
+
+       public string GetTextWindow() {
+               string s = "";
+
+               for (int i = 0; i <= pageheight + 1 && textorigin.y + i < text.Lines.Count; i++) {
+                       string l = (string)text.Lines[textorigin.y + i];
+                       if (textorigin.x > l.Length) {
+                               s += "\n";
+                       } else {
+                               s += l.Substring(textorigin.x) + "\n";
+                       }
+               }
+               return s;
+       }
+
+       private void FixTextWindow() {
+               if (cursor.x < textorigin.x) textorigin.x = cursor.x;
+               if (cursor.y < textorigin.y) textorigin.y = cursor.y;
+               if (cursor.x > textorigin.x + pagewidth) textorigin.x = cursor.x - pagewidth;
+               if (cursor.y > textorigin.y + pageheight) textorigin.y = cursor.y - pageheight;
+       }
+
+       public void SetPageSize(int w, int h) {
+               pagewidth = w;
+               pageheight = h;
+               FixTextWindow();
        }
 
        public void MoveCursor(Gdk.Key k) {
@@ -156,35 +195,136 @@ public class TextDocument {
                case Gdk.Key.Home:
                        cursor.x = 0;
                        break;
+               case Gdk.Key.Page_Up:
+                       cursor.y -= pageheight;
+                       break;
+               case Gdk.Key.Page_Down:
+                       cursor.y += pageheight;
+                       break;
                }
        }
 
-       public void AddChar(int c) {
-               c = c & 0xFF;
-               if (c > 128) return;
-
-               switch(c) {
-               case 8:
-                       int l = 0;
-                       if (cursor.y > 0) l = text.LineLength(cursor.y-1);
-                       text.Backspace(cursor.x, cursor.y);
-                       if (cursor.x == 0) {
-                               cursor.y--;
-                               if (cursor.y >= text.Lines.Count) return;
-                               cursor.x = l;
+       public void NextWord() {
+               if (cursor.x >= text.LineLength(cursor.y)) {
+                       cursor.y++;
+                       cursor.x = 0;
+               } else {
+                       string s = (String)text.Lines[cursor.y];
+                       int i = s.IndexOf(' ', cursor.x);
+                       if (i == -1) {
+                               cursor.y++;
+                               cursor.x = 0;
                        } else {
-                               cursor.x--;
+                               cursor.x = i + 1;
                        }
-                       break;
-               case 13:
-                       text.Newline(cursor.x, cursor.y);
+               }
+       }
+
+       public void PreviousWord() {
+               if (cursor.y > text.Lines.Count) {
                        cursor.x = 0;
-                       cursor.y++;
-                       break;
-               default:
-                       text.Insert(cursor.x, cursor.y, (char)c);
-                       cursor.x++;
-                       break;
+                       cursor.y--;
+               } else if (cursor.y == text.Lines.Count) {
+                       string s = (String)text.Lines[text.Lines.Count - 1];
+                       int i = s.LastIndexOf(' ');
+                       if (i == -1) {
+                               cursor.x = 0;
+                       } else {
+                               cursor.x = i + 1;
+                       }
+                       cursor.y--;
+               } else if (cursor.x == 0 && cursor.y > 0) {
+                       string s = (String)text.Lines[cursor.y - 1];
+                       int i = s.LastIndexOf(' ');
+                       if (i == -1) {
+                               cursor.x = 0;
+                       } else {
+                               cursor.x = i + 1;
+                       }
+                       cursor.y--;
+               } else if (cursor.x == 0 && cursor.y == 0) {
+                       return;
+               } else {
+                       string s = (String)text.Lines[cursor.y];
+                       if (cursor.x >= s.Length)
+                               cursor.x = s.Length - 1;
+                       int i = s.LastIndexOf(' ', cursor.x - 2, cursor.x - 2);
+                       if (i == -1) {
+                               cursor.x = 0;
+                       } else {
+                               cursor.x = i + 1;
+                       }
                }
        }
+
+       [GLib.ConnectBefore ()]
+       public void KeyPress(object o, Gtk.KeyPressEventArgs args) {
+               if ((args.Event.State & Gdk.ModifierType.ControlMask) != 0) {
+                       switch(args.Event.Key) {
+                       case Gdk.Key.Right:
+                               NextWord();
+                               break;
+                       case Gdk.Key.Left:
+                               PreviousWord();
+                               break;
+                       }
+               } else if ((args.Event.State & Gdk.ModifierType.Mod1Mask) != 0) {
+               } else {
+                       switch(args.Event.Key) {
+                       case Gdk.Key.Up:
+                       case Gdk.Key.Down:
+                       case Gdk.Key.Left:
+                       case Gdk.Key.Right:
+                       case Gdk.Key.Page_Up:
+                       case Gdk.Key.Page_Down:
+                       case Gdk.Key.Home:
+                       case Gdk.Key.End:
+                               MoveCursor(args.Event.Key);
+                               break;
+                       case Gdk.Key.Delete:
+                               text.Delete(cursor.x, cursor.y);
+                               break;
+                       case Gdk.Key.BackSpace:
+                               int l = 0;
+                               if (cursor.y > 0) l = text.LineLength(cursor.y-1);
+                               text.Backspace(cursor.x, cursor.y);
+                               if (cursor.x == 0) {
+                                       cursor.y--;
+                                       if (cursor.y >= text.Lines.Count) return;
+                                       cursor.x = l;
+                               } else {
+                                       cursor.x--;
+                               }
+                               break;
+                       case Gdk.Key.Return:
+                               text.Newline(cursor.x, cursor.y);
+                               cursor.x = 0;
+                               cursor.y++;
+                               break;
+                       default:
+                               AddChar((int)args.Event.KeyValue);
+                               break;
+                       }
+               }
+               FixTextWindow();
+       }
+       
+       public void AddChar(int c) {
+               c = c & 0xFF;
+               if (c > 128) return;
+
+               text.Insert(cursor.x, cursor.y, (char)c);
+               cursor.x++;
+       }
+
+       public void Save() {
+               if (filename == null)
+                       throw new InvalidOperationException("Cannot Save() without filename");
+               text.Save(filename);
+       }
+
+       public void Save(string filename) {
+               this.filename = filename;
+               Save();
+       }
 }