[Gtk-sharp-list] [PATCH] problems with gconf list type
Gonzalo Paniagua Javier
gonzalo@ximian.com
Wed, 20 Aug 2003 19:49:33 +0200
--=-Ljh0a3bsqpflLDgJneXo
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
El mié, 20-08-2003 a las 10:20, ddt escribió:
> hi
>
> I'm writing a little program that get list type from gconf.
> when i get string type no exception raise but list type is raise
> exception.
>
> here is my code
> ----
> using Gconf;
> public class test
> {
> public static void Main()
> {
> GConf.Client gc = new GConf.Client();
> //string
> gc.Get("/apps/epiphany/web/cache_size");
> //list
> gc.Get("/apps/epiphany/web/language");
> }
> }
> ----
> and error message here
> ----
> $ mono gconf_get_list.exe
> Unhandled Exception: GConf.InvalidValueTypeException: Exception of type
> GConf.InvalidValueTypeException was thrown.
> in <0x000f0> 00 GConf.Value:Get ()
> in <0x0012a> 00 GConf.Client:Get (string)
> in <0x0003c> 00 .test:Main ()
> ----
> Is this bug? or am I wrong?
> Thanks
Support for lists was not implemented.
Attached you can get a patch that implements it (Mike, Rachel, may I
commit?) and a your sample modified to update the languages.
Cheers.
-Gonzalo
--=-Ljh0a3bsqpflLDgJneXo
Content-Disposition: attachment; filename=gconf-lists.patch
Content-Type: text/plain; name=gconf-lists.patch; charset=iso-8859-1
Content-Transfer-Encoding: 7bit
? entry
? warnings.txt
? doc/documentation.tree
? doc/documentation.zip
? gdk/PixbufLoader.cu
? gtk/DataBoundModel.csssssssssssssss
? parser/gl.sources
Index: ChangeLog
===================================================================
RCS file: /cvs/public/gtk-sharp/ChangeLog,v
retrieving revision 1.445
diff -u -r1.445 ChangeLog
--- ChangeLog 19 Aug 2003 21:07:23 -0000 1.445
+++ ChangeLog 20 Aug 2003 17:58:48 -0000
@@ -1,3 +1,10 @@
+2003-08-20 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+ * gconf/GConf/Value.cs: implemented support for lists.
+
+ * glib/ListBase.cs: implemented the IDisposable stuff and created a new method,
+ FreeList, to free the list when needed.
+
2003-08-19 John Luke <jluke@cfl.rr.com>
* glib/ListBase.cs: Add convenience .Append (string) method
Index: gconf/GConf/Value.cs
===================================================================
RCS file: /cvs/public/gtk-sharp/gconf/GConf/Value.cs,v
retrieving revision 1.2
diff -u -r1.2 Value.cs
--- gconf/GConf/Value.cs 10 Jun 2003 18:09:45 -0000 1.2
+++ gconf/GConf/Value.cs 20 Aug 2003 17:58:49 -0000
@@ -1,6 +1,7 @@
namespace GConf
{
using System;
+ using System.Collections;
using System.Runtime.InteropServices;
internal enum ValueType
@@ -49,6 +50,8 @@
return ValueType.Float;
} else if (data is bool) {
return ValueType.Bool;
+ } else if (data is ICollection) {
+ return ValueType.List;
} else {
return ValueType.Invalid;
}
@@ -63,6 +66,12 @@
Set (data, type);
}
+ [DllImport("gconf-2")]
+ static extern IntPtr gconf_value_set_list_nocopy (IntPtr value, IntPtr list);
+
+ [DllImport("gconf-2")]
+ static extern IntPtr gconf_value_set_list_type (IntPtr value, ValueType vtype);
+
void Set (object data, ValueType type)
{
if (data == null)
@@ -82,10 +91,41 @@
case ValueType.Bool:
gconf_value_set_bool (Raw, (bool) data);
break;
+ case ValueType.List:
+ ValueType listType;
+ GLib.SList list = GetListFromCollection ((ICollection) data, out listType);
+ gconf_value_set_list_type (Raw, listType);
+ gconf_value_set_list_nocopy (Raw, list.Handle);
+ break;
default:
throw new InvalidValueTypeException ();
}
}
+
+ GLib.SList GetListFromCollection (ICollection data, out ValueType listType)
+ {
+ object [] arr = (object []) Array.CreateInstance (typeof (object), data.Count);
+ data.CopyTo (arr, 0);
+
+ listType = ValueType.Invalid;
+ GLib.SList list = new GLib.SList (IntPtr.Zero);
+ GC.SuppressFinalize (list);
+
+ foreach (object o in arr) {
+ ValueType type = LookupType (o);
+ if (listType == ValueType.Invalid)
+ listType = type;
+
+ if (listType == ValueType.Invalid || type != listType)
+ throw new InvalidValueTypeException ();
+
+ Value v = new Value (o);
+ GC.SuppressFinalize (v);
+ list.Append (v.Raw);
+ }
+
+ return list;
+ }
[DllImport("gconf-2")]
static extern IntPtr gconf_value_get_string (IntPtr value);
@@ -99,6 +139,9 @@
[DllImport("gconf-2")]
static extern bool gconf_value_get_bool (IntPtr value);
+ [DllImport("gconf-2")]
+ static extern IntPtr gconf_value_get_list (IntPtr value);
+
public object Get ()
{
switch (val_type)
@@ -111,12 +154,45 @@
return gconf_value_get_float (Raw);
case ValueType.Bool:
return gconf_value_get_bool (Raw);
+ case ValueType.List:
+ GLib.SList list = new GLib.SList (gconf_value_get_list (Raw), typeof (Value));
+ Array result = Array.CreateInstance (GetListType (), list.Count);
+ int i = 0;
+ foreach (Value v in list) {
+ ((IList) result) [i] = v.Get ();
+ v.managed = false; // This is the trick to prevent a crash
+ i++;
+ }
+
+ return result;
default:
throw new InvalidValueTypeException ();
}
}
[DllImport("gconf-2")]
+ static extern ValueType gconf_value_get_list_type (IntPtr value);
+
+ Type GetListType ()
+ {
+ ValueType vt = gconf_value_get_list_type (Raw);
+ switch (vt) {
+ case ValueType.String:
+ return typeof (string);
+ case ValueType.Int:
+ return typeof (int);
+ case ValueType.Float:
+ return typeof (float);
+ case ValueType.Bool:
+ return typeof (bool);
+ case ValueType.List:
+ return typeof (GLib.SList);
+ default:
+ throw new InvalidValueTypeException ();
+ }
+ }
+
+ [DllImport("gconf-2")]
static extern IntPtr gconf_value_new (ValueType type);
public Value (ValueType type)
@@ -173,10 +249,16 @@
~Value ()
{
- Dispose ();
+ Dispose (false);
}
public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing)
{
if (managed && Raw != IntPtr.Zero)
{
Index: glade/HandlerNotFoundExeception.cs
===================================================================
RCS file: /cvs/public/gtk-sharp/glade/HandlerNotFoundExeception.cs,v
retrieving revision 1.1
diff -u -r1.1 HandlerNotFoundExeception.cs
--- glade/HandlerNotFoundExeception.cs 13 Sep 2002 11:38:36 -0000 1.1
+++ glade/HandlerNotFoundExeception.cs 20 Aug 2003 17:58:49 -0000
@@ -14,7 +14,7 @@
/// Exception thrown when signal autoconnection fails.
/// </summary>
[Serializable]
- public class HandlerNotFoundException : Exception
+ public class HandlerNotFoundException : SystemException
{
string handler_name;
string signal_name;
@@ -23,6 +23,14 @@
public HandlerNotFoundException (string handler_name, string signal_name,
EventInfo evnt, Type delegate_type)
+ : this (handler_name, signal_name, evnt, delegate_type, null)
+ {
+ }
+
+ public HandlerNotFoundException (string handler_name, string signal_name,
+ EventInfo evnt, Type delegate_type, Exception inner)
+ : base ("No handler " + handler_name + " found for signal " + signal_name,
+ inner)
{
this.handler_name = handler_name;
this.signal_name = signal_name;
@@ -37,13 +45,6 @@
signal_name = info.GetString ("SignalName");
evnt = info.GetValue ("Event", typeof (EventInfo)) as EventInfo;
delegate_type = info.GetValue ("DelegateType", typeof (Type)) as Type;
- }
-
- public override string Message
- {
- get {
- return "No handler " + handler_name + " found for signal " + signal_name;
- }
}
public string HandlerName
Index: glib/ListBase.cs
===================================================================
RCS file: /cvs/public/gtk-sharp/glib/ListBase.cs,v
retrieving revision 1.7
diff -u -r1.7 ListBase.cs
--- glib/ListBase.cs 19 Aug 2003 21:07:24 -0000 1.7
+++ glib/ListBase.cs 20 Aug 2003 17:58:49 -0000
@@ -49,7 +49,7 @@
~ListBase ()
{
- Dispose ();
+ Dispose (false);
}
public bool Managed {
@@ -76,7 +76,8 @@
}
set {
if (managed && list_ptr != IntPtr.Zero)
- Dispose ();
+ FreeList ();
+
list_ptr = value;
}
}
@@ -180,15 +181,26 @@
// IDisposable
public void Dispose ()
{
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
if (!managed)
return;
+ FreeList ();
+ }
+
+ void FreeList ()
+ {
if (list_ptr != IntPtr.Zero)
Free (list_ptr);
list_ptr = IntPtr.Zero;
length = -1;
}
-
+
// ICloneable
abstract public object Clone ();
}
--=-Ljh0a3bsqpflLDgJneXo
Content-Disposition: attachment; filename=gcs.cs
Content-Type: text/plain; name=gcs.cs; charset=iso-8859-1
Content-Transfer-Encoding: 7bit
using System;
using GConf;
public class test
{
public static void Main()
{
GConf.Client gc = new GConf.Client ();
//string
gc.Get ("/apps/epiphany/web/cache_size");
//list
Array list = (Array) gc.Get ("/apps/epiphany/web/language");
foreach (object o in list)
Console.WriteLine ("{0}: {1}", o.GetType (), o);
string [] mylist = new string [] {"us", "system", "es"};
gc.Set ("/apps/epiphany/web/language", mylist);
list = (Array) gc.Get ("/apps/epiphany/web/language");
foreach (object o in list)
Console.WriteLine ("{0}: {1}", o.GetType (), o);
}
}
--=-Ljh0a3bsqpflLDgJneXo--