Add plugin for F11 full-screen toggle
[WebThing.git] / WebThing.cs
index 678194b..08cfb1b 100644 (file)
@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.Reflection;
 using System.IO;
 using System.Text.RegularExpressions;
 using System.Runtime.InteropServices;
@@ -9,190 +8,187 @@ using GtkSharp;
 using WebKit;
 
 namespace bytex64.WebThing {
-    public enum CompassDirection {
+    public enum AttachPoint {
         N, E, S, W, Interior
     }
 
     public class WebThing {
+        private Gtk.Window _Window;
         public Gtk.Window Window {
             get { return _Window; }
         }
-
         public Gtk.Window w {
             get { return _Window; }
         }
 
-        public Gtk.ScrolledWindow ScrolledWindow {
-            get { return _ScrolledWindow; }
+        public ScrolledWindow ScrolledWindow {
+            get { return Tabs.CurrentPageWidget as ScrolledWindow; }
         }
-
-        public Gtk.ScrolledWindow sw {
-            get { return _ScrolledWindow; }
+        public ScrolledWindow sw {
+            get { return ScrolledWindow; }
         }
 
-        public WebKit.WebView WebView {
-            get { return _WebView; }
+        public WebView WebView {
+            get { return (Tabs.CurrentPageWidget as WebThingView).WebView; }
+        }
+        public WebView wv {
+            get { return WebView; }
         }
 
-        public WebKit.WebView wv {
-            get { return _WebView; }
+        private Gtk.Notebook _Tabs;
+        public Gtk.Notebook Tabs {
+            get { return _Tabs; }
         }
 
-        private Gtk.Window _Window;
-        private ScrolledWindow _ScrolledWindow;
-        private WebKit.WebView _WebView;
         private Gtk.Table WidgetGrid;
         private Gtk.Alignment InteriorOverlay;
 
-        public Dictionary<string,object> Plugins;
-        public Dictionary<string,string> Options;
-        public string[] Arguments;
+        public PluginManager Plugins;
 
         [DllImport ("SoupSettings.dll")]
         private static extern void soup_settings();
 
+        // Main setup
         public void Run() {
             Application.Init();
 
-            ParseArgs();
+            soup_settings();
+
+            Config.ParseCommandLine();
+            Config.Load();
+            //Config.DumpOptions();
 
+            // Initialize Window
             _Window = new Gtk.Window("WebThing");
-            _Window.SetWmclass("webthing", "WebThing");
+            // The GTK+ docs say not to use this, but the defaults are
+            // based on the executable name, which I don't like.
+            _Window.SetWmclass("webthing", "WebThing");  
             _Window.Role = "browser";
             _Window.Destroyed += delegate { Quit(); };
 
+            // Initialize WidgetGrid
+            // The WidgetGrid holds the Tabs (and thus WebKit) and
+            // AttachPoint.Interior in the center, and allows widgets to
+            // be added on the sides of the browser
             WidgetGrid = new Gtk.Table(3, 3, false);
             _Window.Add(WidgetGrid);
 
-            _ScrolledWindow = new Gtk.ScrolledWindow();
-            WidgetGrid.Attach(_ScrolledWindow, 1, 2, 1, 2);
-
+            // Initialize Tabs
+            // Tabs are a core feature of WebThing, not a plugin.  By
+            // default, they do nothing -- Tab manipulation is left to
+            // plugins to define.
+            _Tabs = new Gtk.Notebook();
+            _Tabs.ShowBorder = false;
+            _Tabs.Scrollable = true;
+            _Tabs.SwitchPage += Tabs_SwitchPage;
+            WidgetGrid.Attach(_Tabs, 1, 2, 1, 2);
+
+            // InteriorOverlay goes over top of the Tabs to contain
+            // widgets that hover over the content, like progress, or
+            // inline search.  This is not a very solid idea ATM.
             InteriorOverlay = new Gtk.Alignment(1, 0, 0, 0);
             WidgetGrid.Attach(InteriorOverlay, 1, 2, 1, 2);
 
-            _WebView = new WebKit.WebView();
-            _WebView.TitleChanged += delegate(object o, TitleChangedArgs e) {
-                _Window.Title = e.Title + " - WebThing";
-            };
-            soup_settings();
-
-            _ScrolledWindow.Add(_WebView);
-
             _Window.ShowAll();
 
-            Plugins = new Dictionary<string, object>();
-            // TODO: Conf.Get("plugins") instead of hard-coded path?
-            using (TextReader f = new StreamReader("plugins.conf")) {
-                string line;
-                while ((line = f.ReadLine()) != null) {
-                    line = line.Trim();
-                    LoadPlugin(line);
-                }
-            }
-
-            Application.Run();
-        }
-
-        protected void ParseArgs() {
-            Options = new Dictionary<string,string>();
-            Queue<string> q = new Queue<string>();
-            foreach (string s in System.Environment.GetCommandLineArgs()) {
-                q.Enqueue(s);
-            }
-            q.Dequeue();   // Remove self argument
-
-            Regex SimpleOpt = new Regex(@"^-([a-zA-Z0-9]+)$");
-            Regex LongOpt   = new Regex(@"^--([\w-]+)$");
-            string OptLast = null;
-            List<string> args = new List<string>();
-
-            while (q.Count > 0) {
-                string opt = q.Dequeue();
-                Match m;
-                   
-                m = SimpleOpt.Match(opt);
-                if (m.Success) {
-                    string s = m.Groups[1].Value;
-                    if (s.Length > 1) {
-                        foreach (char c in s) {
-                            Options[c.ToString()] = "";
-                        }
-                        OptLast = null;
-                    } else {
-                        Options[s] = "";
-                        OptLast = s;
-                    }
-                    continue;
-                }
-
-                m = LongOpt.Match(opt);
-                if (m.Success) {
-                    string s = m.Groups[1].Value;
-                    Options[s] = "";
-                    OptLast = s;
-                    continue;
-                }
-
-                // else
-
-                if (OptLast != null) {
-                    Options[OptLast] = opt;
-                    OptLast = null;
-                } else {
-                    args.Add(opt);
-                }
-            }
-            Arguments = args.ToArray();
+            // Load Plugins
+            Plugins = new PluginManager(this);
+            Plugins.Load();
 
-            /*
-            Console.WriteLine("Options:");
-            foreach (string key in Options.Keys)
-                Console.WriteLine("   {0}\t{1}", key, Options[key]);
+            // Create a new, default WebThingView if one has not already
+            // been created.
+            if (Tabs.NPages == 0)
+                OpenUriTab("http://dominionofawesome.com/");
+            WebView.GrabFocus();
 
-            Console.WriteLine("Arguments: {0}", String.Join(" ", Arguments));
-            */
+            Application.Run();
         }
 
-        public void LoadPlugin(string assemblyname) {
-            Assembly a = Assembly.LoadFile("plugins/" + assemblyname + ".dll");
-            object obj = a.CreateInstance("Plugin", false, BindingFlags.ExactBinding, null, new object[] { this }, null, null);
-            Plugins[assemblyname] = obj;
+        public void Quit() {
+            Plugins.Deinit();
+            Application.Quit();
         }
 
-        public void AttachWidget(Gtk.Widget widget, CompassDirection direction, AttachOptions xoptions, AttachOptions yoptions) {
+        // Widget attachment
+        public void AttachWidget(Gtk.Widget widget, AttachPoint direction, AttachOptions xoptions, AttachOptions yoptions) {
             switch(direction) {
-            case CompassDirection.N:
+            case AttachPoint.N:
                 WidgetGrid.Attach(widget, 0, 3, 0, 1, xoptions, yoptions, 0, 0);
                 break;
-            case CompassDirection.E:
+            case AttachPoint.E:
                 WidgetGrid.Attach(widget, 2, 3, 1, 2, xoptions, yoptions, 0, 0);
                 break;
-            case CompassDirection.S:
+            case AttachPoint.S:
                 WidgetGrid.Attach(widget, 0, 3, 2, 3, xoptions, yoptions, 0, 0);
                 break;
-            case CompassDirection.W:
+            case AttachPoint.W:
                 WidgetGrid.Attach(widget, 0, 1, 1, 2, xoptions, yoptions, 0, 0);
                 break;
-            case CompassDirection.Interior:
+            case AttachPoint.Interior:
                 InteriorOverlay.Add(widget);
                 break;
             }
         }
 
-        public void AttachWidget(Gtk.Widget widget, CompassDirection direction) {
+        public void AttachWidget(Gtk.Widget widget, AttachPoint direction) {
             AttachWidget(widget, direction, 0, 0);
         }
 
-        public void OpenUri(string Uri) {
+        // Tab management
+        public WebThingView NewTab() {
+            WebThingView newview = NewWebThingView();
+            Plugins.WebViewSetup(newview.WebView);
+            return newview;
+        }
+
+        private WebThingView NewWebThingView() {
+            WebThingView newview = new WebThingView();
+            Tabs.AppendPage(newview, new Label("Blank"));
+            newview.WebView.TitleChanged += delegate(object o, TitleChangedArgs e) {
+                Tabs.SetTabLabelText((Gtk.Widget) newview, e.Title);
+                if (newview == Tabs.CurrentPageWidget)
+                    _Window.Title = e.Title + " - WebThing";
+            };
+            newview.Show();
+            return newview;
+        }
+
+        public void CloseTab() {
+            CloseTab(_Tabs.Page);
+        }
+
+        public void CloseTab(int tab) {
+            if (_Tabs.NPages > 1) {
+                try {
+                    WebThingView view = _Tabs.GetNthPage(tab) as WebThingView;
+                    _Tabs.RemovePage(tab);
+                    view.Dispose();
+                } catch (ArgumentOutOfRangeException) {
+                    Console.WriteLine("Attempted to close tab out of range: {0}", tab);
+                }
+            }
+        }
+
+        private void Tabs_SwitchPage(object o, SwitchPageArgs e) {
+            Gtk.Widget page = _Tabs.GetNthPage((int)e.PageNum);
+            _Window.Title = _Tabs.GetTabLabelText(page) + " - WebThing";
+        }
+
+        // Uri loading
+        public string FixUri(string Uri) {
             if (!Regex.IsMatch(Uri, @"://")) {
-                Uri = String.Format("http://{0}", Uri);
+                return String.Format("http://{0}", Uri);
             }
-            wv.Open(Uri);
+            return Uri;
         }
 
-        public void Quit() {
-            // TODO: Create a way of shutting down plugins
-            Application.Quit();
+        public void OpenUri(string Uri) {
+            wv.Open(FixUri(Uri));
+        }
+
+        public void OpenUriTab(string Uri) {
+            WebThingView wtv = NewTab();
+            wtv.WebView.Open(FixUri(Uri));
         }
     }
 }