Rearrange initialization to be clearer and shorter
[WebThing.git] / WebThing.cs
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Text.RegularExpressions;
5 using System.Runtime.InteropServices;
6 using Gtk;
7 using GtkSharp;
8 using WebKit;
9
10 namespace bytex64.WebThing {
11     public enum AttachPoint {
12         N, E, S, W, Interior
13     }
14
15     public class WebThing {
16         private Gtk.Window _Window;
17         public Gtk.Window Window {
18             get { return _Window; }
19         }
20         public Gtk.Window w {
21             get { return _Window; }
22         }
23
24         public ScrolledWindow ScrolledWindow {
25             get { return Tabs.CurrentPageWidget as ScrolledWindow; }
26         }
27         public ScrolledWindow sw {
28             get { return ScrolledWindow; }
29         }
30
31         public WebView WebView {
32             get { return (Tabs.CurrentPageWidget as WebThingView).WebView; }
33         }
34         public WebView wv {
35             get { return WebView; }
36         }
37
38         private Gtk.Notebook _Tabs;
39         public Gtk.Notebook Tabs {
40             get { return _Tabs; }
41         }
42
43         private Gtk.Table WidgetGrid;
44         private Gtk.Alignment InteriorOverlay;
45
46         public PluginManager Plugins;
47
48         [DllImport ("SoupSettings.dll")]
49         private static extern void soup_settings();
50
51         // Main setup
52         public void Run() {
53             Application.Init();
54
55             soup_settings();
56
57             Config.ParseCommandLine();
58             Config.Load();
59             //Config.DumpOptions();
60
61             // Initialize Window
62             _Window = new Gtk.Window("WebThing");
63             // The GTK+ docs say not to use this, but the defaults are
64             // based on the executable name, which I don't like.
65             _Window.SetWmclass("webthing", "WebThing");  
66             _Window.Role = "browser";
67             _Window.Destroyed += delegate { Quit(); };
68
69             // Initialize WidgetGrid
70             // The WidgetGrid holds the Tabs (and thus WebKit) and
71             // AttachPoint.Interior in the center, and allows widgets to
72             // be added on the sides of the browser
73             WidgetGrid = new Gtk.Table(3, 3, false);
74             _Window.Add(WidgetGrid);
75
76             // Initialize Tabs
77             // Tabs are a core feature of WebThing, not a plugin.  By
78             // default, they do nothing -- Tab manipulation is left to
79             // plugins to define.
80             _Tabs = new Gtk.Notebook();
81             _Tabs.ShowBorder = false;
82             _Tabs.Scrollable = true;
83             _Tabs.SwitchPage += Tabs_SwitchPage;
84             WidgetGrid.Attach(_Tabs, 1, 2, 1, 2);
85
86             // InteriorOverlay goes over top of the Tabs to contain
87             // widgets that hover over the content, like progress, or
88             // inline search.  This is not a very solid idea ATM.
89             InteriorOverlay = new Gtk.Alignment(1, 0, 0, 0);
90             WidgetGrid.Attach(InteriorOverlay, 1, 2, 1, 2);
91
92             _Window.ShowAll();
93
94             // Load Plugins
95             Plugins = new PluginManager(this);
96             Plugins.Load();
97
98             // Create a new, default WebThingView if one has not already
99             // been created.
100             if (Tabs.NPages == 0) {
101                 WebThingView default_tab = NewTab();
102                 default_tab.WebView.GrabFocus();
103             }
104
105             Application.Run();
106         }
107
108         public void Quit() {
109             // TODO: Create a way of shutting down plugins
110             Application.Quit();
111         }
112
113         // Widget attachment
114         public void AttachWidget(Gtk.Widget widget, AttachPoint direction, AttachOptions xoptions, AttachOptions yoptions) {
115             switch(direction) {
116             case AttachPoint.N:
117                 WidgetGrid.Attach(widget, 0, 3, 0, 1, xoptions, yoptions, 0, 0);
118                 break;
119             case AttachPoint.E:
120                 WidgetGrid.Attach(widget, 2, 3, 1, 2, xoptions, yoptions, 0, 0);
121                 break;
122             case AttachPoint.S:
123                 WidgetGrid.Attach(widget, 0, 3, 2, 3, xoptions, yoptions, 0, 0);
124                 break;
125             case AttachPoint.W:
126                 WidgetGrid.Attach(widget, 0, 1, 1, 2, xoptions, yoptions, 0, 0);
127                 break;
128             case AttachPoint.Interior:
129                 InteriorOverlay.Add(widget);
130                 break;
131             }
132         }
133
134         public void AttachWidget(Gtk.Widget widget, AttachPoint direction) {
135             AttachWidget(widget, direction, 0, 0);
136         }
137
138         // Tab management
139         public WebThingView NewTab() {
140             WebThingView newview = NewWebThingView();
141             Plugins.WebViewSetup(newview.WebView);
142             return newview;
143         }
144
145         private WebThingView NewWebThingView() {
146             WebThingView newview = new WebThingView();
147             Tabs.AppendPage(newview, new Label("Blank"));
148             newview.WebView.TitleChanged += delegate(object o, TitleChangedArgs e) {
149                 Tabs.SetTabLabelText((Gtk.Widget) newview, e.Title);
150                 if (newview == Tabs.CurrentPageWidget)
151                     _Window.Title = e.Title + " - WebThing";
152             };
153             newview.Show();
154             return newview;
155         }
156
157         public void CloseTab() {
158             CloseTab(_Tabs.Page);
159         }
160
161         public void CloseTab(int tab) {
162             if (_Tabs.NPages > 1) {
163                 try {
164                     WebThingView view = _Tabs.GetNthPage(tab) as WebThingView;
165                     _Tabs.RemovePage(tab);
166                     view.Dispose();
167                 } catch (ArgumentOutOfRangeException) {
168                     Console.WriteLine("Attempted to close tab out of range: {0}", tab);
169                 }
170             }
171         }
172
173         private void Tabs_SwitchPage(object o, SwitchPageArgs e) {
174             Gtk.Widget page = _Tabs.GetNthPage((int)e.PageNum);
175             _Window.Title = _Tabs.GetTabLabelText(page) + " - WebThing";
176         }
177
178         // Uri loading
179         public string FixUri(string Uri) {
180             if (!Regex.IsMatch(Uri, @"://")) {
181                 return String.Format("http://{0}", Uri);
182             }
183             return Uri;
184         }
185
186         public void OpenUri(string Uri) {
187             wv.Open(FixUri(Uri));
188         }
189
190         public void OpenUriTab(string Uri) {
191             WebThingView wtv = NewTab();
192             wtv.WebView.Open(FixUri(Uri));
193         }
194     }
195 }