5aa52cfa81410dc3cddcf5c3c1c5c7f2ebc174e3
[WebThing.git] / WebThing.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Reflection;
4 using System.IO;
5 using System.Text.RegularExpressions;
6 using System.Runtime.InteropServices;
7 using Gtk;
8 using GtkSharp;
9 using WebKit;
10
11 namespace bytex64.WebThing {
12     public enum CompassDirection {
13         N, E, S, W, Interior
14     }
15
16     public class WebThing {
17         private Gtk.Window _Window;
18         public Gtk.Window Window {
19             get { return _Window; }
20         }
21         public Gtk.Window w {
22             get { return _Window; }
23         }
24
25         public ScrolledWindow ScrolledWindow {
26             get { return Tabs.CurrentPageWidget as ScrolledWindow; }
27         }
28         public ScrolledWindow sw {
29             get { return ScrolledWindow; }
30         }
31
32         public WebView WebView {
33             get { return (Tabs.CurrentPageWidget as WebThingView).WebView; }
34         }
35         public WebView wv {
36             get { return WebView; }
37         }
38
39         private Gtk.Notebook _Tabs;
40         public Gtk.Notebook Tabs {
41             get { return _Tabs; }
42         }
43
44         private Gtk.Table WidgetGrid;
45         private Gtk.Alignment InteriorOverlay;
46
47         public Dictionary<string,WebThingPlugin> Plugins;
48
49         [DllImport ("SoupSettings.dll")]
50         private static extern void soup_settings();
51
52         public void Run() {
53             Application.Init();
54             Plugins = new Dictionary<string,WebThingPlugin>();
55
56             Config.ParseCommandLine();
57             Config.Load();
58             //Config.DumpOptions();
59
60             soup_settings();
61
62             _Window = new Gtk.Window("WebThing");
63             _Window.SetWmclass("webthing", "WebThing");
64             _Window.Role = "browser";
65             _Window.Destroyed += delegate { Quit(); };
66
67             WidgetGrid = new Gtk.Table(3, 3, false);
68             _Window.Add(WidgetGrid);
69
70             _Tabs = new Gtk.Notebook();
71             _Tabs.ShowBorder = false;
72             _Tabs.Scrollable = true;
73             _Tabs.SwitchPage += Tabs_SwitchPage;
74             WidgetGrid.Attach(_Tabs, 1, 2, 1, 2);
75
76             InteriorOverlay = new Gtk.Alignment(1, 0, 0, 0);
77             WidgetGrid.Attach(InteriorOverlay, 1, 2, 1, 2);
78
79             _Window.ShowAll();
80
81             WebThingView newview = NewWebThingView();
82
83             // TODO: Conf.Get("plugins") instead of hard-coded path?
84             using (TextReader f = new StreamReader("plugins.conf")) {
85                 string line;
86                 while ((line = f.ReadLine()) != null) {
87                     line = line.Trim();
88                     LoadPlugin(line);
89                 }
90             }
91
92             WebViewSetupPlugins(newview.WebView);
93             newview.WebView.GrabFocus();
94
95             Application.Run();
96         }
97
98         public void LoadPlugin(string assemblyname) {
99             Assembly a = Assembly.LoadFile("plugins/" + assemblyname + ".dll");
100             Type[] types = a.GetTypes();
101             foreach (Type t in types) {
102                 if (t.IsSubclassOf(typeof(WebThingPlugin))) {
103                     WebThingPlugin p = (WebThingPlugin) a.CreateInstance(t.FullName, false, BindingFlags.ExactBinding, null, null, null, null);
104                     p.Init(this);
105                     Plugins[t.FullName] = p;
106                     Console.WriteLine("Successfully loaded {0}", t.FullName);
107                 }
108             }
109         }
110
111         public void AttachWidget(Gtk.Widget widget, CompassDirection direction, AttachOptions xoptions, AttachOptions yoptions) {
112             switch(direction) {
113             case CompassDirection.N:
114                 WidgetGrid.Attach(widget, 0, 3, 0, 1, xoptions, yoptions, 0, 0);
115                 break;
116             case CompassDirection.E:
117                 WidgetGrid.Attach(widget, 2, 3, 1, 2, xoptions, yoptions, 0, 0);
118                 break;
119             case CompassDirection.S:
120                 WidgetGrid.Attach(widget, 0, 3, 2, 3, xoptions, yoptions, 0, 0);
121                 break;
122             case CompassDirection.W:
123                 WidgetGrid.Attach(widget, 0, 1, 1, 2, xoptions, yoptions, 0, 0);
124                 break;
125             case CompassDirection.Interior:
126                 InteriorOverlay.Add(widget);
127                 break;
128             }
129         }
130
131         public void AttachWidget(Gtk.Widget widget, CompassDirection direction) {
132             AttachWidget(widget, direction, 0, 0);
133         }
134
135         public WebView NewTab() {
136             WebThingView newview = NewWebThingView();
137             WebViewSetupPlugins(newview.WebView);
138             return newview.WebView;
139         }
140
141         private WebThingView NewWebThingView() {
142             WebThingView newview = new WebThingView();
143             Tabs.AppendPage(newview, new Label("Blank"));
144             newview.WebView.TitleChanged += delegate(object o, TitleChangedArgs e) {
145                 Tabs.SetTabLabelText((Gtk.Widget) newview, e.Title);
146                 if (newview == Tabs.CurrentPageWidget)
147                     _Window.Title = e.Title + " - WebThing";
148             };
149             newview.Show();
150             return newview;
151         }
152
153         private void WebViewSetupPlugins(WebView view) {
154             foreach (string key in Plugins.Keys) {
155                 Plugins[key].InitWebView(view);
156             }
157         }
158
159         public void CloseTab() {
160             CloseTab(_Tabs.Page);
161         }
162
163         public void CloseTab(int tab) {
164             if (_Tabs.NPages > 1) {
165                 try {
166                     WebThingView view = _Tabs.GetNthPage(tab) as WebThingView;
167                     _Tabs.RemovePage(tab);
168                     view.Dispose();
169                 } catch (ArgumentOutOfRangeException) {
170                 }
171             }
172         }
173
174         public string FixUri(string Uri) {
175             if (!Regex.IsMatch(Uri, @"://")) {
176                 return String.Format("http://{0}", Uri);
177             }
178             return Uri;
179         }
180
181         public void OpenUri(string Uri) {
182             wv.Open(FixUri(Uri));
183         }
184
185         public void OpenUriTab(string Uri) {
186             WebView view = NewTab();
187             view.Open(FixUri(Uri));
188         }
189
190         public void Quit() {
191             // TODO: Create a way of shutting down plugins
192             Application.Quit();
193         }
194
195         private void Tabs_SwitchPage(object o, SwitchPageArgs e) {
196             Gtk.Widget page = _Tabs.GetNthPage((int)e.PageNum);
197             _Window.Title = _Tabs.GetTabLabelText(page) + " - WebThing";
198         }
199     }
200 }