Move configuration to Config module
[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.SwitchPage += Tabs_SwitchPage;
73             WidgetGrid.Attach(_Tabs, 1, 2, 1, 2);
74
75             InteriorOverlay = new Gtk.Alignment(1, 0, 0, 0);
76             WidgetGrid.Attach(InteriorOverlay, 1, 2, 1, 2);
77
78             _Window.ShowAll();
79
80             WebThingView newview = NewWebThingView();
81
82             // TODO: Conf.Get("plugins") instead of hard-coded path?
83             using (TextReader f = new StreamReader("plugins.conf")) {
84                 string line;
85                 while ((line = f.ReadLine()) != null) {
86                     line = line.Trim();
87                     LoadPlugin(line);
88                 }
89             }
90
91             WebViewSetupPlugins(newview.WebView);
92             newview.WebView.GrabFocus();
93
94             Application.Run();
95         }
96
97         public void LoadPlugin(string assemblyname) {
98             Assembly a = Assembly.LoadFile("plugins/" + assemblyname + ".dll");
99             Type[] types = a.GetTypes();
100             foreach (Type t in types) {
101                 if (t.IsSubclassOf(typeof(WebThingPlugin))) {
102                     WebThingPlugin p = (WebThingPlugin) a.CreateInstance(t.FullName, false, BindingFlags.ExactBinding, null, null, null, null);
103                     p.Init(this);
104                     Plugins[t.FullName] = p;
105                     Console.WriteLine("Successfully loaded {0}", t.FullName);
106                 }
107             }
108         }
109
110         public void AttachWidget(Gtk.Widget widget, CompassDirection direction, AttachOptions xoptions, AttachOptions yoptions) {
111             switch(direction) {
112             case CompassDirection.N:
113                 WidgetGrid.Attach(widget, 0, 3, 0, 1, xoptions, yoptions, 0, 0);
114                 break;
115             case CompassDirection.E:
116                 WidgetGrid.Attach(widget, 2, 3, 1, 2, xoptions, yoptions, 0, 0);
117                 break;
118             case CompassDirection.S:
119                 WidgetGrid.Attach(widget, 0, 3, 2, 3, xoptions, yoptions, 0, 0);
120                 break;
121             case CompassDirection.W:
122                 WidgetGrid.Attach(widget, 0, 1, 1, 2, xoptions, yoptions, 0, 0);
123                 break;
124             case CompassDirection.Interior:
125                 InteriorOverlay.Add(widget);
126                 break;
127             }
128         }
129
130         public void AttachWidget(Gtk.Widget widget, CompassDirection direction) {
131             AttachWidget(widget, direction, 0, 0);
132         }
133
134         public WebView NewTab() {
135             WebThingView newview = NewWebThingView();
136             WebViewSetupPlugins(newview.WebView);
137             return newview.WebView;
138         }
139
140         private WebThingView NewWebThingView() {
141             WebThingView newview = new WebThingView();
142             Tabs.AppendPage(newview, new Label("Blank"));
143             newview.WebView.TitleChanged += delegate(object o, TitleChangedArgs e) {
144                 Tabs.SetTabLabelText((Gtk.Widget) newview, e.Title);
145                 if (newview == Tabs.CurrentPageWidget)
146                     _Window.Title = e.Title + " - WebThing";
147             };
148             newview.Show();
149             return newview;
150         }
151
152         private void WebViewSetupPlugins(WebView view) {
153             foreach (string key in Plugins.Keys) {
154                 Plugins[key].InitWebView(view);
155             }
156         }
157
158         public void CloseTab() {
159             CloseTab(_Tabs.Page);
160         }
161
162         public void CloseTab(int tab) {
163             if (_Tabs.NPages > 1) {
164                 try {
165                     WebThingView view = _Tabs.GetNthPage(tab) as WebThingView;
166                     _Tabs.RemovePage(tab);
167                     view.Dispose();
168                 } catch (ArgumentOutOfRangeException) {
169                 }
170             }
171         }
172
173         public string FixUri(string Uri) {
174             if (!Regex.IsMatch(Uri, @"://")) {
175                 return String.Format("http://{0}", Uri);
176             }
177             return Uri;
178         }
179
180         public void OpenUri(string Uri) {
181             wv.Open(FixUri(Uri));
182         }
183
184         public void OpenUriTab(string Uri) {
185             WebView view = NewTab();
186             view.Open(FixUri(Uri));
187         }
188
189         public void Quit() {
190             // TODO: Create a way of shutting down plugins
191             Application.Quit();
192         }
193
194         private void Tabs_SwitchPage(object o, SwitchPageArgs e) {
195             Gtk.Widget page = _Tabs.GetNthPage((int)e.PageNum);
196             _Window.Title = _Tabs.GetTabLabelText(page) + " - WebThing";
197         }
198     }
199 }