4 // Copyright (C) 2004 Novell, Inc.
8 // Permission is hereby granted, free of charge, to any person obtaining a
9 // copy of this software and associated documentation files (the "Software"),
10 // to deal in the Software without restriction, including without limitation
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 // and/or sell copies of the Software, and to permit persons to whom the
13 // Software is furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 // DEALINGS IN THE SOFTWARE.
28 using System
.Collections
;
29 using System
.Diagnostics
;
30 using System
.Reflection
;
36 namespace Beagle
.Tile
{
38 public class TileCanvas
: Gecko
.WebControl
{
40 public event EventHandler PreRenderEvent
;
41 public event EventHandler PostRenderEvent
;
43 public TileCanvas () : base ()
48 private void DispatchAction (string tile_id
,
51 Tile t
= GetTile (tile_id
);
57 MethodInfo info
= t
.GetType().GetMethod (action
,
58 BindingFlags
.Public
| BindingFlags
.NonPublic
| BindingFlags
.Instance
,
60 CallingConventions
.Any
,
64 Console
.WriteLine ("Couldn't find method called {0}", action
);
67 object[] attrs
= info
.GetCustomAttributes (false);
68 foreach (object attr
in attrs
) {
69 if (attr
is TileActionAttribute
) {
70 info
.Invoke (t
, null);
74 Console
.WriteLine ("{0} does not have the TileAction attribute");
77 private void OnOpenUri (object o
, OpenUriArgs args
)
79 string uri
= args
.AURI
;
80 System
.Console
.WriteLine ("Open URI: {0}", uri
);
87 if (uri
.StartsWith ("action:")) {
88 int pos1
= "action:".Length
;
89 int pos2
= uri
.IndexOf ("!");
91 string tile_id
= uri
.Substring (pos1
, pos2
- pos1
);
92 string action
= uri
.Substring (pos2
+ 1);
93 DispatchAction (tile_id
, action
);
97 string command
= null;
98 string commandArgs
= null;
100 if (uri
.StartsWith (Uri
.UriSchemeHttp
)
101 || uri
.StartsWith (Uri
.UriSchemeHttps
)
102 || uri
.StartsWith (Uri
.UriSchemeFile
)) {
103 command
= "gnome-open";
104 commandArgs
= "'" + uri
+ "'";
105 } else if (uri
.StartsWith (Uri
.UriSchemeMailto
)) {
106 command
= "evolution";
110 if (command
!= null) {
111 Process p
= new Process ();
112 p
.StartInfo
.UseShellExecute
= false;
113 p
.StartInfo
.FileName
= command
;
115 p
.StartInfo
.Arguments
= commandArgs
;
118 } catch (Exception e
) {
119 Console
.WriteLine ("Unable to run {0}: {1}", command
, e
);
128 /////////////////////////////////////////////////
136 root
.SetChangedHandler (new TileChangedHandler (OnTileChanged
));
140 /////////////////////////////////////////////////
142 Hashtable actionTable
= null;
145 private void ClearActions ()
147 actionTable
= new Hashtable ();
151 private string AddAction (TileActionHandler handler
)
154 return "dynaction:NULL";
155 string key
= "dynaction:" + actionId
.ToString ();
157 actionTable
[key
] = handler
;
161 private bool DoAction (string key
)
163 TileActionHandler handler
= (TileActionHandler
) actionTable
[key
];
164 if (handler
!= null) {
171 /////////////////////////////////////////////////
173 Hashtable tileTable
= null;
175 private void ClearTiles ()
177 tileTable
= new Hashtable ();
180 private void CacheTile (Tile tile
)
182 tileTable
[tile
.UniqueKey
] = tile
;
183 tile
.SetChangedHandler (new TileChangedHandler (OnTileChanged
));
186 private Tile
GetTile (string key
)
190 return (Tile
) tileTable
[key
];
193 /////////////////////////////////////////////////
195 private class TileCanvasRenderContext
: TileRenderContext
{
200 public TileCanvasRenderContext (TileCanvas _canvas
, Tile _tile
)
204 canvas
.CacheTile (tileMain
);
207 override public void Write (string markup
)
209 canvas
.AppendData (markup
);
212 override public void Link (string label
,
213 TileActionHandler handler
)
215 string key
= canvas
.AddAction (handler
);
216 Write ("<a href=\"{0}\">{1}</a>", key
, label
);
219 override public void Tile (Tile tile
)
221 canvas
.CacheTile (tile
);
226 private static ArrayList style_attributes
= null;
227 private static ArrayList style_templates
= null;
228 private static string preferred_font_family
;
229 private static double preferred_font_size
;
231 static private void GetFontSettings ()
233 GConf
.Client client
= new GConf
.Client ();
237 font
= client
.Get ("/desktop/gnome/interface/font_name") as string;
238 } catch (GConf
.NoSuchKeyException
) { }
240 // Sans 10 seems to be the default GNOME fallback
244 Pango
.FontDescription font_desc
= Pango
.FontDescription
.FromString (font
);
246 preferred_font_family
= font_desc
.Family
;
247 preferred_font_size
= font_desc
.Size
/ Pango
.Scale
.PangoScale
;
250 static private void ScanAssembly (Assembly assembly
)
252 style_attributes
= new ArrayList ();
253 foreach (Type type
in assembly
.GetTypes ()) {
254 if (type
.IsSubclassOf (typeof (Tile
))) {
255 foreach (object obj
in Attribute
.GetCustomAttributes (type
)) {
256 if (obj
is TileStyleAttribute
) {
257 style_attributes
.Add (obj
);
264 private void RenderStyles (TileRenderContext ctx
)
266 if (style_attributes
== null)
267 ScanAssembly (Assembly
.GetExecutingAssembly ());
269 if (style_templates
== null) {
272 style_templates
= new ArrayList ();
273 foreach (TileStyleAttribute attr
in style_attributes
) {
274 Template t
= new Template (attr
.Resource
);
275 t
["FontFamily"] = preferred_font_family
;
276 t
["FontSize"] = preferred_font_size
.ToString ();
277 style_templates
.Add (t
);
281 foreach (Template t
in style_templates
) {
282 ctx
.Write (t
.ToString ());
286 private void PaintTile (Tile tile
)
288 TileCanvasRenderContext ctx
;
289 ctx
= new TileCanvasRenderContext (this,
292 // IMPORTANT! The <meta> tag has to be in the first
293 // chunk written to the stream or else the encoding
295 ctx
.Write ("<html>\n<head>\n<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n");
297 ctx
.Write ("<style type=\"text/css\" media=\"screen\">\n");
299 ctx
.Write ("</style>\n");
301 ctx
.Write ("</head>\n");
307 ctx
.Write ("</html>");
310 /////////////////////////////////////////////////
312 StringBuilder content
;
314 public String Source
{
315 get { return content.ToString (); }
318 public new void AppendData (string data
)
320 content
.Append (data
);
323 /////////////////////////////////////////////////
325 private void DoRender ()
328 time
= new Beagle
.Util
.Stopwatch ();
331 System
.Console
.WriteLine ("Rendering");
332 if (PreRenderEvent
!= null)
333 PreRenderEvent (this, new EventArgs ());
338 string mime_type
= "text/html";
339 if (Environment
.GetEnvironmentVariable ("BEST_DEBUG_HTML") != null)
340 mime_type
= "text/plain";
342 content
= new StringBuilder ();
344 RenderData (content
.ToString (), "file:///", mime_type
);
346 if (PostRenderEvent
!= null)
347 PostRenderEvent (this, new EventArgs ());
350 System
.Console
.WriteLine ("Done Rendering: {0}",
357 /////////////////////////////////////////////////
359 private uint renderId
= 0;
361 public void Render ()
365 GLib
.Source
.Remove (renderId
);
372 private bool RenderHandler ()
381 Beagle
.Util
.Stopwatch time
;
382 public void ScheduleRender ()
384 time
= new Beagle
.Util
.Stopwatch ();
389 renderId
= GLib
.Idle
.Add (new GLib
.IdleHandler (RenderHandler
));
393 private void OnTileChanged (Tile tile
)