// WARNING: This file is in UTF8 format due to the use of ã // XML.custom // // Author: Ricardo Fernández Pascual // // (c) 2002 Ricardo Fernández Pascual // // Field binding code by Rachel Hestilow // (c) 2003 Rachel Hestilow // // This code is inserted after the automatically generated code. // keep this around so it doesn't get GC'd static GladeSharp.XMLCustomWidgetHandlerWrapper callback_wrapper = null; [DllImport("libglade-2.0-0.dll")] static extern void glade_set_custom_handler (GladeSharp.XMLCustomWidgetHandlerNative handler, IntPtr user_data); static public void SetCustomHandler (Glade.XMLCustomWidgetHandler handler) { callback_wrapper = new GladeSharp.XMLCustomWidgetHandlerWrapper (handler, null); glade_set_custom_handler (callback_wrapper.NativeDelegate, IntPtr.Zero); } [DllImport("gladesharpglue")] static extern IntPtr gtksharp_glade_xml_get_filename (IntPtr raw); /// Filename Property /// Gets the filename used to create this GladeXML object /// public string Filename { get { string ret; IntPtr ptr = gtksharp_glade_xml_get_filename (Handle); if (ptr == IntPtr.Zero) { // from resource ret = System.Reflection.Assembly.GetCallingAssembly ().Location; } else { ret = Marshal.PtrToStringAnsi (ptr); } return ret; } } /// Indexer of widgets /// Acts like GetWidget public Gtk.Widget this [string name] { get { return GetWidget (name); } } [DllImport("libglade-2.0-0.dll")] static extern IntPtr glade_get_widget_name (IntPtr widget); static public string GetWidgetName (Gtk.Widget w) { string ret; IntPtr ptr = glade_get_widget_name (w.Handle); if (ptr == IntPtr.Zero) ret = ""; else ret = Marshal.PtrToStringAnsi (ptr); return ret; } [DllImport("libglade-2.0-0.dll")] static extern IntPtr glade_get_widget_tree (IntPtr widget); static public Glade.XML GetWidgetTree (Gtk.Widget w) { IntPtr ret_raw = glade_get_widget_tree (w.Handle); Glade.XML ret = GLib.Object.GetObject (ret_raw, false) as Glade.XML; return ret; } /* a constructor that reads the XML from a Stream */ [DllImport("libglade-2.0-0.dll")] static extern IntPtr glade_xml_new_from_buffer(byte[] buffer, int size, string root, string domain); /// Creates a Glade.XML object from a Stream /// Reads the contents of the stream and parses it. It must be in /// correct Glade format public XML (System.IO.Stream s, string root, string domain) : base (IntPtr.Zero) { if (GetType() != typeof (XML)) throw new InvalidOperationException ("Can't chain to this constructor from subclasses."); if (s == null) throw new ArgumentNullException ("s"); int size = (int) s.Length; byte[] buffer = new byte[size]; s.Read (buffer, 0, size); Raw = glade_xml_new_from_buffer(buffer, size, root, domain); } /// Creates a Glade.XML object from a resource /// Reads the contents of the resource in the /// given assembly and parses it. If the assembly is null, /// the current assembly will be used. It must be in /// correct Glade format public XML (System.Reflection.Assembly assembly, string resource_name, string root, string domain) : base (IntPtr.Zero) { if (GetType() != typeof (XML)) throw new InvalidOperationException ("Can't chain to this constructor from subclasses."); if (assembly == null) assembly = System.Reflection.Assembly.GetCallingAssembly (); System.IO.Stream s = assembly.GetManifestResourceStream (resource_name); if (s == null) throw new ArgumentException ("Cannot get resource file '" + resource_name + "'", "resource_name"); int size = (int) s.Length; byte[] buffer = new byte[size]; s.Read (buffer, 0, size); s.Close (); Raw = glade_xml_new_from_buffer(buffer, size, root, domain); } /* signal autoconnection using reflection */ /// Automatically connect signals /// Connects the signals defined in the glade file with handler methods /// provided by the given object. public void Autoconnect (object handler) { BindFields (handler); SignalConnector sc = new SignalConnector (this, handler); sc.Autoconnect (); } /// Automatically connect signals /// Connects the signals defined in the glade file with static handler /// methods provided by the given type. public void Autoconnect (Type handler_class) { BindFields (handler_class); SignalConnector sc = new SignalConnector (this, handler_class); sc.Autoconnect (); } class SignalConnector { /* the Glade.XML object whose signals we want to connect */ XML gxml; /* the object to look for handlers */ object handler_object; /* the type to look for handlers if no object has been specified */ Type handler_type; public SignalConnector (XML gxml, object handler) { this.gxml = gxml; this.handler_object = handler; this.handler_type = handler.GetType (); } public SignalConnector (XML gxml, Type type) { this.gxml = gxml; this.handler_object = null; this.handler_type = type; } delegate void RawXMLConnectFunc (string handler_name, IntPtr objekt, string signal_name, string signal_data, IntPtr connect_object, int after, IntPtr user_data); [DllImport("libglade-2.0-0.dll")] static extern void glade_xml_signal_autoconnect_full (IntPtr raw, RawXMLConnectFunc func, IntPtr user_data); public void Autoconnect () { RawXMLConnectFunc cf = new RawXMLConnectFunc (ConnectFunc); glade_xml_signal_autoconnect_full (gxml.Handle, cf, IntPtr.Zero); } void ConnectFunc (string handler_name, IntPtr objekt_ptr, string signal_name, string signal_data, IntPtr connect_object_ptr, int after, IntPtr user_data) { GLib.Object objekt = GLib.Object.GetObject (objekt_ptr, false); /* if an connect_object_ptr is provided, use that as handler */ object connect_object = connect_object_ptr == IntPtr.Zero ? handler_object : GLib.Object.GetObject (connect_object_ptr, false); /* search for the event to connect */ System.Reflection.MemberInfo[] evnts = objekt.GetType (). FindMembers (System.Reflection.MemberTypes.Event, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, signalFilter, signal_name); foreach (System.Reflection.EventInfo ei in evnts) { bool connected = false; System.Reflection.MethodInfo add = ei.GetAddMethod (); System.Reflection.ParameterInfo[] addpi = add.GetParameters (); if (addpi.Length == 1) { /* this should be always true, unless there's something broken */ Type delegate_type = addpi[0].ParameterType; /* look for an instance method */ if (connect_object != null) try { Delegate d = Delegate.CreateDelegate (delegate_type, connect_object, handler_name); add.Invoke (objekt, new object[] { d } ); connected = true; } catch (ArgumentException) { /* ignore if there is not such instance method */ } /* look for a static method if no instance method has been found */ if (!connected && handler_type != null) try { Delegate d = Delegate.CreateDelegate (delegate_type, handler_type, handler_name); add.Invoke (objekt, new object[] { d } ); connected = true; } catch (ArgumentException) { /* ignore if there is not such static method */ } if (!connected) { throw new HandlerNotFoundException (handler_name, signal_name, ei, delegate_type); } } } } System.Reflection.MemberFilter signalFilter = new System.Reflection.MemberFilter (SignalFilter); /* matches events to GLib signal names */ static bool SignalFilter (System.Reflection.MemberInfo m, object filterCriteria) { string signame = (filterCriteria as string); object[] attrs = m.GetCustomAttributes (typeof (GLib.SignalAttribute), true); if (attrs.Length > 0) { foreach (GLib.SignalAttribute a in attrs) { if (signame == a.CName) { return true; } } return false; } else { /* this tries to match the names when no attibutes are present. It is only a fallback. */ signame = signame.ToLower ().Replace ("_", ""); string evname = m.Name.ToLower (); return signame == evname; } } } private void BindFields (object target, Type type) { System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic; if (target != null) flags |= System.Reflection.BindingFlags.Instance; else flags |= System.Reflection.BindingFlags.Static; System.Reflection.FieldInfo[] fields = type.GetFields (flags); if (fields == null) return; foreach (System.Reflection.FieldInfo field in fields) { object[] attrs = field.GetCustomAttributes (typeof (WidgetAttribute), true); if (attrs == null || attrs.Length == 0) continue; // The widget to field binding must be 1:1, so only check // the first attribute. WidgetAttribute widget = (WidgetAttribute) attrs[0]; if (widget.Specified) field.SetValue (target, GetWidget (widget.Name), flags, null, null); else field.SetValue (target, GetWidget (field.Name), flags, null, null); } } public void BindFields (object target) { BindFields (target, target.GetType ()); } public void BindFields (Type type) { BindFields (null, type); } public static Glade.XML FromStream (System.IO.Stream stream, string root, string domain) { return new Glade.XML (stream, root, domain); } public static Glade.XML FromAssembly ( System.Reflection.Assembly assembly, string resource_name, string root, string domain) { return new Glade.XML (assembly, resource_name, root, domain); } public static Glade.XML FromAssembly (string resource_name, string root, string domain) { return new Glade.XML ( System.Reflection.Assembly.GetCallingAssembly (), resource_name, root, domain); } [DllImport("libglade-2.0-0.dll")] static extern IntPtr glade_xml_get_widget_prefix(IntPtr raw, string name); public Gtk.Widget[] GetWidgetPrefix(string name) { IntPtr raw_ret = glade_xml_get_widget_prefix(Handle, name); if (raw_ret == IntPtr.Zero) return new Gtk.Widget [0]; GLib.List list = new GLib.List (raw_ret); Gtk.Widget[] result = new Gtk.Widget [list.Count]; int i = 0; foreach (Gtk.Widget w in list) result [i++] = w; return result; }