[gtkada] Signal handler

Op de Coul, Manuel Manuel.op.de.Coul at eon.com
Mon Aug 1 15:32:34 CEST 2011


Sorry for the delay in response, I have created a small compilable example with
the same behaviour. I'll remember catching all Ada exceptions in signal handlers.

I was thinking that the problem might be in GtkAda's "ada_tree_iter_copy" called 
in the body of Gtk.Tree_Model.Get_Tree_Iter. Is there a reason why it was written
in C and not Ada?

Here's the example:
--------- fill_entry.ads -------

with Glib.Object;
with Glib.Values; use Glib.Values;

   function Fill_Entry (Object : access Glib.Object.GObject_Record'Class;
                        Params : in GValues) return Boolean;

--------- fill_entry.adb -------

with Gtk.Enums;            use Gtk.Enums;
with Gtk.Entry_Completion; use Gtk.Entry_Completion;
with Gtk.GEntry;           use Gtk.GEntry;
with Gtk.Tree_Model;       use Gtk.Tree_Model;

   function Fill_Entry (Object : access Glib.Object.GObject_Record'Class;
                        Params : in GValues) return Boolean is
      Model : Gtk_Tree_Model;
      Iter  : Gtk_Tree_Iter;
   begin
      Model := Get_Model(Gtk_Entry_Completion(Object));
      Get_Tree_Iter (Nth (Params, 1), Iter);
      Set_Text (Gtk_Entry(Get_Entry(Gtk_Entry_Completion(Object))), Get_String(Model, Iter, 1));
      return True;
   end Fill_Entry;

--------- signal_match_test.adb -------

with Glib;                 use Glib;
with Glib.Properties;      use Glib.Properties;
with Gtk.Box;              use Gtk.Box;
with Gtk.Combo;            use Gtk.Combo;
with Gtk.Dialog;           use Gtk.Dialog;
with Gtk.GEntry;           use Gtk.GEntry;
with Gtk.Main;
with Gtk.Entry_Completion; use Gtk.Entry_Completion;
with Gtk.Enums;            use Gtk.Enums;
with Gtk.List_Store;       use Gtk.List_Store;
with Gtk.Tree_Model;       use Gtk.Tree_Model;
with Gtk.Widget;           use Gtk.Widget;
with Gtkada.Handlers;      use Gtkada.Handlers;

with Ada.Exceptions;
with Text_Io;

with Fill_Entry;

procedure Signal_Match_Test is
   type Created_Dialog_Record is new Gtk_Dialog_Record with record
      Dialog_Vbox : Gtk_Vbox;
   end record;
   type Created_Dialog_Access is access all Created_Dialog_Record'Class;

   Created_Dialog : Created_Dialog_Access;
   Def_Widget  : Gtk_Widget;
   Response    : Gtk_Response_Type;
   Fifth_Combo : Gtk_Combo;
   Fifth_Entry : Gtk_Entry;
   Compl : Gtk_Entry_Completion;
   List : Gtk_List_Store;
   Iter : Gtk_Tree_Iter;
   Text_Column_Property : constant Glib.Properties.Property_Int :=
     Glib.Properties.Build ("text-column");
begin
   Gtk.Main.Set_Locale;
   Gtk.Main.Init;
   Created_Dialog := new Created_Dialog_Record;
   Gtk.Dialog.Initialize (Created_Dialog);
   Set_Title (Created_Dialog, "Signal Match Test");
   Created_Dialog.Dialog_Vbox := Get_Vbox (Created_Dialog);
   Def_Widget := Add_Button (Created_Dialog, "gtk-cancel", Gtk_Response_Cancel);

   Gtk_New (Fifth_Combo);
   Fifth_Entry := Get_Entry (Fifth_Combo);
   Pack_Start (Created_Dialog.Dialog_Vbox, Fifth_Combo);

   Gtk_New (List, GType_Array'(GType_String, GType_String, GType_String));
   Append (List, Iter);
   Set (List, Iter, 0, "col1");
   Set (List, Iter, 1, "col2");
   Set (List, Iter, 2, "col3");

   Gtk_New (Compl);
   Set_Text_Column (Compl, 0);
   Set_Text_Column (Compl, 1);
   Set_Text_Column (Compl, 2);
   Set_Property (Compl, Text_Column_Property, 0);
   Set_Model (Compl, Gtk_Tree_Model(List));
   Object_Return_Callback.Connect (Compl, Signal_Match_Selected, Fill_Entry'Access);
   Set_Completion (Fifth_Entry, Compl);

   Set_Text (Fifth_Entry, "Type a 'c' and activate the row");
   Show_All (Created_Dialog);
   Response := Run (Created_Dialog);
   Destroy (Created_Dialog);
exception
   when The_Error : others =>
      Text_Io.Put_Line(
        Ada.Exceptions.Exception_Message(The_Error) & Ascii.LF &
        Ada.Exceptions.Exception_Name(The_Error));
end Signal_Match_Test;

---------------------------------------

Thanks very much again,
Manuel


-----Original Message-----
From: gtkada-bounces at lists.adacore.com [mailto:gtkada-bounces at lists.adacore.com] On Behalf Of Dmitry A. Kazakov
Sent: dinsdag 14 juni 2011 16:26
To: gtkada
Subject: Re: [gtkada] Signal handler

On Tue, 14 Jun 2011 15:21:50 +0200, you wrote:

> Thanks to you both. I was able to connect the signal handler, but cannot get the 
> iter from the Gvalues.
> The comment
> 
>> In package Gtk.Entry_Completion:
>>    --  - "match_selected"
>>    --    procedure Handler
>>    --       (Completion : access Gtk_Entry_Completion_Record'Class;
>>    --        Model      : Gtk_Tree_Model;
>>    --        Iter       : Gtk_Tree_Iter);
>>    --    Gets emitted when a match from the list is selected. The default
>>    --    behaviour is to replace the contents of the entry with the contents of
>>    --    the text column in the row pointed to by Iter.
>>    --    Return value: %TRUE if the signal has been handled
> 
> is not correct, it should be a function returning Boolean.
> That means also that Gtk.Handlers.Callback does not need to be instantiated, 
> but GtkAda.Handlers can be used.
> So the handler is (note the different Object type):
> 
>    function Fill_Entry (Object : access Glib.Object.GObject_Record'Class;
>                         Params : in GValues)
>      return Boolean is
>       Model : Gtk_Tree_Model;
>       Iter  : Gtk_Tree_Iter;
>    begin
>       Model := Get_Model(Gtk_Entry_Completion(Object));
>       Get_Tree_Iter (Nth (Params, 1), Iter);
>       Set_Text (Gtk_Entry(Get_Entry(Gtk_Entry_Completion(Object))), Get_String(Model, Iter, 1));
>       --Set_Text (Gtk_Entry(Get_Entry(Gtk_Entry_Completion(Object))), "hello");
>       return True;
>    end Fill_Entry;
> 
> And
> 
>    Gtk_New (List, GType_Array'(1 => GType_String, 2 => GType_String));
>    Gtk_New (Compl);
>    Set_Model (Compl, Gtk_Tree_Model(List));
>    Object_Return_Callback.Connect (Compl, "match_selected", Fill_Entry'Access);
> 
> Now setting "hello" to the entry works, but getting the string from the list model gives:
> 
> (scala.exe:5260): Gtk-CRITICAL **: gtk_list_store_get_value: assertion `VALID_ITER (iter, list_store)' failed
> 
> (scala.exe:5260): GLib-GObject-WARNING **: gtype.c:3940: type id `0' is invalid
> 
> (scala.exe:5260): GLib-GObject-WARNING **: can't peek value table for type `<invalid>' which is not currently referenced
> 
> raised PROGRAM_ERROR : EXCEPTION_ACCESS_VIOLATION
> 
> Any further help very much appreciated.
> 
> Manuel

1. GType_Array is over GUInt (starts from 0).

2. Where is a call to Set_Text_Column? Or Get_Text_Column instead of a
hand-written constant in the handler.

3. Always catch all Ada exceptions in signal handlers, log the
Exception_Information using GLib.Messages.Log, and stop the exception
propagation to prevent crash.

4. It would be helpful in order to test it. if you sent a complete
compilable program sample.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
_______________________________________________
gtkada mailing list
gtkada at lists.adacore.com
http://lists.adacore.com/mailman/listinfo/gtkada



More information about the gtkada mailing list