Provided by: libgtk2-ex-formfactory-perl_0.67-0ubuntu1_all bug


       Gtk2::Ex::FormFactory::Context - Context in a FormFactory framework


         my $context = Gtk2::Ex::FormFactory::Context->new (
           default_get_prefix => Default prefix for read accessors,
           default_set_prefix => Default prefix for write accessors,

         $context->add_object (
           name                => Name of the application object in
                                  this Context,
           aggregated_by       => Object.Attribute of the parent object
                                  aggregating this object
           object              => The application object itself or a
                                  callback which returns the object,
                                  or undef if aggregated or set later
           get_prefix          => Prefix for read accessors,
           set_prefix          => Prefix for write accessors,
           accessor            => CODEREF which handles access to all object
           attr_activity_href  => Hash of CODEREFS for attributes which return
                                  activity of the corresponding attributes,
           attr_depends_href   => Hash defining attribute dependencies,
           attr_accessors_href => Hash of CODEREFS which override correspondent
                                  accessors in this Context,
           buffered            => Indicates whether changes should be buffered,
           changes_attr_filter => Regex for attributes which should not trigger
                                  the object's 'changed' status


       This module implements a very importent concept of the Gtk2::Ex::FormFactory framework.

       The Context knows of all your application objects, how attributes of the objects can be
       accessed (for reading and writing), which attributes probably depend on other attributes
       and knows of how to control the activity state of attributes resp. of the Widgets which
       represent these attributes.

       So the Context is a layer between your application objects and the GUI which represents
       particular attributes of your objects.




       Attributes are handled through the common get_ATTR(), set_ATTR() style accessors, but they
       are mostly passed once to the object constructor and must not be altered after associated
       FormFactory's were built.

       default_get_prefix = SCALAR [optional]
           Usually your application's objects use a common prefix for all attribute accessors.
           This defines the default prefix for read accessors and defaults to "get_".

       default_set_prefix = SCALAR [optional]
           Usually your application's objects use a common prefix for all attribute accessors.
           This defines the default prefix for write accessors and defaults to "set_".


       $context->add_object (...)
           All your application objects must be added to the Context using this method.
           Parameters are passed to the method as a hash:

           name = SCALAR [mandatory]
               Each object in a Context need a unique name, so this parameter is mandatory. You
               refer to this name when you create Widgets and want to associate these with your
               application object's attributes.

           object = BLESSED REF|CODEREF [optional]
               This is the application object itself, or a code reference which returns the
               object. Using the code reference option gives you very flexible control of what
               this object actually is. But also note that this may have some impact on
               performance, because this code reference will be called quite often.

               Often objects are aggregated by other objects, in that case don't set the object
               reference here but use the aggregate_by option described below.

               An application object in terms of the Context may become undef, that's why the
               object parameter is optional here. Also the code reference may return undef.

               Once an object gets undef, all associated widgets will be set inactive
               automatically. You can control per widget if it should render invisible or
               insensitive in that case. Refer to Gtk2::Ex::FormFactory::Widget for details.

           aggregated_by = "object.attr" [optional]
               If this object has a parent object set this option to the fully qualified
               attribute holding the object reference, using the object dot attribute notation:


               where object is the name of the parent object used to register it to this Context,
               and attr the attribute holding the reference to the object currently added to the

               Once this attribute resp. the parent object change, the Context will be updated
               automatically, including all widgets depending on this widget.

               This way you can define your full object aggregation hierarchy and
               Gtk2::Ex::FormFactory takes care of all resulting dependencies on the GUI.

           get_prefix = SCALAR [optional]
               With this parameter you can override the default_get_prefix setting of this
               Context for this object.

           set_prefix = SCALAR [optional]
               With this parameter you can override the default_set_prefix setting of this
               Context for this object.

           accessor = CODEREF(object,attr[,value]) [optional]
               If accessor is set this code reference is used as a generic accessor callback for
               all attributes. It handles getting and setting as well.

               Called with two arguments the passed attribute is to be read, with three
               arguments, the third argument is the value which is to be assigned to the

               This overrides attr_accessors_href described beyond.

           attr_accessors_href = HASHREF [optional]
               Often your application object attribute values doesn't fit the data type a
               particular Widget expects, e.g. in case of the Gtk2::Ex::FormFactory::List widget,
               which expects a two dimensional array for its content.

               Since you need this conversion only for a particular GUI task it makes sense to
               implement the conversion routine in the Context instead of adding such GUI
               specific methods to your underlying classes, which should be as much GUI
               independent as possible.

               That's why you can override arbitrary accessors (read and write) using the
               attr_accessors_href parameter. Key is the name of method to be overriden and
               constant scalar value or a code reference, which is called instead of the real

               The code reference gets your application object as the first parameter, as usual
               for object methods, and additionally the new value in case of write access.

               A short example. Here we override the accessors get_tracks and set_tracks of an
               imagnary disc object, which represents an audio CD. The track title is stored as a
               simple array and needs to be converted to a two dimensional array as expected by
               Gtk2::Ex::FormFactory::List. Additionally an constant accessor is defined for a
               Gtk2::Ex::FormFactory::Popup showing a bunch of music genres:

                 $context->add_object (
                   name => "disc",
                   attr_accessors_href => {
                     get_tracks => sub {
                       my $disc = shift;
                       #-- Convert the one dimensional array of disc
                       #-- tracks to the two dimensional array expected
                       #-- by Gtk2::Ex::FormFactory::List. Also the number
                       #-- of the track is added to the first column here
                       my @list;
                       my $nr = 1;
                       foreach my $track ( @{$disc->get_tracks} ) {
                         push @list, [ $nr++, $track ];
                     set_tracks => sub {
                       my $disc = shift;
                       my ($list_ref) = @_;
                       #-- Convert the array back (the List is editable in
                       #-- our example, so values can be changed).
                       my @list;
                       foreach my $row ( @{$list_ref} ) {
                               push @list, $row->[1];
                       return \@list;
                     genre_list => {
                       "rock" => "Rock",
                       "pop"  => "Pop",
                       "elec" => "Electronic",
                       "jazz" => "Jazz",

           attr_activity_href = HASHREF [OPTIONAL]
               As mentioned earlier activity of Widgets is controlled by the
               Gtk2::Ex::FormFactory framework. E.g. if the an object becomes undef, all
               associated widgets render inactive.

               With the attr_activity_href setting you can handle activity on attribute level,
               not only on object level.

               The key of the hash is the attribute name and value is a code reference, which
               returns TRUE or FALSE and control the activity this way.

               Again an example: imagine a text entry which usually is set with a default value
               controlled by your application.  But if the user wants to override the entry he
               first has to press a correpondent checkbox to activate this.

                 $context->add_object (
                   name => "person",
                   attr_activity_href => {
                     ident_number => sub {
                       my $person = shift;
                       return $person->get_may_override_ident_number;
                   attr_depends_href => {
                     ident_number => "person.may_override_ident_number",

               For details about the attr_depends_href option read on.

           attr_depends_href = HASHREF [OPTIONAL]
               This hash defines dependencies between attributes. If you look at the example
               above you see why this is necessary.  The ident_number of a person may be
               overriden only if the may_override_ident_number attribute of this person is set.
               Since this dependency is coded inside the code reference, Gtk2::Ex::FormFactory
               isn't aware of it until you add a corresponding attr_depends_href entry.

               Now the GUI will automatically activate the Widget for the ident_number attribute
               once may_override_ident_number is set, e.g. by a CheckBox the user clicked.

               If an attribute depends on more than one other attributes you can use a list

                 attr_depends_href => sub {
                     ident_number => [

           buffered = BOOL [OPTIONAL]
               If set to TRUE this activates buffering for this object. Please refer to the
               BUFFERED CONTEXT OBJECTS chapter for details.

           changes_attr_filter = REGEX [OPTIONAL]
               Gtk2::Ex::FormFactory maintains a flag indicating whether an object was changed.
               Under special circumstances you want specific attributes not affecting this
               "changed" state of an object. You can specify an regular expression here. Changes
               of attributes matching this expression won't touch the changes state of the

               To receive or change the object's changed state refer to the object_changed
               attribute of Gtk2::Ex::FormFactory::Proxy.

       $context->remove_object ( $name )
           Remove the object $name from this context.

       $app_object = $context->get_object ( $name )
           This returns the application object registered as $name to this context.

       $context->set_object ( $name => $object )
           This sets a new object, which was registered as $name to this context.

       $context->get_object_attr ( "$object.$attr" )
           Retrieves the attribute named $attr of the object $object.

       $context->set_object_attr ( "$object.$attr", $value )
           Set the attribute named $attr of the object $object to $value. Dependent widgets
           update automatically.

       $context->update_object_attr_widgets ( $object_name, $attr_name )
           Triggers updates on all GUI widgets which are associated with the attribute $attr_name
           of the object registered as $object_name to this context.

           You may omit $attr_name and pass a fully qualified "object.attr" noted string as the
           first argument instead.

       $context->update_object_widgets ( $object_name )
           Triggers updates on all GUI widgets which are associated with the object registered as
           $object_name to this context.

       $context->update_object_widgets_activity ( $object_name, $activity )
           This updates the activity state of all GUI widgets which are associated with the
           object registered as $object_name to this context.

           $activity is 'inactive' or 'active'.

       $proxy = $context->get_proxy ( $object_name )
           This returns the Gtk2::Ex::FormFactory::Proxy instance which was created for the
           object registered as $name to this context.  With the proxy you can do updates on
           object attributes which trigger the correspondent GUI updates as well.


       This feature was introduced in version 0.58 and is marked experimental so please use with

       If you set buffered => 1 when adding an object to the Context a buffering Proxy will be
       used for this object. That means that all GUI changes in a synchronized FormFactory dialog
       are buffered in the proxy object. Normally all changes are commited immediately to the
       object, which is Ok in many situations, but makes implementing a Cancel button difficult
       resp. you need to care about this yourself by using a copy of the object or something like

       A FormFactory gets "buffered" if all its widgets are connected to a buffered object. In
       that case Gtk2::Ex::Form::DialogButtons show a Cancel button automatically, even in a
       synchronized dialog.

   What's this good for?
       If your FormFactory doesn't has the sync flag set you get Cancel button as well, since no
       changes are applied to the objects until the user hit the Ok button. All changes are kept
       in the "GUI". But such a dialog lacks of all dynamic auto-widget-updating features, e.g.
       setting widgets inactive under specific conditions. For very simple dialogs this is Ok,
       but if you need these features you need the buffering facility as well.

       But take care when implementing your closures for widget activity checking: they must not
       use the original objects! They need to access the attributes through the Context, because
       your original object doesn't see any GUI changes until the FormFactory is applied! All
       changes are buffered in the Context. If you access your objects through the Context
       anything works as expected.

       Buffering is useful as well in other situations e.g. if you're accessing remote objects
       over a network (for example with Event::RPC) where a method call is somewhat expensive.


        Joern Reder <joern at zyn dot de>


       Copyright 2004-2006 by Joern Reder.

       This library is free software; you can redistribute it and/or modify it under the terms of
       the GNU Library General Public License as published by the Free Software Foundation;
       either version 2.1 of the License, or (at your option) any later version.

       This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
       without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
       See the GNU Library General Public License for more details.

       You should have received a copy of the GNU Library General Public License along with this
       library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       Boston, MA  02111-1307 USA.