From d33dd8a15f56479ca9a6aca07745601278b6ae6d Mon Sep 17 00:00:00 2001 From: Rachel Hestilow Date: Sat, 19 Oct 2002 09:31:20 +0000 Subject: [PATCH] 2002-10-19 Rachel Hestilow * gconf, sample/gconf: Added. * glue/combo.c: This was never added, add it now. * configure.in, makefile, sample/Makefile.in: Build new gconf bindings if gnome is enabled. svn path=/trunk/gtk-sharp/; revision=8389 --- ChangeLog | 9 + configure.in | 4 + gconf/GConf.PropertyEditors/EditorShell.cs | 97 +++ gconf/GConf.PropertyEditors/Makefile.in | 28 + gconf/GConf.PropertyEditors/PropertyEditor.cs | 78 +++ .../PropertyEditorBool.cs | 31 + .../PropertyEditorColorPicker.cs | 44 ++ .../PropertyEditorEntry.cs | 33 + .../PropertyEditorEnum.cs | 85 +++ .../PropertyEditorFileEntry.cs | 37 ++ .../PropertyEditorOptionMenu.cs | 41 ++ .../PropertyEditorRadioButton.cs | 62 ++ .../PropertyEditorSpinButton.cs | 42 ++ .../PropertyEditorToggleButton.cs | 31 + gconf/GConf/ChangeSet.cs | 60 ++ gconf/GConf/Client.cs | 99 +++ gconf/GConf/ClientBase.cs | 54 ++ gconf/GConf/Makefile.in | 26 + gconf/GConf/NoSuchKeyException.cs | 8 + gconf/GConf/NotifyEventArgs.cs | 25 + gconf/GConf/NotifyEventHandler.cs | 4 + gconf/GConf/NotifyWrapper.cs | 37 ++ gconf/GConf/Value.cs | 196 ++++++ gconf/GConf/_Entry.cs | 31 + gconf/Makefile.in | 19 + gconf/doc/intro.html | 207 +++++++ gconf/tools/Makefile.in | 25 + gconf/tools/gconfsharp-schemagen.in | 2 + gconf/tools/schemagen.cs | 272 +++++++++ makefile | 2 +- sample/Makefile.in | 9 +- sample/gconf/Makefile | 21 + sample/gconf/main.cs | 75 +++ sample/gconf/sample.glade | 572 ++++++++++++++++++ sample/gconf/sample.gladep | 7 + sample/gconf/sample.schema | 73 +++ 36 files changed, 2441 insertions(+), 5 deletions(-) create mode 100644 gconf/GConf.PropertyEditors/EditorShell.cs create mode 100644 gconf/GConf.PropertyEditors/Makefile.in create mode 100644 gconf/GConf.PropertyEditors/PropertyEditor.cs create mode 100644 gconf/GConf.PropertyEditors/PropertyEditorBool.cs create mode 100644 gconf/GConf.PropertyEditors/PropertyEditorColorPicker.cs create mode 100644 gconf/GConf.PropertyEditors/PropertyEditorEntry.cs create mode 100644 gconf/GConf.PropertyEditors/PropertyEditorEnum.cs create mode 100644 gconf/GConf.PropertyEditors/PropertyEditorFileEntry.cs create mode 100644 gconf/GConf.PropertyEditors/PropertyEditorOptionMenu.cs create mode 100644 gconf/GConf.PropertyEditors/PropertyEditorRadioButton.cs create mode 100644 gconf/GConf.PropertyEditors/PropertyEditorSpinButton.cs create mode 100644 gconf/GConf.PropertyEditors/PropertyEditorToggleButton.cs create mode 100644 gconf/GConf/ChangeSet.cs create mode 100644 gconf/GConf/Client.cs create mode 100644 gconf/GConf/ClientBase.cs create mode 100644 gconf/GConf/Makefile.in create mode 100644 gconf/GConf/NoSuchKeyException.cs create mode 100644 gconf/GConf/NotifyEventArgs.cs create mode 100644 gconf/GConf/NotifyEventHandler.cs create mode 100644 gconf/GConf/NotifyWrapper.cs create mode 100644 gconf/GConf/Value.cs create mode 100644 gconf/GConf/_Entry.cs create mode 100644 gconf/Makefile.in create mode 100644 gconf/doc/intro.html create mode 100644 gconf/tools/Makefile.in create mode 100644 gconf/tools/gconfsharp-schemagen.in create mode 100644 gconf/tools/schemagen.cs create mode 100644 sample/gconf/Makefile create mode 100644 sample/gconf/main.cs create mode 100644 sample/gconf/sample.glade create mode 100644 sample/gconf/sample.gladep create mode 100644 sample/gconf/sample.schema diff --git a/ChangeLog b/ChangeLog index c375dda66..71fd108b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2002-10-19 Rachel Hestilow + + * gconf, sample/gconf: Added. + + * glue/combo.c: This was never added, add it now. + + * configure.in, makefile, sample/Makefile.in: Build new + gconf bindings if gnome is enabled. + 2002-10-14 Mike Kestner * glib/Object.cs (GetObject): remove (int) cast diff --git a/configure.in b/configure.in index 06d0c5e69..7e53ed4c3 100644 --- a/configure.in +++ b/configure.in @@ -112,6 +112,10 @@ glade/Makefile gnome/Makefile gda/Makefile gnomedb/Makefile +gconf/Makefile +gconf/GConf/Makefile +gconf/GConf.PropertyEditors/Makefile +gconf/tools/Makefile sample/Makefile ]) diff --git a/gconf/GConf.PropertyEditors/EditorShell.cs b/gconf/GConf.PropertyEditors/EditorShell.cs new file mode 100644 index 000000000..97f1b8fa1 --- /dev/null +++ b/gconf/GConf.PropertyEditors/EditorShell.cs @@ -0,0 +1,97 @@ +namespace GConf.PropertyEditors +{ + using System; + using System.Collections; + + public class EditorNotSupportedException : Exception + { + } + + public class InvalidGladeKeyException : Exception + { + public InvalidGladeKeyException (string control_name) : base ("No such glade entry \"" + control_name + "\"") + { + } + } + + public class EditorShell + { + ArrayList editors = new ArrayList (); + Hashtable by_key = new Hashtable (); + Glade.XML gxml; + GConf.ChangeSet cs = null; + + public EditorShell (Glade.XML gxml) + { + this.gxml = gxml; + } + + public EditorShell (Glade.XML gxml, GConf.ChangeSet cs) + { + this.gxml = gxml; + this.cs = cs; + } + + public void Add (PropertyEditor editor) + { + editors.Add (editor); + if (cs != null) + editor.ChangeSet = cs; + editor.Setup (); + } + + public void Add (string key, string control_name) + { + Add (key, control_name, null, null); + } + + public void Add (string key, string control_name, Type enum_type, int[] enum_values) + { + PropertyEditor editor; + Gtk.Widget control = gxml[control_name]; + + if (control == null) + throw new InvalidGladeKeyException (control_name); + + if (control is Gnome.ColorPicker) + editor = new PropertyEditorColorPicker (key, (Gnome.ColorPicker) control); + else if (control is Gnome.FileEntry) + editor = new PropertyEditorFileEntry (key, (Gnome.FileEntry) control); + else if (control is Gtk.SpinButton) + editor = new PropertyEditorSpinButton (key, (Gtk.SpinButton) control); + else if (control is Gtk.RadioButton) + editor = new PropertyEditorRadioButton (key, (Gtk.RadioButton) control, enum_type, enum_values); + else if (control is Gtk.ToggleButton) + editor = new PropertyEditorToggleButton (key, (Gtk.ToggleButton) control); + else if (control is Gtk.Entry) + editor = new PropertyEditorEntry (key, (Gtk.Entry) control); + else if (control is Gtk.OptionMenu) + editor = new PropertyEditorOptionMenu (key, (Gtk.OptionMenu) control, enum_type, enum_values); + else + throw new EditorNotSupportedException (); + + by_key.Add (key, editor); + Add (editor); + } + + public void Add (string key, string control_name, Type enum_type) + { + Add (key, control_name, enum_type, null); + } + + public void AddGuard (string key, string control_name) + { + if (!by_key.Contains (key)) + return; + Gtk.Widget control = gxml[control_name]; + if (control == null) + throw new InvalidGladeKeyException (control_name); + + PropertyEditorBool editor = by_key[key] as PropertyEditorBool; + if (editor == null) + throw new EditorNotSupportedException (); + + editor.AddGuard (control); + } + } +} diff --git a/gconf/GConf.PropertyEditors/Makefile.in b/gconf/GConf.PropertyEditors/Makefile.in new file mode 100644 index 000000000..8d80cae0f --- /dev/null +++ b/gconf/GConf.PropertyEditors/Makefile.in @@ -0,0 +1,28 @@ +MCS = mcs +DESTDIR = + +SOURCES = \ + PropertyEditor.cs \ + PropertyEditorBool.cs \ + PropertyEditorColorPicker.cs \ + PropertyEditorEnum.cs \ + PropertyEditorEntry.cs \ + PropertyEditorFileEntry.cs \ + PropertyEditorOptionMenu.cs \ + PropertyEditorRadioButton.cs \ + PropertyEditorSpinButton.cs \ + PropertyEditorToggleButton.cs \ + EditorShell.cs \ + # + +all: gconf-sharp-peditors.dll + +gconf-sharp-peditors.dll: $(SOURCES) + $(MCS) $(SOURCES) /r:../GConf/gconf-sharp.dll /r:glib-sharp /r:gtk-sharp /r:gnome-sharp /r:glade-sharp /r:System.Drawing /target:library /out:gconf-sharp-peditors.dll + +install: all + cp gconf-sharp-peditors.dll $(DESTDIR)@prefix@/lib + +clean: + rm -f gconf-sharp-peditors.dll + diff --git a/gconf/GConf.PropertyEditors/PropertyEditor.cs b/gconf/GConf.PropertyEditors/PropertyEditor.cs new file mode 100644 index 000000000..cf22a063c --- /dev/null +++ b/gconf/GConf.PropertyEditors/PropertyEditor.cs @@ -0,0 +1,78 @@ +namespace GConf.PropertyEditors +{ + using Gtk; + + public abstract class PropertyEditor + { + protected abstract void ValueChanged (object sender, NotifyEventArgs args); + protected abstract void ConnectHandlers (); + + string key; + Client client; + ChangeSet cs; + Widget control; + + public string Key + { + get { return key; } + } + + public Widget Control + { + get { return control; } + } + + protected object Get () + { + ClientBase c = (cs != null) ? (ClientBase) cs : (ClientBase) client; + try { + return c.Get (key); + } catch (NoSuchKeyException e) { + } + + if (cs != null) + { + try { + return client.Get (key); + } catch (NoSuchKeyException e) { + } + } + + return null; + } + + protected virtual void Set (object val) + { + ClientBase c = (cs != null) ? (ClientBase) cs : (ClientBase) client; + c.Set (key, val); + } + + public virtual void Setup () + { + if (client == null) + client = new Client (); + + ValueChanged (client, new NotifyEventArgs (key, Get ())); + ConnectHandlers (); + client.AddNotify (key, new NotifyEventHandler (ValueChanged)); + } + + public Client Client + { + get { return client; } + set { client = value; } + } + + public ChangeSet ChangeSet + { + get { return cs; } + set { cs = value; } + } + + public PropertyEditor (string key, Widget control) + { + this.key = key; + this.control = control; + } + } +} diff --git a/gconf/GConf.PropertyEditors/PropertyEditorBool.cs b/gconf/GConf.PropertyEditors/PropertyEditorBool.cs new file mode 100644 index 000000000..d0ec72f90 --- /dev/null +++ b/gconf/GConf.PropertyEditors/PropertyEditorBool.cs @@ -0,0 +1,31 @@ +namespace GConf.PropertyEditors +{ + using Gtk; + using System; + using System.Collections; + + public abstract class PropertyEditorBool : PropertyEditor + { + ArrayList guards = new ArrayList (); + + public void AddGuard (Widget control) + { + guards.Add (control); + control.Sensitive = (bool) Get (); + } + + protected override void Set (object val) + { + bool val_bool = (bool) val; + + foreach (Widget control in guards) + control.Sensitive = val_bool; + + base.Set (val); + } + + public PropertyEditorBool (string key, Widget control) : base (key, control) + { + } + } +} diff --git a/gconf/GConf.PropertyEditors/PropertyEditorColorPicker.cs b/gconf/GConf.PropertyEditors/PropertyEditorColorPicker.cs new file mode 100644 index 000000000..d179f54dd --- /dev/null +++ b/gconf/GConf.PropertyEditors/PropertyEditorColorPicker.cs @@ -0,0 +1,44 @@ +namespace GConf.PropertyEditors +{ + using Gtk; + using GtkSharp; + using Gnome; + using System; + using System.Drawing; + + public class PropertyEditorColorPicker : PropertyEditor + { + protected override void ValueChanged (object sender, NotifyEventArgs args) + { + object val = args.Value; + if (val == null) + return; + + ColorPicker picker = (ColorPicker) Control; + Color color = ColorTranslator.FromHtml ((string) val); + picker.SetI8 (color.R, color.G, color.B, color.A); + } + + byte ToByte (uint val) + { + return (byte) (val >> 8); + } + + void Changed (object obj, ColorSetArgs args) + { + ColorPicker picker = (ColorPicker) Control; + Color color = Color.FromArgb (ToByte (picker.Red), ToByte (picker.Green), ToByte (picker.Blue)); + Set (ColorTranslator.ToHtml (color)); + } + + protected override void ConnectHandlers () + { + ColorPicker picker = (ColorPicker) Control; + picker.ColorSet += new ColorSetHandler (Changed); + } + + public PropertyEditorColorPicker (string key, ColorPicker picker) : base (key, picker) + { + } + } +} diff --git a/gconf/GConf.PropertyEditors/PropertyEditorEntry.cs b/gconf/GConf.PropertyEditors/PropertyEditorEntry.cs new file mode 100644 index 000000000..25edf97c1 --- /dev/null +++ b/gconf/GConf.PropertyEditors/PropertyEditorEntry.cs @@ -0,0 +1,33 @@ +namespace GConf.PropertyEditors +{ + using Gtk; + using System; + + public class PropertyEditorEntry : PropertyEditor + { + protected override void ValueChanged (object sender, NotifyEventArgs args) + { + object val = args.Value; + if (val == null) + return; + Entry entry = (Entry) Control; + entry.Text = (string) val; + } + + void Changed (object obj, EventArgs args) + { + Entry entry = (Entry) Control; + Set (entry.Text); + } + + protected override void ConnectHandlers () + { + Entry entry = (Entry) Control; + entry.Changed += new EventHandler (Changed); + } + + public PropertyEditorEntry (string key, Entry entry) : base (key, entry) + { + } + } +} diff --git a/gconf/GConf.PropertyEditors/PropertyEditorEnum.cs b/gconf/GConf.PropertyEditors/PropertyEditorEnum.cs new file mode 100644 index 000000000..e1d0d49c3 --- /dev/null +++ b/gconf/GConf.PropertyEditors/PropertyEditorEnum.cs @@ -0,0 +1,85 @@ +namespace GConf.PropertyEditors +{ + using System; + + public abstract class PropertyEditorEnum : PropertyEditor + { + Type enum_type = null; + int[] enum_values; + bool is_int = false; + + protected int ValueToInt (object val) + { + if (val is int) + { + is_int = true; + return (int) val; + } + else if (val is string && enum_type != null) + { + object enum_val; + try { + enum_val = Enum.Parse (enum_type, (string) val); + } catch (Exception e) { + enum_val = 0; + } + + int history = -1; + for (int i = 0; i < enum_values.Length; i++) + { + if (enum_values[i] == (int) enum_val) + { + history = i; + break; + } + } + return history; + } + else + { + return -1; + } + } + + protected override void Set (object val) + { + if (is_int) + base.Set ((int) val); + else if (enum_type != null) + { + int enum_val = enum_values[(int) val]; + base.Set (Enum.GetName (enum_type, enum_val)); + } + } + + public PropertyEditorEnum (string key, Gtk.Widget control) : base (key, control) + { + } + + void InitValues () + { + Array values = Enum.GetValues (enum_type); + enum_values = new int[values.Length]; + + int i = 0; + foreach (object val in values) + { + enum_values[i] = (int) val; + i++; + } + } + + public PropertyEditorEnum (string key, Gtk.Widget control, Type enum_type, int[] enum_values) : base (key, control) + { + this.enum_type = enum_type; + if (enum_values == null) + InitValues (); + } + + public PropertyEditorEnum (string key, Gtk.Widget control, Type enum_type) : base (key, control) + { + this.enum_type = enum_type; + InitValues (); + } + } +} diff --git a/gconf/GConf.PropertyEditors/PropertyEditorFileEntry.cs b/gconf/GConf.PropertyEditors/PropertyEditorFileEntry.cs new file mode 100644 index 000000000..fdbd59fc8 --- /dev/null +++ b/gconf/GConf.PropertyEditors/PropertyEditorFileEntry.cs @@ -0,0 +1,37 @@ +namespace GConf.PropertyEditors +{ + using Gtk; + using Gnome; + using System; + + public class PropertyEditorFileEntry : PropertyEditor + { + protected override void ValueChanged (object sender, NotifyEventArgs args) + { + object val = args.Value; + if (val == null) + return; + FileEntry entry = (FileEntry) Control; + entry.Filename = (string) val; + } + + void Changed (object obj, EventArgs args) + { + FileEntry entry = (FileEntry) Control; + string filename = entry.Filename; + if (filename == null) + filename = String.Empty; + Set (filename); + } + + protected override void ConnectHandlers () + { + FileEntry entry = (FileEntry) Control; + entry.Changed += new EventHandler (Changed); + } + + public PropertyEditorFileEntry (string key, FileEntry entry) : base (key, entry) + { + } + } +} diff --git a/gconf/GConf.PropertyEditors/PropertyEditorOptionMenu.cs b/gconf/GConf.PropertyEditors/PropertyEditorOptionMenu.cs new file mode 100644 index 000000000..cbd266a32 --- /dev/null +++ b/gconf/GConf.PropertyEditors/PropertyEditorOptionMenu.cs @@ -0,0 +1,41 @@ +namespace GConf.PropertyEditors +{ + using Gtk; + using GtkSharp; + using System; + + public class PropertyEditorOptionMenu : PropertyEditorEnum + { + protected override void ValueChanged (object sender, NotifyEventArgs args) + { + object val = args.Value; + OptionMenu menu = (OptionMenu) Control; + menu.SetHistory ((uint) ValueToInt (val)); + } + + void Changed (object obj, EventArgs args) + { + OptionMenu menu = (OptionMenu) Control; + int history = menu.History; + Set (history); + } + + protected override void ConnectHandlers () + { + OptionMenu menu = (OptionMenu) Control; + menu.Changed += new EventHandler (Changed); + } + + public PropertyEditorOptionMenu (string key, OptionMenu menu) : base (key, menu) + { + } + + public PropertyEditorOptionMenu (string key, OptionMenu menu, Type enum_type, int[] enum_values) : base (key, menu, enum_type, enum_values) + { + } + + public PropertyEditorOptionMenu (string key, OptionMenu menu, Type enum_type) : base (key, menu, enum_type) + { + } + } +} diff --git a/gconf/GConf.PropertyEditors/PropertyEditorRadioButton.cs b/gconf/GConf.PropertyEditors/PropertyEditorRadioButton.cs new file mode 100644 index 000000000..8bd6f918b --- /dev/null +++ b/gconf/GConf.PropertyEditors/PropertyEditorRadioButton.cs @@ -0,0 +1,62 @@ +namespace GConf.PropertyEditors +{ + using Gtk; + using GtkSharp; + using System; + + public class PropertyEditorRadioButton : PropertyEditorEnum + { + GLib.SList group = null; + + protected override void ValueChanged (object sender, NotifyEventArgs args) + { + object val = args.Value; + int selected = ValueToInt (val); + int i = group.Count - 1; + foreach (RadioButton button in group) + { + if (i == selected) + { + button.Active = true; + break; + } + i--; + } + } + + void Changed (object obj, EventArgs args) + { + int i = group.Count - 1; + foreach (RadioButton button in group) + { + if (button.Active) + { + Set (i); + break; + } + i--; + } + } + + protected override void ConnectHandlers () + { + foreach (RadioButton button in group) + button.Toggled += new EventHandler (Changed); + } + + public PropertyEditorRadioButton (string key, RadioButton button) : base (key, button) + { + group = button.Group; + } + + public PropertyEditorRadioButton (string key, RadioButton button, Type enum_type, int[] enum_values) : base (key, button, enum_type, enum_values) + { + group = button.Group; + } + + public PropertyEditorRadioButton (string key, RadioButton button, Type enum_type) : base (key, button, enum_type) + { + group = button.Group; + } + } +} diff --git a/gconf/GConf.PropertyEditors/PropertyEditorSpinButton.cs b/gconf/GConf.PropertyEditors/PropertyEditorSpinButton.cs new file mode 100644 index 000000000..8326d50ae --- /dev/null +++ b/gconf/GConf.PropertyEditors/PropertyEditorSpinButton.cs @@ -0,0 +1,42 @@ +namespace GConf.PropertyEditors +{ + using Gtk; + using GtkSharp; + using System; + + public class PropertyEditorSpinButton : PropertyEditor + { + bool is_int; + + protected override void ValueChanged (object sender, NotifyEventArgs args) + { + object val = args.Value; + SpinButton spin = (SpinButton) Control; + is_int = val is int; + + if (is_int) + spin.Value = (double) (int) val; + else + spin.Value = (double) val; + } + + void Changed (object obj, EventArgs args) + { + Adjustment adj = (Adjustment) obj; + if (is_int) + Set ((int) adj.Value); + else + Set (adj.Value); + } + + protected override void ConnectHandlers () + { + SpinButton spin = (SpinButton) Control; + spin.Adjustment.ValueChanged += new EventHandler (Changed); + } + + public PropertyEditorSpinButton (string key, SpinButton spin) : base (key, spin) + { + } + } +} diff --git a/gconf/GConf.PropertyEditors/PropertyEditorToggleButton.cs b/gconf/GConf.PropertyEditors/PropertyEditorToggleButton.cs new file mode 100644 index 000000000..63a123200 --- /dev/null +++ b/gconf/GConf.PropertyEditors/PropertyEditorToggleButton.cs @@ -0,0 +1,31 @@ +namespace GConf.PropertyEditors +{ + using Gtk; + using System; + + public class PropertyEditorToggleButton : PropertyEditorBool + { + protected override void ValueChanged (object sender, NotifyEventArgs args) + { + object val = args.Value; + ToggleButton checkbox = (ToggleButton) Control; + checkbox.Active = (bool) val; + } + + void Toggled (object obj, EventArgs args) + { + ToggleButton checkbox = (ToggleButton) Control; + Set (checkbox.Active); + } + + protected override void ConnectHandlers () + { + ToggleButton checkbox = (ToggleButton) Control; + checkbox.Toggled += new EventHandler (Toggled); + } + + public PropertyEditorToggleButton (string key, ToggleButton checkbox) : base (key, checkbox) + { + } + } +} diff --git a/gconf/GConf/ChangeSet.cs b/gconf/GConf/ChangeSet.cs new file mode 100644 index 000000000..a3ad60d37 --- /dev/null +++ b/gconf/GConf/ChangeSet.cs @@ -0,0 +1,60 @@ +namespace GConf +{ + using System; + using System.Runtime.InteropServices; + + public class ChangeSet : ClientBase, IDisposable + { + IntPtr Raw = IntPtr.Zero; + + [DllImport("gconf-2")] + static extern IntPtr gconf_change_set_new (); + + public ChangeSet () + { + Initialize (); + Raw = gconf_change_set_new (); + } + + ~ChangeSet () + { + Dispose (); + } + + [DllImport("gconf-2")] + static extern void gconf_change_set_unref (IntPtr cs); + + public void Dispose () + { + if (Raw != IntPtr.Zero) + { + gconf_change_set_unref (Raw); + Raw = IntPtr.Zero; + } + } + + [DllImport("gconf-2")] + static extern void gconf_change_set_set (IntPtr cs, string key, IntPtr val); + + protected override void SetValue (string key, Value val) + { + gconf_change_set_set (Raw, key, val.Handle); + } + + [DllImport("gconf-2")] + static extern bool gconf_change_set_check_value (IntPtr cs, string key, out IntPtr val); + + public override object Get (string key) + { + IntPtr raw_val; + if (gconf_change_set_check_value (Raw, key, out raw_val) && raw_val != IntPtr.Zero) { + Value val = new Value (raw_val); + val.Managed = false; + return val.Get (); + } else { + throw new NoSuchKeyException (); + } + } + } +} + diff --git a/gconf/GConf/Client.cs b/gconf/GConf/Client.cs new file mode 100644 index 000000000..72226f883 --- /dev/null +++ b/gconf/GConf/Client.cs @@ -0,0 +1,99 @@ +namespace GConf +{ + using System; + using System.Collections; + using System.Runtime.InteropServices; + + public class Client : ClientBase + { + IntPtr Raw = IntPtr.Zero; + Hashtable dirs = new Hashtable (); + Hashtable callbacks = new Hashtable (); + + [DllImport("gconf-2")] + static extern IntPtr gconf_client_get_default (); + + public Client () + { + Initialize (); + Raw = gconf_client_get_default (); + } + + internal Client (IntPtr raw) + { + Initialize (); + Raw = raw; + } + + [DllImport("gconf-2")] + static extern void gconf_client_set (IntPtr client, string key, IntPtr val, out IntPtr err); + + protected override void SetValue (string key, Value val) + { + IntPtr err; + gconf_client_set (Raw, key, val.Handle, out err); + if (err != IntPtr.Zero) + throw new GLib.GException (err); + } + + [DllImport("gconf-2")] + static extern IntPtr gconf_client_get (IntPtr client, string key, out IntPtr err); + + public override object Get (string key) + { + IntPtr err; + IntPtr raw = gconf_client_get (Raw, key, out err); + if (err != IntPtr.Zero) + throw new GLib.GException (err); + if (raw == IntPtr.Zero) + throw new NoSuchKeyException (); + + Value val = new Value (raw); + return val.Get (); + } + + [DllImport("gconf-2")] + static extern uint gconf_client_add_dir (IntPtr client, string dir, int preload, out IntPtr err); + + void AddDir (string dir) + { + IntPtr err; + + if (dirs.Contains (dir)) + return; + + dirs.Add (dir, 1); + gconf_client_add_dir (Raw, dir, 0, out err); + if (err != IntPtr.Zero) + throw new GLib.GException (err); + } + + [DllImport("gconf-2")] + static extern uint gconf_client_notify_add (IntPtr client, string dir, NotifyFuncNative func, IntPtr user_data, IntPtr destroy_notify, out IntPtr err); + + public void AddNotify (string dir, NotifyEventHandler notify) + { + IntPtr err; + + AddDir (dir); + uint cnxn = gconf_client_notify_add (Raw, dir, NotifyWrapper.Wrap (notify), IntPtr.Zero, IntPtr.Zero, out err); + if (err != IntPtr.Zero) + throw new GLib.GException (err); + callbacks.Add (notify, cnxn); + } + + [DllImport("gconf-2")] + static extern void gconf_client_notify_remove (IntPtr client, uint cnxn); + + public void RemoveNotify (string dir, NotifyEventHandler notify) + { + if (!callbacks.Contains (notify)) + return; + + uint cnxn = (uint) callbacks[notify]; + gconf_client_notify_remove (Raw, cnxn); + callbacks.Remove (notify); + } + } +} + diff --git a/gconf/GConf/ClientBase.cs b/gconf/GConf/ClientBase.cs new file mode 100644 index 000000000..1ab355e3b --- /dev/null +++ b/gconf/GConf/ClientBase.cs @@ -0,0 +1,54 @@ +namespace GConf +{ + using System; + using System.Runtime.InteropServices; + + public abstract class ClientBase + { + public abstract object Get (string key); + protected abstract void SetValue (string key, Value val); +/* + public void Set (string key, string val) + { + Set (key, new Value (val)); + } + + public void Set (string key, int val) + { + Set (key, new Value (val)); + } + + public void Set (string key, double val) + { + Set (key, new Value (val)); + } + + public void Set (string key, bool val) + { + Set (key, new Value (val)); + } +*/ + public void Set (string key, object val) + { + SetValue (key, new Value (val)); + } + + [DllImport("gconf-2")] + static extern bool gconf_is_initialized (); + + [DllImport("gconf-2")] + static extern bool gconf_init (int argc, IntPtr argv, out IntPtr err); + + protected void Initialize () + { + if (!gconf_is_initialized ()) + { + IntPtr err; + gconf_init (0, IntPtr.Zero, out err); + if (err != IntPtr.Zero) + throw new GLib.GException (err); + } + } + } +} + diff --git a/gconf/GConf/Makefile.in b/gconf/GConf/Makefile.in new file mode 100644 index 000000000..dbeb37865 --- /dev/null +++ b/gconf/GConf/Makefile.in @@ -0,0 +1,26 @@ +MCS = mcs +DESTDIR = + +SOURCES = \ + ClientBase.cs \ + Client.cs \ + ChangeSet.cs \ + _Entry.cs \ + NoSuchKeyException.cs \ + NotifyEventArgs.cs \ + NotifyEventHandler.cs \ + NotifyWrapper.cs \ + Value.cs \ + # + +all: gconf-sharp.dll + +gconf-sharp.dll: $(SOURCES) + $(MCS) $(SOURCES) /r:glib-sharp.dll /target:library /out:gconf-sharp.dll + +install: all + cp gconf-sharp.dll $(DESTDIR)@prefix@/lib + +clean: + rm -f gconf-sharp.dll + diff --git a/gconf/GConf/NoSuchKeyException.cs b/gconf/GConf/NoSuchKeyException.cs new file mode 100644 index 000000000..bf774ffe4 --- /dev/null +++ b/gconf/GConf/NoSuchKeyException.cs @@ -0,0 +1,8 @@ +namespace GConf +{ + using System; + + public class NoSuchKeyException : Exception + { + } +} diff --git a/gconf/GConf/NotifyEventArgs.cs b/gconf/GConf/NotifyEventArgs.cs new file mode 100644 index 000000000..9f6c46448 --- /dev/null +++ b/gconf/GConf/NotifyEventArgs.cs @@ -0,0 +1,25 @@ +namespace GConf +{ + public class NotifyEventArgs : System.EventArgs + { + string key; + object val; + + public NotifyEventArgs (string key, object val) + { + this.key = key; + this.val = val; + } + + public string Key + { + get { return key; } + } + + public object Value + { + get { return val; } + } + } +} + diff --git a/gconf/GConf/NotifyEventHandler.cs b/gconf/GConf/NotifyEventHandler.cs new file mode 100644 index 000000000..ee33e989d --- /dev/null +++ b/gconf/GConf/NotifyEventHandler.cs @@ -0,0 +1,4 @@ +namespace GConf +{ + public delegate void NotifyEventHandler (object sender, NotifyEventArgs args); +} diff --git a/gconf/GConf/NotifyWrapper.cs b/gconf/GConf/NotifyWrapper.cs new file mode 100644 index 000000000..46531435e --- /dev/null +++ b/gconf/GConf/NotifyWrapper.cs @@ -0,0 +1,37 @@ +namespace GConf +{ + using System; + using System.Collections; + + internal delegate void NotifyFuncNative (IntPtr client_ptr, uint id, IntPtr entry_ptr, IntPtr user_data); + + internal class NotifyWrapper + { + static ArrayList refs = new ArrayList (); + NotifyEventHandler notify; + NotifyFuncNative native; + + void NotifyCB (IntPtr client_ptr, uint id, IntPtr entry_ptr, IntPtr user_data) + { + Client client = new Client (client_ptr); + _Entry entry = new _Entry (entry_ptr); + Value val = new Value (entry.ValuePtr); + val.Managed = false; + notify (client, new NotifyEventArgs (entry.Key, val.Get ())); + } + + public NotifyWrapper (NotifyEventHandler notify) + { + this.notify = notify; + this.native = new NotifyFuncNative (this.NotifyCB); + } + + public static NotifyFuncNative Wrap (NotifyEventHandler notify) + { + NotifyWrapper wrapper = new NotifyWrapper (notify); + refs.Add (wrapper); + return wrapper.native; + } + } +} + diff --git a/gconf/GConf/Value.cs b/gconf/GConf/Value.cs new file mode 100644 index 000000000..ad471a753 --- /dev/null +++ b/gconf/GConf/Value.cs @@ -0,0 +1,196 @@ +namespace GConf +{ + using System; + using System.Runtime.InteropServices; + + internal enum ValueType + { + Invalid, + String, + Int, + Float, + Bool, + Schema, + List, + Pair + }; + + internal struct NativeValue + { + public ValueType type; + } + + internal class InvalidValueTypeException : Exception + { + } + + internal class Value : IDisposable + { + IntPtr Raw = IntPtr.Zero; + ValueType val_type = ValueType.Invalid; + bool managed = true; + + [DllImport("gconf-2")] + static extern void gconf_value_set_string (IntPtr value, string data); + [DllImport("gconf-2")] + static extern void gconf_value_set_int (IntPtr value, int data); + [DllImport("gconf-2")] + static extern void gconf_value_set_float (IntPtr value, double data); + [DllImport("gconf-2")] + static extern void gconf_value_set_bool (IntPtr value, bool data); + + ValueType LookupType (object data) + { + if (data is string) { + return ValueType.String; + } else if (data is int) { + return ValueType.Int; + } else if (data is double) { + return ValueType.Float; + } else if (data is bool) { + return ValueType.Bool; + } else { + return ValueType.Invalid; + } + } + + public void Set (object data) + { + if (data == null) + throw new NullReferenceException (); + + ValueType type = LookupType (data); + Set (data, type); + } + + void Set (object data, ValueType type) + { + if (data == null) + throw new NullReferenceException (); + + switch (type) + { + case ValueType.String: + gconf_value_set_string (Raw, (string) data); + break; + case ValueType.Int: + gconf_value_set_int (Raw, (int) data); + break; + case ValueType.Float: + gconf_value_set_float (Raw, (double) data); + break; + case ValueType.Bool: + gconf_value_set_bool (Raw, (bool) data); + break; + default: + throw new InvalidValueTypeException (); + } + } + + [DllImport("gconf-2")] + static extern string gconf_value_get_string (IntPtr value); + + [DllImport("gconf-2")] + static extern int gconf_value_get_int (IntPtr value); + + [DllImport("gconf-2")] + static extern double gconf_value_get_float (IntPtr value); + + [DllImport("gconf-2")] + static extern bool gconf_value_get_bool (IntPtr value); + + public object Get () + { + switch (val_type) + { + case ValueType.String: + return gconf_value_get_string (Raw); + case ValueType.Int: + return gconf_value_get_int (Raw); + case ValueType.Float: + return gconf_value_get_float (Raw); + case ValueType.Bool: + return gconf_value_get_bool (Raw); + default: + throw new InvalidValueTypeException (); + } + } + + [DllImport("gconf-2")] + static extern IntPtr gconf_value_new (ValueType type); + + public Value (ValueType type) + { + Raw = gconf_value_new (type); + } + + void Initialize (object val, ValueType type) + { + Raw = gconf_value_new (type); + val_type = type; + Set (val, type); + } + + public Value (IntPtr raw) + { + Raw = raw; + NativeValue val = (NativeValue) Marshal.PtrToStructure (raw, typeof (NativeValue)); + val_type = val.type; + } +/* + public Value (string val) + { + Initialize (val, ValueType.String); + } + + public Value (int val) + { + Initialize (val, ValueType.Int); + } + + public Value (double val) + { + Initialize (val, ValueType.Float); + } + + public Value (bool val) + { + Initialize (val, ValueType.Bool); + } +*/ + public Value (object val) + { + Initialize (val, LookupType (val)); + } + public bool Managed + { + get { return managed; } + set { managed = value; } + } + + [DllImport("gconf-2")] + static extern void gconf_value_free (IntPtr value); + + ~Value () + { + Dispose (); + } + + public void Dispose () + { + if (managed && Raw != IntPtr.Zero) + { + gconf_value_free (Raw); + Raw = IntPtr.Zero; + } + } + + public IntPtr Handle + { + get { + return Raw; + } + } + } +} + diff --git a/gconf/GConf/_Entry.cs b/gconf/GConf/_Entry.cs new file mode 100644 index 000000000..d2dee1be8 --- /dev/null +++ b/gconf/GConf/_Entry.cs @@ -0,0 +1,31 @@ +namespace GConf +{ + using System; + using System.Runtime.InteropServices; + + internal struct _NativeEntry + { + public string key; + public IntPtr value; + } + + internal class _Entry + { + _NativeEntry native; + + public _Entry (IntPtr raw) + { + native = (_NativeEntry) Marshal.PtrToStructure (raw, typeof (_NativeEntry)); + } + + public string Key + { + get { return native.key; } + } + + internal IntPtr ValuePtr + { + get { return native.value; } + } + } +} diff --git a/gconf/Makefile.in b/gconf/Makefile.in new file mode 100644 index 000000000..0b012a407 --- /dev/null +++ b/gconf/Makefile.in @@ -0,0 +1,19 @@ +SUBDIRS = GConf GConf.PropertyEditors tools + +@ENABLE_GNOME_TRUE@ all: linux +@ENABLE_GNOME_FALSE@ all: + +linux: + for i in $(SUBDIRS); do \ + make -C $$i || exit 1; \ + done + +install: all + for i in $(SUBDIRS); do \ + make -C $$i install || exit 1; \ + done + +clean: + for i in $(SUBDIRS); do \ + make -C $$i clean || exit 1; \ + done diff --git a/gconf/doc/intro.html b/gconf/doc/intro.html new file mode 100644 index 000000000..3372aaaa2 --- /dev/null +++ b/gconf/doc/intro.html @@ -0,0 +1,207 @@ + + + + + Using GConf# + + +

+ Using GConf#

+

Introduction

+

Using GConf directly from an application is often inconvenient. + Because the configuration key system effectively represents a + string-based API, accessing GConf values leaves your application + open to runtime errors from a single typo. Even if you store your + keys in constants (as is recommended), you still wind up maintaining + two lists of keys: one in the schema, and one in your app.

+

Another problem is that the GConf value types are very limited: + string, float, int, bool, and list. When storing common value types + such as colors or enumerations, one has to serialize these values + to and from strings.

+

Finally, providing graphical dialogs for your settings can be a very + tedious process. For each config element exposed in your UI, you have + to manually hook up the "changed" signal on the UI to a custom handler + setting the GConf value. Inversely, one must initially populate the + dialog based on previously-set GConf values. Complicating all of this + is the GNOME HIG, which specifies that all preference dialogs be + instant-apply if possible.

+

GConf# addresses these issues with two new utilities: SchemaGen, and + the GConf.PropertyEditors library.

+ +

SchemaGen

+

SchemaGen is a new tool which generates a custom API for the settings + in a gconf schema file. Given a schema, it generates two classes, + Settings and SettingKeys. Settings provides static + properties for each specified gconf setting. These properties map + directly to the values in the gconf database. Settings also + specifies static events for each setting indicating when the setting + has changed, and a generic Changed event which notifies when any + of your settings have changed. Finally, for every property in + Settings, SchemaGen creates a read-only property of the same + name in SettingKeys specifying the GConf key used to access + this property. SettingKeys is not needed if you are only using + the Settings class, but it is very useful when attaching + PropertyEditors, or when accessing GConf directly.

+

SchemaGen also provides for limited marshalling to and from the + GConf value types. It currently defines marshallers for + System.Drawing.Color and for enumerations. This is done by specifying + a cstype directive in the GConf schema.

+

Example

+

First, we need to write a GConf schema specifying our settings.

+
+<gconfschema>
+ <schemalist>
+  <schema>
+   <key>/schemas/apps/gconfsharp/sample_app/toolbar_alignment</key>
+   <applyto>/apps/gconfsharp/sample_app/toolbar_alignment</applyto>
+   <owner>sample_app</owner>
+   <type>string</type>
+   <cstype class="Sample.Alignment">enum</cstype>
+   <locale name="C">
+    <short>Toolbar alignment</short>
+    <long>Where the toolbar should be. Can be one of Top, Bottom, Left, Rigt.</long>
+   </locale>
+   <default>Top</default>
+  </schema>
+  <schema>
+   <key>/schemas/apps/gconfsharp/sample_app/text_color</key>
+   <applyto>/apps/gconfsharp/sample_app/text_color</applyto>
+   <owner>sample_app</owner>
+   <type>string</type>
+   <cstype>color</cstype>
+   <locale name="C">
+    <short>Text color</short>
+    <long>Text color</long>
+   </locale>
+   <default>#000000</default>
+  </schema>
+  <schema>
+   <key>/schemas/apps/gconfsharp/sample_app/enable_text_color</key>
+   <applyto>/apps/gconfsharp/sample_app/enable_text_color</applyto>
+   <owner>sample_app</owner>
+   <type>bool</type>
+   <locale name="C">
+    <short>Show colored text</short>
+    <long>Show colored text</long>
+   </locale>
+   <default>#000000</default>
+  </schema>
+ </schemalist>
+</gconfschemafile>  
+  
+

Note how we specify both the cstype and type for the enum and color. + This is because GConf doesn't know anything about cstype.

+

We save this to sample.schema, and install it with the command:

+
env GCONF_CONFIG_SOURCE="" gconftool-2 --makefile-install-rule sample.schema
+

GConf generates a warning because it doesn't recognize cstype, but + it is nothing to worry about.

+

We're now ready to run SchemaGen. Installing the schema before running + SchemaGen is not required, but you should make sure to install it before + running your application, because GConf# will throw an exception if + GConf can't find your settings.

+

SchemaGen's full executable name is gconfsharp-schemagen. It + takes a namespace and the schema filename as parameters, and outputs + to the console. Here is the command used to generate Settings.cs for + sample.schema:

+
gconfsharp-schemagen Sample sample.schema > Settings.cs
+

Now we're ready to write a small program using our new settings.

+
+namespace Sample
+{
+   using System;
+   using System.Drawing;
+   
+   public enum Alignment
+   {
+     Top,
+     Bottom,
+     Left,
+     Right
+   }
+   
+   class X
+   {
+      public static void Main (string args[])
+      {
+         Alignment align = Settings.ToolbarAlignment;
+         Console.WriteLine ("Alignment is: {0}", align);
+	 Settings.ToolbarAlignment = Left;
+	 Console.WriteLine ("Color is: {0}", Settings.TextColor);
+	 Console.WriteLine ("Color is enabled: {0}", Settings.TextEnableColor);
+      }
+   }
+}
+  
+

As you can see, our GConf settings are now nicely encapsulated, and + are as easy to access as any other .NET properties.

+

Property Editors

+

Property Editors are objects which act as intermediaries between + GConf and Gtk+ widgets. They are analoguous to the Controller of the MVC + design pattern. Property editors do two things: +

    +
  • They listen to GConf notifications, and update the widget + to reflect any changes in a GConf setting. +
  • They connect to the various "changed" signals on a widget, + and update GConf to reflect the widget's current state.
  • +
+ This means that the widget and GConf are always in sync, no matter + if the value is set through Gtk+ or through GConf. GConf# defines a + number of Property Editors which correspond to common widget/setting + combinations -- for example, a CheckButton representing a boolean + setting. +

+

GConf# also provides a utility class called EditorShell. + EditorShell exposes a simple API to automatically construct + PropertyEditors for a Glade UI.

+

As a historical note, and in the interests of giving credit where + credit is due, it should be noted that GConf Property Editors are + not unique to GConf#. They were originally conceived and implemented + by Bradford Hovinen for use in the GNOME Control Center. Although + the APIs are somewhat similar, the original version was written in + C and was limited to internal use in the Control Center.

+

Example

+

For this example we'll assume you have written a Glade UI for + the settings in the previous example. It employs three elements: + an option menu named "toolbar_menu", a checkbox named "enable_check", + and a color picker named "colorpicker". Given our Glade.XML object, + all we have to do is set up the EditorShell.

+
+Glade.XML gxml = ...
+GConf.PropertyEditors.EditorShell shell = new GConf.PropertyEditors.EditorShell (gxml);
+
+shell.Add (SettingKeys.ToolbarAlignment, "toolbar_menu", typeof (Sample.Alignment));
+shell.Add (SettingKeys.EnableTextColor, "enable_check");
+shell.Add (SettingKeys.TextColor, "colorpicker");
+  
+

That's all that is needed to implement the preferences dialog. Note + how we didn't have to specify what type of property editor to use. + The EditorShell uses introspection to create the correct Property + Editor for all the types of widgets it knows about. Also note that + because ToolbarAlignment is an enum, we had to pass its type in so that + the Property Editor can store its value correctly. By default, + Property Editors assume that the order of elements in an OptionMenu + (or RadioButton) correspond to the order of values in an enum. If + this is not the case, you can pass in an additional parameter to + Add: an array of integers, each array element being the integer + representation of an enum value. This array represents the order of + values in your GUI element. +

+

Now, a really good preference dialog would "ghost out" the + color picker if the "Enable text color" option is disabled. This + requires a small addition to our previous code:

+
+shell.AddGuard (SettingKeys.EnableTextColor, "color_box");
+  
+

Again, for the purposes of the example, "color_box" is the name of the + HBox containing the label and color picker corresponding to TextColor.

+

+

+ + Last updated: October 19th, 2002
+ Rachel Hestilow (hestilow@ximian.com)
+
+

+ + diff --git a/gconf/tools/Makefile.in b/gconf/tools/Makefile.in new file mode 100644 index 000000000..60b99e9e9 --- /dev/null +++ b/gconf/tools/Makefile.in @@ -0,0 +1,25 @@ +MCS = mcs +DESTDIR = +bindir = @prefix@/bin + +SOURCES = \ + schemagen.cs \ + # + +all: gconfsharp-schemagen.exe gconfsharp-schemagen + +gconfsharp-schemagen.exe: $(SOURCES) + $(MCS) /out:gconfsharp-schemagen.exe $(SOURCES) + +gconfsharp-schemagen: gconfsharp-schemagen.in + sed -e 's^\@bindir\@^$(bindir)^g' < gconfsharp-schemagen.in > gconfsharp-schemagen.tmp \ + && mv gconfsharp-schemagen.tmp gconfsharp-schemagen \ + && chmod +x gconfsharp-schemagen + +install: all + chmod +x gconfsharp-schemagen && cp gconfsharp-schemagen.exe gconfsharp-schemagen $(DESTDIR)@prefix@/bin + +clean: + rm -f gconfsharp-schemagen.exe + rm -f gconfsharp-schemagen + diff --git a/gconf/tools/gconfsharp-schemagen.in b/gconf/tools/gconfsharp-schemagen.in new file mode 100644 index 000000000..abb690315 --- /dev/null +++ b/gconf/tools/gconfsharp-schemagen.in @@ -0,0 +1,2 @@ +#!/bin/sh +@bindir@/mono @bindir@/gconfsharp-schemagen.exe "$@" diff --git a/gconf/tools/schemagen.cs b/gconf/tools/schemagen.cs new file mode 100644 index 000000000..9bcf1e73f --- /dev/null +++ b/gconf/tools/schemagen.cs @@ -0,0 +1,272 @@ +namespace GConf.Tools +{ + using GConf; + using System; + using System.Xml; + using System.Collections; + using System.IO; + using System.Text; + + class SchemaGen + { + private Hashtable keys = new Hashtable (); + private Hashtable classes = new Hashtable (); + + static void Die (string error) + { + Console.WriteLine (error); + Environment.Exit (1); + } + + void DieInvalid (string filename) + { + Die (filename + " is an invalid schema"); + } + + void Parse (string filename) + { + XmlDocument doc = new XmlDocument (); + try { + doc.Load (filename); + } catch (XmlException e) { + Die ("Could not parse " + filename); + } + + XmlElement root = doc.DocumentElement; + if (!(root != null && root.HasChildNodes && root.Name == "gconfschemafile")) + DieInvalid (filename); + + foreach (XmlNode slist in root.ChildNodes) + { + if (!(slist != null && slist.Name == "schemalist")) + continue; + + foreach (XmlNode schema_node in slist.ChildNodes) + { + XmlElement schema = schema_node as XmlElement; + if (!(schema != null && schema.Name == "schema")) + continue; + + XmlElement key = schema["applyto"]; + XmlElement type = schema["cstype"]; + if (type == null) + type = schema["type"]; + if (key == null || type == null) + DieInvalid (filename); + keys.Add (key.InnerText, type.InnerText); + + if (type.HasAttribute ("class")) + classes.Add (key.InnerText, type.GetAttribute ("class")); + } + } + } + + string ExtractPrefix () + { + string path = null; + + foreach (string key in keys.Keys) + { + int slash = key.LastIndexOf ('/'); + if (slash < 0) + continue; + + string new_path = key.Substring (0, slash + 1); + if (path == null || new_path.Length < path.Length) + path = new_path; + } + + return path; + } + + string BaseName (string key) + { + int slash = key.LastIndexOf ('/'); + if (slash < 0) + return key; + return key.Substring (slash + 1); + } + + string PropertyName (string key) + { + string basename = BaseName (key); + StringBuilder sb = new StringBuilder (); + + bool needs_caps = true; + foreach (char orig in basename) + { + char c = orig; + if (c == '_' || c == '-') + { + needs_caps = true; + continue; + } + + if (needs_caps) + { + c = c.ToString ().ToUpper ()[0]; + needs_caps = false; + } + + sb.Append (c); + } + + return sb.ToString (); + } + + string CSType (string key, string type) + { + switch (type) + { + case "float": + return "double"; + case "string": + return "string"; + case "int": + return "int"; + case "bool": + return "bool"; + case "color": + return "System.Drawing.Color"; + case "enum": + if (classes.Contains (key)) + return (string) classes[key]; + else + return "string"; + default: + return null; + } + } + + void GenerateSimpleProperty (TextWriter sw, string key, string key_str, string type, string cstype) + { + sw.WriteLine ("\t\t\tget {"); + sw.WriteLine ("\t\t\t\treturn ({0}) client.Get ({1});", cstype, key_str); + sw.WriteLine ("\t\t\t}"); + + sw.WriteLine ("\t\t\tset {"); + sw.WriteLine ("\t\t\t\tclient.Set ({0}, value);", key_str); + sw.WriteLine ("\t\t\t}"); + } + + void GenerateColorProperty (TextWriter sw, string key, string key_str, string type, string cstype) + { + sw.WriteLine ("\t\t\tget {"); + sw.WriteLine ("\t\t\t\treturn System.Drawing.ColorTranslator.FromHtml ((string) client.Get ({0}));", key_str); + sw.WriteLine ("\t\t\t}"); + + sw.WriteLine ("\t\t\tset {"); + sw.WriteLine ("\t\t\t\tclient.Set ({0}, System.Drawing.ColorTranslator.ToHtml (value));", key_str); + sw.WriteLine ("\t\t\t}"); + } + + void GenerateEnumProperty (TextWriter sw, string key, string key_str, string type, string cstype) + { + sw.WriteLine ("\t\t\tget {"); + sw.WriteLine ("\t\t\t\ttry {"); + sw.WriteLine ("\t\t\t\t\treturn ({0}) System.Enum.Parse (typeof ({0}), (string) client.Get ({1}));", cstype, key_str); + sw.WriteLine ("\t\t\t\t} catch (System.Exception e) {"); + sw.WriteLine ("\t\t\t\t\treturn ({0}) 0;", cstype); + sw.WriteLine ("\t\t\t\t}"); + sw.WriteLine ("\t\t\t}"); + + sw.WriteLine ("\t\t\tset {"); + sw.WriteLine ("\t\t\t\tclient.Set ({0}, System.Enum.GetName (typeof ({1}), value));", key_str, cstype); + sw.WriteLine ("\t\t\t}"); + } + + void GenerateEvent (TextWriter sw, string name, string key_str) + { + sw.WriteLine (); + sw.WriteLine ("\t\tpublic static event GConf.NotifyEventHandler {0}Changed", name); + sw.WriteLine ("\t\t{"); + sw.WriteLine ("\t\t\tadd {"); + sw.WriteLine ("\t\t\t\tclient.AddNotify ({0}, value);", key_str); + sw.WriteLine ("\t\t\t}"); + sw.WriteLine ("\t\t\tremove{"); + sw.WriteLine ("\t\t\t\tclient.RemoveNotify ({0}, value);", key_str); + sw.WriteLine ("\t\t\t}"); + sw.WriteLine ("\t\t}"); + } + + void Generate (string ns_str) + { + string path = ExtractPrefix (); + TextWriter sw = Console.Out; + + sw.WriteLine ("namespace {0}", ns_str); + sw.WriteLine ("{"); + + sw.WriteLine ("\tpublic class Settings"); + sw.WriteLine ("\t{"); + sw.WriteLine ("\t\tstatic GConf.Client client = new GConf.Client ();"); + + GenerateEvent (sw, "", "\"" + path.Substring (0, path.Length - 1) + "\""); + + foreach (string key in keys.Keys) + { + string type = (string) keys[key]; + string cstype = CSType (key, type); + string key_str = "\"" + key + "\""; + + if (cstype == null) + { + Console.Error.WriteLine ("Warning: unknown type \"{0}\" for key {1}", type, key); + continue; + } + + sw.WriteLine (); + sw.WriteLine ("\t\tpublic static {0} {1}", cstype, PropertyName (key)); + sw.WriteLine ("\t\t{"); + + switch (type) + { + case "color": + GenerateColorProperty (sw, key, key_str, type, cstype); + break; + case "enum": + GenerateEnumProperty (sw, key, key_str, type, cstype); + break; + default: + GenerateSimpleProperty (sw, key, key_str, type, cstype); + break; + } + + sw.WriteLine ("\t\t}"); + + GenerateEvent (sw, PropertyName (key), key_str); + } + + sw.WriteLine ("\t}"); + sw.WriteLine (); + sw.WriteLine ("\tpublic class SettingKeys"); + sw.WriteLine ("\t{"); + + foreach (string key in keys.Keys) + { + sw.WriteLine ("\t\tpublic static string {0}", PropertyName (key)); + sw.WriteLine ("\t\t{"); + sw.WriteLine ("\t\t\tget {"); + sw.WriteLine ("\t\t\t\t return \"{0}\";", key); + sw.WriteLine ("\t\t\t}"); + sw.WriteLine ("\t\t}"); + } + + sw.WriteLine ("\t}"); + sw.WriteLine ("}"); + } + + public static void Main (string[] args) + { + if (args.Length < 2) + Die ("Usage: gconfsharp-schemagen namespace schemafile"); + string ns = args[0]; + string filename = args[1]; + + SchemaGen gen = new SchemaGen (); + gen.Parse (filename); + gen.Generate (ns); + } + } +} + diff --git a/makefile b/makefile index 8ab24e29d..52f7276f1 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,6 @@ NATIVE_DIRS = glue parser -DIRS=generator api glib pango atk gdk gtk glade art gnome gda gnomedb sample +DIRS=generator api glib pango atk gdk gtk glade art gnome gda gnomedb gconf sample ROOT=/cygdrive/$(subst \,/,$(subst :\,/,$(SYSTEMROOT))) CSC=$(ROOT)/microsoft.net/framework/v1.0.3705/csc.exe MCS=mcs diff --git a/sample/Makefile.in b/sample/Makefile.in index 28f5c8f10..c10a89df6 100755 --- a/sample/Makefile.in +++ b/sample/Makefile.in @@ -18,7 +18,8 @@ windows: $(CSC) /unsafe /out:gtk-hello-world.exe /r:../glib/glib-sharp.dll /r:../gtk/gtk-sharp.dll /r:../gdk/gdk-sharp.dll HelloWorld.cs $(CSC) /unsafe /out:button.exe /r:../glib/glib-sharp.dll /r:../gtk/gtk-sharp.dll ButtonApp.cs -linux: gtk-hello-world.exe button.exe menu.exe size.exe scribble.exe treeviewdemo.exe $(GNOME_TARGETS) $(GLADE_TARGETS) +linux: gtk-hello-world.exe button.exe menu.exe size.exe scribble.exe treeviewdemo.exe $(GNOME_TARGETS) $(GLADE_TARGETS) +@ENABLE_GNOME_TRUE@ make -C gconf gtk-hello-world.exe: HelloWorld.cs $(MCS) --unsafe -o gtk-hello-world.exe $(local_paths) $(all_assemblies) HelloWorld.cs @@ -55,11 +56,11 @@ glade-test.exe: GladeTest.cs test.glade clean: rm -f *.exe +@ENABLE_GNOME_TRUE@ make -C gconf clean unix: @echo "'make unix' is broken for now." install: linux - @echo "Nothing to install." - - +@ENABLE_GNOME_TRUE@ make -C gconf install + diff --git a/sample/gconf/Makefile b/sample/gconf/Makefile new file mode 100644 index 000000000..30c491b2e --- /dev/null +++ b/sample/gconf/Makefile @@ -0,0 +1,21 @@ +SOURCES = \ + Settings.cs \ + main.cs \ + # + +MCS = mcs +GCONFDIR=../../gconf + +all: sample.exe + +sample.exe: sample.schema sample.glade $(SOURCES) + $(MCS) /out:sample.exe $(SOURCES) /r:$(GCONFDIR)/GConf/gconf-sharp.dll /r:$(GCONFDIR)/GConf.PropertyEditors/gconf-sharp-peditors.dll /r:gtk-sharp /r:glade-sharp /r:gnome-sharp /r:System.Drawing /resource:sample.glade + +Settings.cs: sample.schema + MONO_PATH=$(top_builddir)/gconf/GConf/gconf-sharp.dll mono $(GCONFDIR)/tools/gconfsharp-schemagen.exe Sample sample.schema > Settings.cs + +install: all + GCONF_CONFIG_SOURCE="" gconftool-2 --makefile-install-rule sample.schema + +clean: + rm -f sample.exe Settings.cs diff --git a/sample/gconf/main.cs b/sample/gconf/main.cs new file mode 100644 index 000000000..4ea6f623e --- /dev/null +++ b/sample/gconf/main.cs @@ -0,0 +1,75 @@ +using GConf; +using GConf.PropertyEditors; +using Gtk; +using GtkSharp; +using Gnome; +using System; + +namespace Sample +{ + public enum Names + { + Roy, + George, + Bob, + Sally + } + + public enum Direction + { + Up, + Down, + Left, + Right + } + + class X + { + void DeleteEvent (object obj, DeleteEventArgs args) + { + Application.Quit (); + } + + void Close (object obj, EventArgs args) + { + Application.Quit (); + } + + static void Changed (object obj, NotifyEventArgs args) + { + Console.WriteLine ("Something changed:"); + Console.WriteLine ("\tkey: {0}", args.Key); + Console.WriteLine ("\tvalue: {0}", args.Value); + } + + static void ColorChanged (object obj, NotifyEventArgs args) + { + Console.WriteLine ("The color changed!"); + } + + public static void Main (string[] argv) + { + Program app = new Program ("sampleapp", "0.0.1", Modules.UI, argv); + + Glade.XML gxml = new Glade.XML (null, "sample.glade", "preferences_dialog", null); + gxml.Autoconnect (new X ()); + + Settings.Changed += new NotifyEventHandler (Changed); + Settings.TheColorChanged += new NotifyEventHandler (ColorChanged); + + EditorShell shell = new EditorShell (gxml); + shell.Add (SettingKeys.Enable, "enable"); + shell.Add (SettingKeys.TheColor, "colorpicker"); + shell.Add (SettingKeys.TheFilename, "fileentry"); + shell.Add (SettingKeys.TheInteger, "spinbutton_int"); + shell.Add (SettingKeys.TheFloat, "spinbutton_float"); + shell.Add (SettingKeys.TheFirstEnum, "optionmenu", typeof (Names)); + shell.Add (SettingKeys.TheSecondEnum, "radiobutton", typeof (Direction)); + shell.Add (SettingKeys.TheText, "entry"); + + shell.AddGuard (SettingKeys.Enable, "table1"); + + app.Run (); + } + } +} diff --git a/sample/gconf/sample.glade b/sample/gconf/sample.glade new file mode 100644 index 000000000..a905896fa --- /dev/null +++ b/sample/gconf/sample.glade @@ -0,0 +1,572 @@ + + + + + + + + True + Preferences + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + True + + + + + 2 + True + False + 0 + + + + 5 + True + GTK_BUTTONBOX_END + 10 + + + + True + True + True + gtk-close + True + GTK_RELIEF_NORMAL + -7 + + + + + + 0 + False + True + GTK_PACK_END + + + + + + 4 + True + False + 0 + + + + True + True + Enable all this junk + True + GTK_RELIEF_NORMAL + False + False + True + + + 0 + False + False + + + + + + True + False + 4 + + + + + + + + + + + 0 + False + False + + + + + + True + False + 4 + + + + + + + + + + + 0 + True + True + + + + + + True + 7 + 2 + False + 0 + 0 + + + + True + Filename + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + 0 + 1 + 1 + 2 + fill + + + + + + + True + A color + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + 0 + 1 + 0 + 1 + fill + + + + + + + True + 10 + False + False + + + + True + True + True + True + 0 + + True + * + False + + + + + 1 + 2 + 1 + 2 + + + + + + + True + True + True + False + Pick a color + + + 1 + 2 + 0 + 1 + fill + + + + + + + True + An integer + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + + + 0 + 1 + 2 + 3 + fill + + + + + + + True + A float + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + + + 0 + 1 + 3 + 4 + fill + + + + + + + True + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 1 0 100 1 10 10 + + + 1 + 2 + 2 + 3 + + + + + + + True + True + 1 + 2 + False + GTK_UPDATE_ALWAYS + False + False + 1 0 100 1 10 10 + + + 1 + 2 + 3 + 4 + + + + + + + True + An enum + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + + + 0 + 1 + 4 + 5 + fill + + + + + + + True + True + 0 + + + + + + + True + Roy + True + + + + + + True + George + True + + + + + + True + Bob + True + + + + + + True + Sally + True + + + + + + + 1 + 2 + 4 + 5 + fill + + + + + + + True + 0 + 0.5 + GTK_SHADOW_ETCHED_IN + + + + True + False + 0 + + + + True + True + Up + True + GTK_RELIEF_NORMAL + False + False + True + + + 0 + False + False + + + + + + True + True + Down + True + GTK_RELIEF_NORMAL + False + False + True + radiobutton + + + 0 + False + False + + + + + + True + True + Left + True + GTK_RELIEF_NORMAL + False + False + True + radiobutton + + + 0 + False + False + + + + + + True + True + Right + True + GTK_RELIEF_NORMAL + False + False + True + radiobutton + + + 0 + False + False + + + + + + + + True + Another enum + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + label_item + + + + + 0 + 2 + 5 + 6 + fill + + + + + + True + Some Text + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 4 + 0 + + + 0 + 1 + 6 + 7 + fill + + + + + + + True + True + True + True + 0 + + True + * + False + + + 1 + 2 + 6 + 7 + + + + + + 0 + True + True + + + + + 4 + False + True + + + + + + + diff --git a/sample/gconf/sample.gladep b/sample/gconf/sample.gladep new file mode 100644 index 000000000..ed4465497 --- /dev/null +++ b/sample/gconf/sample.gladep @@ -0,0 +1,7 @@ + + + + + sample + sample + diff --git a/sample/gconf/sample.schema b/sample/gconf/sample.schema new file mode 100644 index 000000000..54d02409e --- /dev/null +++ b/sample/gconf/sample.schema @@ -0,0 +1,73 @@ + + + + + /schemas/apps/gconfsharp/sample_app/enable + /apps/gconfsharp/sample_app/enable + sample_app + bool + true + + + + /schemas/apps/gconfsharp/sample_app/the_color + /apps/gconfsharp/sample_app/the_color + sample_app + string + color + + #0000ff + + + /schemas/apps/gconfsharp/sample_app/the_filename + /apps/gconfsharp/sample_app/the_filename + sample_app + string + + + + + /schemas/apps/gconfsharp/sample_app/the_integer + /apps/gconfsharp/sample_app/the_integer + sample_app + int + + 37 + + + /schemas/apps/gconfsharp/sample_app/the_float + /apps/gconfsharp/sample_app/the_float + sample_app + float + + 3.14 + + + /schemas/apps/gconfsharp/sample_app/the_first_enum + /apps/gconfsharp/sample_app/the_first_enum + sample_app + string + enum + + Bob + + + /schemas/apps/gconfsharp/sample_app/the_second_enum + /apps/gconfsharp/sample_app/the_second_enum + sample_app + string + enum + + Left + + + /schemas/apps/gconfsharp/sample_app/the_text + /apps/gconfsharp/sample_app/the_text + sample_app + string + + Hello World + + + +