2003-08-26 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.

	* glade/HandlerNotFoundException.cs: make it derive from
	SystemException. Don't override Message, the message is created in the
	.ctor.

svn path=/trunk/gtk-sharp/; revision=17646
This commit is contained in:
Gonzalo Paniagua Javier 2003-08-26 21:26:30 +00:00
parent cf917e3981
commit 0996f5f7fd
4 changed files with 118 additions and 12 deletions

View File

@ -1,3 +1,14 @@
2003-08-26 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.
* glade/HandlerNotFoundException.cs: make it derive from
SystemException. Don't override Message, the message is created in the
.ctor.
2003-08-26 Martin Willemoes Hansen <mwh@sysrq.dk>
* sources/makefile

View File

@ -1,6 +1,7 @@
namespace GConf
{
using System;
using System.Collections;
using System.Runtime.InteropServices;
internal enum ValueType
@ -49,6 +50,8 @@ namespace GConf
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 @@ namespace GConf
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 @@ namespace GConf
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 @@ namespace GConf
[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,11 +154,44 @@ namespace GConf
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);
@ -173,10 +249,16 @@ namespace GConf
~Value ()
{
Dispose ();
Dispose (false);
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
protected virtual void Dispose (bool disposing)
{
if (managed && Raw != IntPtr.Zero)
{

View File

@ -14,7 +14,7 @@ namespace Glade {
/// 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 @@ namespace Glade {
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;
@ -39,13 +47,6 @@ namespace Glade {
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
{
get {

View File

@ -49,7 +49,7 @@ namespace GLib {
~ListBase ()
{
Dispose ();
Dispose (false);
}
public bool Managed {
@ -76,7 +76,8 @@ namespace GLib {
}
set {
if (managed && list_ptr != IntPtr.Zero)
Dispose ();
FreeList ();
list_ptr = value;
}
}
@ -179,16 +180,27 @@ namespace GLib {
// 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 ();
}