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
));
141 /////////////////////////////////////////////////
143 Hashtable actionTable
= null;
146 private void ClearActions ()
148 actionTable
= new Hashtable ();
152 private string AddAction (TileActionHandler handler
)
155 return "dynaction:NULL";
156 string key
= "dynaction:" + actionId
.ToString ();
158 actionTable
[key
] = handler
;
162 private bool DoAction (string key
)
164 TileActionHandler handler
= (TileActionHandler
) actionTable
[key
];
165 if (handler
!= null) {
172 /////////////////////////////////////////////////
174 Hashtable tileTable
= null;
176 private void ClearTiles ()
178 tileTable
= new Hashtable ();
181 private void CacheTile (Tile tile
)
183 tileTable
[tile
.UniqueKey
] = tile
;
184 tile
.SetChangedHandler (new TileChangedHandler (OnTileChanged
));
187 private Tile
GetTile (string key
)
191 return (Tile
) tileTable
[key
];
194 /////////////////////////////////////////////////
196 private class TileCanvasRenderContext
: TileRenderContext
{
201 public TileCanvasRenderContext (TileCanvas _canvas
, Tile _tile
)
205 canvas
.CacheTile (tileMain
);
208 override public void Write (string markup
)
210 canvas
.AppendData (markup
);
213 override public void Link (string label
,
214 TileActionHandler handler
)
216 string key
= canvas
.AddAction (handler
);
217 Write ("<a href=\"{0}\">{1}</a>", key
, label
);
220 override public void Tile (Tile tile
)
222 canvas
.CacheTile (tile
);
227 private static ArrayList style_attributes
= null;
228 private static ArrayList style_templates
= null;
229 private static string preferred_font_family
;
230 private static double preferred_font_size
;
232 static private void GetFontSettings ()
234 GConf
.Client client
= new GConf
.Client ();
238 font
= client
.Get ("/desktop/gnome/interface/font_name") as string;
239 } catch (GConf
.NoSuchKeyException
) { }
241 // Sans 10 seems to be the default GNOME fallback
245 Pango
.FontDescription font_desc
= Pango
.FontDescription
.FromString (font
);
247 preferred_font_family
= font_desc
.Family
;
248 preferred_font_size
= font_desc
.Size
/ Pango
.Scale
.PangoScale
;
251 static private void ScanAssembly (Assembly assembly
)
253 style_attributes
= new ArrayList ();
254 foreach (Type type
in assembly
.GetTypes ()) {
255 if (type
.IsSubclassOf (typeof (Tile
))) {
256 foreach (object obj
in Attribute
.GetCustomAttributes (type
)) {
257 if (obj
is TileStyleAttribute
) {
258 style_attributes
.Add (obj
);
265 private void RenderStyles (TileRenderContext ctx
)
267 if (style_attributes
== null)
268 ScanAssembly (Assembly
.GetExecutingAssembly ());
270 if (style_templates
== null) {
273 style_templates
= new ArrayList ();
274 foreach (TileStyleAttribute attr
in style_attributes
) {
275 Template t
= new Template (attr
.Resource
);
276 t
["FontFamily"] = preferred_font_family
;
277 t
["FontSize"] = preferred_font_size
.ToString ();
278 style_templates
.Add (t
);
282 foreach (Template t
in style_templates
) {
283 ctx
.Write (t
.ToString ());
287 private void PaintTile (Tile tile
)
289 TileCanvasRenderContext ctx
;
290 ctx
= new TileCanvasRenderContext (this,
293 // IMPORTANT! The <meta> tag has to be in the first
294 // chunk written to the stream or else the encoding
296 ctx
.Write ("<html>\n<head>\n<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n");
298 ctx
.Write ("<style type=\"text/css\" media=\"screen\">\n");
300 ctx
.Write ("</style>\n");
302 ctx
.Write ("</head>\n");
308 ctx
.Write ("</html>");
311 /////////////////////////////////////////////////
313 StringBuilder content
;
315 public String Source
{
316 get { return content.ToString (); }
319 public new void AppendData (string data
)
321 content
.Append (data
);
324 /////////////////////////////////////////////////
326 private void DoRender ()
329 time
= new Beagle
.Util
.Stopwatch ();
332 System
.Console
.WriteLine ("Rendering");
333 if (PreRenderEvent
!= null)
334 PreRenderEvent (this, new EventArgs ());
339 string mime_type
= "text/html";
340 if (Environment
.GetEnvironmentVariable ("BEST_DEBUG_HTML") != null)
341 mime_type
= "text/plain";
343 content
= new StringBuilder ();
345 RenderData (content
.ToString (), "file:///", mime_type
);
347 if (PostRenderEvent
!= null)
348 PostRenderEvent (this, new EventArgs ());
351 System
.Console
.WriteLine ("Done Rendering: {0}",
358 /////////////////////////////////////////////////
360 private uint renderId
= 0;
362 public void Render ()
366 GLib
.Source
.Remove (renderId
);
373 private bool RenderHandler ()
382 Beagle
.Util
.Stopwatch time
;
383 public void ScheduleRender ()
385 time
= new Beagle
.Util
.Stopwatch ();
390 renderId
= GLib
.Idle
.Add (new GLib
.IdleHandler (RenderHandler
));
394 private void OnTileChanged (Tile tile
)